diff --git a/config/firewall/firewall-lib.pl b/config/firewall/firewall-lib.pl index b389fac3c..eabd9a42f 100644 --- a/config/firewall/firewall-lib.pl +++ b/config/firewall/firewall-lib.pl @@ -391,8 +391,9 @@ sub get_address # IPsec networks. } elsif ($key ~~ ["ipsec_net_src", "ipsec_net_tgt", "IpSec Network"]) { my $network_address = &get_ipsec_net_ip($value, 11); - if ($network_address) { - push(@ret, [$network_address, ""]); + my @nets = split(/\|/, $network_address); + foreach my $net (@nets) { + push(@ret, [$net, ""]); } # The firewall's own IP addresses. diff --git a/config/rootfiles/common/armv5tel/initscripts b/config/rootfiles/common/armv5tel/initscripts index b4cd8f857..a174c5b45 100644 --- a/config/rootfiles/common/armv5tel/initscripts +++ b/config/rootfiles/common/armv5tel/initscripts @@ -62,7 +62,6 @@ etc/rc.d/init.d/mounttmpfs #etc/rc.d/init.d/netsnmpd etc/rc.d/init.d/network etc/rc.d/init.d/network-trigger -etc/rc.d/init.d/network-vlans #etc/rc.d/init.d/networking etc/rc.d/init.d/networking/any etc/rc.d/init.d/networking/blue @@ -232,7 +231,6 @@ etc/rc.d/rcsysinit.d/S75firstsetup etc/rc.d/rcsysinit.d/S80localnet etc/rc.d/rcsysinit.d/S85firewall etc/rc.d/rcsysinit.d/S90network-trigger -etc/rc.d/rcsysinit.d/S91network-vlans etc/rc.d/rcsysinit.d/S92rngd etc/rc.d/rc3.d/S15fireinfo #etc/sysconfig diff --git a/config/rootfiles/common/i586/initscripts b/config/rootfiles/common/i586/initscripts index 878ba667e..84c432a05 100644 --- a/config/rootfiles/common/i586/initscripts +++ b/config/rootfiles/common/i586/initscripts @@ -64,7 +64,6 @@ etc/rc.d/init.d/mounttmpfs #etc/rc.d/init.d/netsnmpd etc/rc.d/init.d/network etc/rc.d/init.d/network-trigger -etc/rc.d/init.d/network-vlans #etc/rc.d/init.d/networking etc/rc.d/init.d/networking/any etc/rc.d/init.d/networking/blue @@ -237,7 +236,6 @@ etc/rc.d/rcsysinit.d/S75firstsetup etc/rc.d/rcsysinit.d/S80localnet etc/rc.d/rcsysinit.d/S85firewall etc/rc.d/rcsysinit.d/S90network-trigger -etc/rc.d/rcsysinit.d/S91network-vlans etc/rc.d/rcsysinit.d/S92rngd etc/rc.d/rc3.d/S15fireinfo #etc/sysconfig diff --git a/config/rootfiles/common/udev b/config/rootfiles/common/udev index d01c46101..4d519544d 100644 --- a/config/rootfiles/common/udev +++ b/config/rootfiles/common/udev @@ -29,6 +29,7 @@ lib/udev #lib/udev/init-net-rules.sh #lib/udev/mtd_probe #lib/udev/network-hotplug-rename +#lib/udev/network-hotplug-vlan #lib/udev/rule_generator.functions #lib/udev/rules.d #lib/udev/rules.d/25-alsa.rules diff --git a/config/rootfiles/core/94/exclude b/config/rootfiles/core/95/exclude similarity index 100% rename from config/rootfiles/core/94/exclude rename to config/rootfiles/core/95/exclude diff --git a/config/rootfiles/core/95/filelists/files b/config/rootfiles/core/95/filelists/files new file mode 100644 index 000000000..949c88baa --- /dev/null +++ b/config/rootfiles/core/95/filelists/files @@ -0,0 +1,8 @@ +etc/system-release +etc/issue +lib/udev/network-hotplug-vlan +lib/udev/rules.d/60-net.rules +srv/web/ipfire/cgi-bin/connections.cgi +srv/web/ipfire/cgi-bin/vpnmain.cgi +usr/lib/firewall/firewall-lib.pl +var/ipfire/langs diff --git a/config/rootfiles/core/94/meta b/config/rootfiles/core/95/meta similarity index 100% rename from config/rootfiles/core/94/meta rename to config/rootfiles/core/95/meta diff --git a/config/rootfiles/core/95/update.sh b/config/rootfiles/core/95/update.sh new file mode 100644 index 000000000..388e18d7c --- /dev/null +++ b/config/rootfiles/core/95/update.sh @@ -0,0 +1,61 @@ +#!/bin/bash +############################################################################ +# # +# This file is part of the IPFire Firewall. # +# # +# IPFire is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 3 of the License, or # +# (at your option) any later version. # +# # +# IPFire is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with IPFire; if not, write to the Free Software # +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +# # +# Copyright (C) 2015 IPFire-Team . # +# # +############################################################################ +# +. /opt/pakfire/lib/functions.sh +/usr/local/bin/backupctrl exclude >/dev/null 2>&1 + +# Remove old core updates from pakfire cache to save space... +core=95 +for (( i=1; i<=$core; i++ )) +do + rm -f /var/cache/pakfire/core-upgrade-*-$i.ipfire +done + +# Remove files +rm -f /etc/rc.d/init.d/network-vlans +rm -f /etc/rc.d/rcsysinit.d/S91network-vlans + +# Stop services + +# Extract files +extract_files + +# Update Language cache +/usr/local/bin/update-lang-cache + +# Start services + +# This update need a reboot... +#touch /var/run/need_reboot + +# Finish +/etc/init.d/fireinfo start +sendprofile +# Update grub config to display new core version +if [ -e /boot/grub/grub.cfg ]; then + grub-mkconfig -o /boot/grub/grub.cfg +fi +sync + +# Don't report the exitcode last command +exit 0 diff --git a/config/rootfiles/oldcore/94/exclude b/config/rootfiles/oldcore/94/exclude new file mode 100644 index 000000000..4c7aa5a5a --- /dev/null +++ b/config/rootfiles/oldcore/94/exclude @@ -0,0 +1,22 @@ +boot/config.txt +etc/alternatives +etc/collectd.custom +etc/ipsec.conf +etc/ipsec.secrets +etc/ipsec.user.conf +etc/ipsec.user.secrets +etc/localtime +etc/shadow +etc/ssh/ssh_config +etc/ssh/sshd_config +etc/ssl/openssl.cnf +etc/sudoers +etc/sysconfig/firewall.local +etc/sysconfig/rc.local +etc/udev/rules.d/30-persistent-network.rules +srv/web/ipfire/html/proxy.pac +var/ipfire/ovpn +var/lib/alternatives +var/log/cache +var/state/dhcp/dhcpd.leases +var/updatecache diff --git a/config/rootfiles/core/94/filelists/armv5tel/glibc b/config/rootfiles/oldcore/94/filelists/armv5tel/glibc similarity index 100% rename from config/rootfiles/core/94/filelists/armv5tel/glibc rename to config/rootfiles/oldcore/94/filelists/armv5tel/glibc diff --git a/config/rootfiles/core/94/filelists/bind b/config/rootfiles/oldcore/94/filelists/bind similarity index 100% rename from config/rootfiles/core/94/filelists/bind rename to config/rootfiles/oldcore/94/filelists/bind diff --git a/config/rootfiles/core/94/filelists/chkconfig b/config/rootfiles/oldcore/94/filelists/chkconfig similarity index 100% rename from config/rootfiles/core/94/filelists/chkconfig rename to config/rootfiles/oldcore/94/filelists/chkconfig diff --git a/config/rootfiles/core/94/filelists/coreutils b/config/rootfiles/oldcore/94/filelists/coreutils similarity index 100% rename from config/rootfiles/core/94/filelists/coreutils rename to config/rootfiles/oldcore/94/filelists/coreutils diff --git a/config/rootfiles/core/94/filelists/dma b/config/rootfiles/oldcore/94/filelists/dma similarity index 100% rename from config/rootfiles/core/94/filelists/dma rename to config/rootfiles/oldcore/94/filelists/dma diff --git a/config/rootfiles/core/94/filelists/dnsmasq b/config/rootfiles/oldcore/94/filelists/dnsmasq similarity index 100% rename from config/rootfiles/core/94/filelists/dnsmasq rename to config/rootfiles/oldcore/94/filelists/dnsmasq diff --git a/config/rootfiles/core/94/filelists/file b/config/rootfiles/oldcore/94/filelists/file similarity index 100% rename from config/rootfiles/core/94/filelists/file rename to config/rootfiles/oldcore/94/filelists/file diff --git a/config/rootfiles/core/94/filelists/files b/config/rootfiles/oldcore/94/filelists/files similarity index 100% rename from config/rootfiles/core/94/filelists/files rename to config/rootfiles/oldcore/94/filelists/files diff --git a/config/rootfiles/core/94/filelists/fireinfo b/config/rootfiles/oldcore/94/filelists/fireinfo similarity index 100% rename from config/rootfiles/core/94/filelists/fireinfo rename to config/rootfiles/oldcore/94/filelists/fireinfo diff --git a/config/rootfiles/core/94/filelists/hdparm b/config/rootfiles/oldcore/94/filelists/hdparm similarity index 100% rename from config/rootfiles/core/94/filelists/hdparm rename to config/rootfiles/oldcore/94/filelists/hdparm diff --git a/config/rootfiles/core/94/filelists/i586/glibc b/config/rootfiles/oldcore/94/filelists/i586/glibc similarity index 100% rename from config/rootfiles/core/94/filelists/i586/glibc rename to config/rootfiles/oldcore/94/filelists/i586/glibc diff --git a/config/rootfiles/core/94/filelists/iproute2 b/config/rootfiles/oldcore/94/filelists/iproute2 similarity index 100% rename from config/rootfiles/core/94/filelists/iproute2 rename to config/rootfiles/oldcore/94/filelists/iproute2 diff --git a/config/rootfiles/core/94/filelists/libgcrypt b/config/rootfiles/oldcore/94/filelists/libgcrypt similarity index 100% rename from config/rootfiles/core/94/filelists/libgcrypt rename to config/rootfiles/oldcore/94/filelists/libgcrypt diff --git a/config/rootfiles/core/94/filelists/libgpg-error b/config/rootfiles/oldcore/94/filelists/libgpg-error similarity index 100% rename from config/rootfiles/core/94/filelists/libgpg-error rename to config/rootfiles/oldcore/94/filelists/libgpg-error diff --git a/config/rootfiles/core/94/filelists/openssh b/config/rootfiles/oldcore/94/filelists/openssh similarity index 100% rename from config/rootfiles/core/94/filelists/openssh rename to config/rootfiles/oldcore/94/filelists/openssh diff --git a/config/rootfiles/core/94/filelists/pcre b/config/rootfiles/oldcore/94/filelists/pcre similarity index 100% rename from config/rootfiles/core/94/filelists/pcre rename to config/rootfiles/oldcore/94/filelists/pcre diff --git a/config/rootfiles/core/94/filelists/perl-Email-Date-Format b/config/rootfiles/oldcore/94/filelists/perl-Email-Date-Format similarity index 100% rename from config/rootfiles/core/94/filelists/perl-Email-Date-Format rename to config/rootfiles/oldcore/94/filelists/perl-Email-Date-Format diff --git a/config/rootfiles/core/94/filelists/perl-MIME-Lite b/config/rootfiles/oldcore/94/filelists/perl-MIME-Lite similarity index 100% rename from config/rootfiles/core/94/filelists/perl-MIME-Lite rename to config/rootfiles/oldcore/94/filelists/perl-MIME-Lite diff --git a/config/rootfiles/core/94/filelists/rrdtool b/config/rootfiles/oldcore/94/filelists/rrdtool similarity index 100% rename from config/rootfiles/core/94/filelists/rrdtool rename to config/rootfiles/oldcore/94/filelists/rrdtool diff --git a/config/rootfiles/core/94/filelists/setup b/config/rootfiles/oldcore/94/filelists/setup similarity index 100% rename from config/rootfiles/core/94/filelists/setup rename to config/rootfiles/oldcore/94/filelists/setup diff --git a/config/rootfiles/core/94/filelists/squid b/config/rootfiles/oldcore/94/filelists/squid similarity index 100% rename from config/rootfiles/core/94/filelists/squid rename to config/rootfiles/oldcore/94/filelists/squid diff --git a/config/rootfiles/oldcore/94/meta b/config/rootfiles/oldcore/94/meta new file mode 100644 index 000000000..d547fa86f --- /dev/null +++ b/config/rootfiles/oldcore/94/meta @@ -0,0 +1 @@ +DEPS="" diff --git a/config/rootfiles/core/94/update.sh b/config/rootfiles/oldcore/94/update.sh similarity index 100% rename from config/rootfiles/core/94/update.sh rename to config/rootfiles/oldcore/94/update.sh diff --git a/config/udev/60-net.rules b/config/udev/60-net.rules index 4f22a1e30..dc39ff09b 100644 --- a/config/udev/60-net.rules +++ b/config/udev/60-net.rules @@ -1,3 +1,7 @@ # Call a script that checks for the right name of the new device. # If it matches the configuration it will be renamed accordingly. ACTION=="add", SUBSYSTEM=="net", PROGRAM="/lib/udev/network-hotplug-rename", RESULT=="?*", NAME="$result" + +# Call a script that will create all virtual devices for a parent device +# that has just come up. +ACTION=="add", SUBSYSTEM=="net", PROGRAM="/lib/udev/network-hotplug-vlan" diff --git a/src/initscripts/init.d/network-vlans b/config/udev/network-hotplug-vlan similarity index 60% rename from src/initscripts/init.d/network-vlans rename to config/udev/network-hotplug-vlan index a6a75c35f..f7b6a9de1 100644 --- a/src/initscripts/init.d/network-vlans +++ b/config/udev/network-hotplug-vlan @@ -17,10 +17,12 @@ # along with IPFire; if not, write to the Free Software # # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # -# Copyright (C) 2012 IPFire Team # +# Copyright (C) 2015 IPFire Team # # # ############################################################################ +[ -n "${INTERFACE}" ] || exit 2 + CONFIG_FILE="/var/ipfire/ethernet/vlans" # Skip immediately if no configuration file has been found. @@ -28,9 +30,6 @@ CONFIG_FILE="/var/ipfire/ethernet/vlans" eval $(/usr/local/bin/readhash ${CONFIG_FILE}) -# This is start or stop. -action=${1} - for interface in green0 red0 blue0 orange0; do case "${interface}" in green*) @@ -55,59 +54,34 @@ for interface in green0 red0 blue0 orange0; do ;; esac - case "${action}" in - start) - # If no parent device has been configured, we assume - # that this interface is not set up for VLANs and - # silently go on. - [ -z "${PARENT_DEV}" ] && continue + # If the parent device does not match the interface that + # has just come up, we will go on for the next one. + [ "${PARENT_DEV}" = "${INTERFACE}" ] || continue - # Check if the interface does already exists. - # If so, we skip creating it. - if [ -d "/sys/class/net/${interface}" ]; then - echo "Interface ${interface} already exists." >&2 - continue - fi + # Check if the interface does already exists. + # If so, we skip creating it. + if [ -d "/sys/class/net/${interface}" ]; then + echo "Interface ${interface} already exists." >&2 + continue + fi - # Check if the parent interface exists. - if [ ! -d "/sys/class/net/${PARENT_DEV}" ]; then - echo "${interface}: Parent device is not set or does not exist: ${PARENT_DEV}" >&2 - continue - fi + if [ -z "${VLAN_ID}" ]; then + echo "${interface}: You did not set the VLAN ID." >&2 + continue + fi - if [ -z "${VLAN_ID}" ]; then - echo "${interface}: You did not set the VLAN ID." >&2 - continue - fi + # Build command line. + command="ip link add link ${PARENT_DEV} name ${interface}" + if [ -n "${MAC_ADDRESS}" ]; then + command="${command} address ${MAC_ADDRESS}" + fi + command="${command} type vlan id ${VLAN_ID}" - # Build command line. - command="ip link add link ${PARENT_DEV} name ${interface}" - if [ -n "${MAC_ADDRESS}" ]; then - command="${command} address ${MAC_ADDRESS}" - fi - command="${command} type vlan id ${VLAN_ID}" + echo "Creating VLAN interface ${interface}..." + ${command} - echo "Creating VLAN interface ${interface}..." - ${command} - - # Bring up the parent device. - ip link set ${PARENT_DEV} up - ;; - - stop) - if [ ! -e "/proc/net/vlan/${interface}" ]; then - echo "${interface} is not a VLAN interface. Skipping." - continue - fi - - echo "Removing VLAN interface ${interface}..." - ip link set ${interface} down - ip link delete ${interface} - ;; - - *) - echo "Invalid action: ${action}" - exit 1 - ;; - esac + # Bring up the parent device. + ip link set ${PARENT_DEV} up done + +exit 0 diff --git a/html/cgi-bin/connections.cgi b/html/cgi-bin/connections.cgi index 4eb9cd7bf..85a9cd745 100644 --- a/html/cgi-bin/connections.cgi +++ b/html/cgi-bin/connections.cgi @@ -261,15 +261,19 @@ close(IPSEC); foreach my $line (@ipsec) { my @vpn = split(',', $line); - my ($network, $mask) = split("/", $vpn[12]); - if (!&General::validip($mask)) { - $mask = ipv4_cidr2msk($mask); + my @subnets = split('|', $vpn[12]); + for my $subnet (@subnets) { + my ($network, $mask) = split("/", $subnet); + + if (!&General::validip($mask)) { + $mask = ipv4_cidr2msk($mask); + } + + push(@network, $network); + push(@masklen, $mask); + push(@colour, ${Header::colourvpn}); } - - push(@network, $network); - push(@masklen, $mask); - push(@colour, ${Header::colourvpn}); } if (-e "${General::swroot}/ovpn/n2nconf") { diff --git a/html/cgi-bin/vpnmain.cgi b/html/cgi-bin/vpnmain.cgi index 65fc80ff8..b697b0aeb 100644 --- a/html/cgi-bin/vpnmain.cgi +++ b/html/cgi-bin/vpnmain.cgi @@ -40,8 +40,7 @@ undef (@dummy); ### ### Initialize variables ### -my $sleepDelay = 4; # after a call to ipsecctrl S or R, wait this delay (seconds) before reading status - # (let the ipsec do its job) +my $sleepDelay = 4; # after a call to ipsecctrl S or R, wait this delay (seconds) before reading status (let the ipsec do its job) my %netsettings=(); our %cgiparams=(); our %vpnsettings=(); @@ -132,306 +131,300 @@ sub valid_dns_host { ### Just return true is one interface is vpn enabled ### sub vpnenabled { - return ($vpnsettings{'ENABLED'} eq 'on'); + return ($vpnsettings{'ENABLED'} eq 'on'); } ### -### old version: maintain serial number to one, without explication. -### this : let the counter go, so that each cert is numbered. +### old version: maintain serial number to one, without explication. +### this: let the counter go, so that each cert is numbered. ### -sub cleanssldatabase -{ - if (open(FILE, ">${General::swroot}/certs/serial")) { - print FILE "01"; - close FILE; - } - if (open(FILE, ">${General::swroot}/certs/index.txt")) { - print FILE ""; - close FILE; - } - unlink ("${General::swroot}/certs/index.txt.old"); - unlink ("${General::swroot}/certs/serial.old"); - unlink ("${General::swroot}/certs/01.pem"); +sub cleanssldatabase { + if (open(FILE, ">${General::swroot}/certs/serial")) { + print FILE "01"; + close FILE; + } + if (open(FILE, ">${General::swroot}/certs/index.txt")) { + print FILE ""; + close FILE; + } + unlink ("${General::swroot}/certs/index.txt.old"); + unlink ("${General::swroot}/certs/serial.old"); + unlink ("${General::swroot}/certs/01.pem"); } -sub newcleanssldatabase -{ - if (! -s "${General::swroot}/certs/serial" ) { - open(FILE, ">${General::swroot}/certs/serial"); - print FILE "01"; - close FILE; - } - if (! -s ">${General::swroot}/certs/index.txt") { - system ("touch ${General::swroot}/certs/index.txt"); - } - unlink ("${General::swroot}/certs/index.txt.old"); - unlink ("${General::swroot}/certs/serial.old"); -# unlink ("${General::swroot}/certs/01.pem"); numbering evolves. Wrong place to delete +sub newcleanssldatabase { + if (! -s "${General::swroot}/certs/serial" ) { + open(FILE, ">${General::swroot}/certs/serial"); + print FILE "01"; + close FILE; + } + if (! -s ">${General::swroot}/certs/index.txt") { + system ("touch ${General::swroot}/certs/index.txt"); + } + unlink ("${General::swroot}/certs/index.txt.old"); + unlink ("${General::swroot}/certs/serial.old"); +# unlink ("${General::swroot}/certs/01.pem"); numbering evolves. Wrong place to delete } ### ### Call openssl and return errormessage if any ### sub callssl ($) { - my $opt = shift; - my $retssl = `/usr/bin/openssl $opt 2>&1`; #redirect stderr - my $ret = ''; - foreach my $line (split (/\n/, $retssl)) { - &General::log("ipsec", "$line") if (0); # 1 for verbose logging - $ret .= '
'.$line if ( $line =~ /error|unknown/ ); - } - if ($ret) { - $ret= &Header::cleanhtml($ret); - } - return $ret ? "$Lang::tr{'openssl produced an error'}: $ret" : '' ; + my $opt = shift; + my $retssl = `/usr/bin/openssl $opt 2>&1`; #redirect stderr + my $ret = ''; + foreach my $line (split (/\n/, $retssl)) { + &General::log("ipsec", "$line") if (0); # 1 for verbose logging + $ret .= '
'.$line if ( $line =~ /error|unknown/ ); + } + if ($ret) { + $ret= &Header::cleanhtml($ret); + } + return $ret ? "$Lang::tr{'openssl produced an error'}: $ret" : '' ; } ### ### Obtain a CN from given cert ### sub getCNfromcert ($) { - #&General::log("ipsec", "Extracting name from $_[0]..."); - my $temp = `/usr/bin/openssl x509 -text -in $_[0]`; - $temp =~ /Subject:.*CN=(.*)[\n]/; - $temp = $1; - $temp =~ s+/Email+, E+; - $temp =~ s/ ST=/ S=/; - $temp =~ s/,//g; - $temp =~ s/\'//g; - return $temp; + #&General::log("ipsec", "Extracting name from $_[0]..."); + my $temp = `/usr/bin/openssl x509 -text -in $_[0]`; + $temp =~ /Subject:.*CN=(.*)[\n]/; + $temp = $1; + $temp =~ s+/Email+, E+; + $temp =~ s/ ST=/ S=/; + $temp =~ s/,//g; + $temp =~ s/\'//g; + return $temp; } ### ### Obtain Subject from given cert ### sub getsubjectfromcert ($) { - #&General::log("ipsec", "Extracting subject from $_[0]..."); - my $temp = `/usr/bin/openssl x509 -text -in $_[0]`; - $temp =~ /Subject: (.*)[\n]/; - $temp = $1; - $temp =~ s+/Email+, E+; - $temp =~ s/ ST=/ S=/; - return $temp; + #&General::log("ipsec", "Extracting subject from $_[0]..."); + my $temp = `/usr/bin/openssl x509 -text -in $_[0]`; + $temp =~ /Subject: (.*)[\n]/; + $temp = $1; + $temp =~ s+/Email+, E+; + $temp =~ s/ ST=/ S=/; + return $temp; } ### -### Combine local subnet and connection name to make a unique name for each connection section +### Combine local subnet and connection name to make a unique name for each connection section ### (this sub is not used now) ### sub makeconnname ($) { - my $conn = shift; - my $subnet = shift; + my $conn = shift; + my $subnet = shift; - $subnet =~ /^(.*?)\/(.*?)$/; # $1=IP $2=mask - my $ip = unpack('N', &Socket::inet_aton($1)); - if (length ($2) > 2) { - my $mm = unpack('N', &Socket::inet_aton($2)); - while ( ($mm & 1)==0 ) { - $ip >>= 1; - $mm >>= 1; - }; - } else { - $ip >>= (32 - $2); - } - return sprintf ("%s-%X", $conn, $ip); + $subnet =~ /^(.*?)\/(.*?)$/; # $1=IP $2=mask + my $ip = unpack('N', &Socket::inet_aton($1)); + if (length ($2) > 2) { + my $mm = unpack('N', &Socket::inet_aton($2)); + while ( ($mm & 1)==0 ) { + $ip >>= 1; + $mm >>= 1; + }; + } else { + $ip >>= (32 - $2); + } + return sprintf ("%s-%X", $conn, $ip); } ### ### Write a config file. ### ###Type=Host : GUI can choose the interface used (RED,GREEN,BLUE) and ### the side is always defined as 'left'. -### configihash[14]: 'VHOST' is allowed ### sub writeipsecfiles { - my %lconfighash = (); - my %lvpnsettings = (); - &General::readhasharray("${General::swroot}/vpn/config", \%lconfighash); - &General::readhash("${General::swroot}/vpn/settings", \%lvpnsettings); - - open(CONF, ">${General::swroot}/vpn/ipsec.conf") or die "Unable to open ${General::swroot}/vpn/ipsec.conf: $!"; - open(SECRETS, ">${General::swroot}/vpn/ipsec.secrets") or die "Unable to open ${General::swroot}/vpn/ipsec.secrets: $!"; - flock CONF, 2; - flock SECRETS, 2; - print CONF "version 2\n\n"; - print CONF "conn %default\n"; - print CONF "\tkeyingtries=%forever\n"; - print CONF "\n"; - - # Add user includes to config file - if (-e "/etc/ipsec.user.conf") { - print CONF "include /etc/ipsec.user.conf\n"; - print CONF "\n"; - } - - print SECRETS "include /etc/ipsec.user.secrets\n"; - - if (-f "${General::swroot}/certs/hostkey.pem") { - print SECRETS ": RSA ${General::swroot}/certs/hostkey.pem\n" - } - my $last_secrets = ''; # old the less specifics connections - - foreach my $key (keys %lconfighash) { - next if ($lconfighash{$key}[0] ne 'on'); - - #remote peer is not set? => use '%any' - $lconfighash{$key}[10] = '%any' if ($lconfighash{$key}[10] eq ''); - - my $localside; - if ($lconfighash{$key}[26] eq 'BLUE') { - $localside = $netsettings{'BLUE_ADDRESS'}; - } elsif ($lconfighash{$key}[26] eq 'GREEN') { - $localside = $netsettings{'GREEN_ADDRESS'}; - } elsif ($lconfighash{$key}[26] eq 'ORANGE') { - $localside = $netsettings{'ORANGE_ADDRESS'}; - } else { # it is RED - $localside = $lvpnsettings{'VPN_IP'}; - } - - print CONF "conn $lconfighash{$key}[1]\n"; - print CONF "\tleft=$localside\n"; - my $cidr_net=&General::ipcidr($lconfighash{$key}[8]); - print CONF "\tleftsubnet=$cidr_net\n"; - print CONF "\tleftfirewall=yes\n"; - print CONF "\tlefthostaccess=yes\n"; - - print CONF "\tright=$lconfighash{$key}[10]\n"; - if ($lconfighash{$key}[3] eq 'net') { - my $cidr_net=&General::ipcidr($lconfighash{$key}[11]); - print CONF "\trightsubnet=$cidr_net\n"; - } elsif ($lconfighash{$key}[10] eq '%any' && $lconfighash{$key}[14] eq 'on') { #vhost allowed for roadwarriors? - print CONF "\trightsubnet=vhost:%no,%priv\n"; - } - - # Local Cert and Remote Cert (unless auth is DN dn-auth) - if ($lconfighash{$key}[4] eq 'cert') { - print CONF "\tleftcert=${General::swroot}/certs/hostcert.pem\n"; - print CONF "\trightcert=${General::swroot}/certs/$lconfighash{$key}[1]cert.pem\n" if ($lconfighash{$key}[2] ne '%auth-dn'); - } - - # Local and Remote IDs - print CONF "\tleftid=\"$lconfighash{$key}[7]\"\n" if ($lconfighash{$key}[7]); - print CONF "\trightid=\"$lconfighash{$key}[9]\"\n" if ($lconfighash{$key}[9]); - - # Is PFS enabled? - my $pfs = $lconfighash{$key}[28] eq 'on' ? 'on' : 'off'; - - # Algorithms - if ($lconfighash{$key}[18] && $lconfighash{$key}[19] && $lconfighash{$key}[20]) { - my @encs = split('\|', $lconfighash{$key}[18]); - my @ints = split('\|', $lconfighash{$key}[19]); - my @groups = split('\|', $lconfighash{$key}[20]); - - my @algos = &make_algos("ike", \@encs, \@ints, \@groups, 1); - print CONF "\tike=" . join(",", @algos); - - if ($lconfighash{$key}[24] eq 'on') { #only proposed algorythms? - print CONF "!\n"; - } else { - print CONF "\n"; - } - } - - if ($lconfighash{$key}[21] && $lconfighash{$key}[22]) { - my @encs = split('\|', $lconfighash{$key}[21]); - my @ints = split('\|', $lconfighash{$key}[22]); - my @groups = split('\|', $lconfighash{$key}[23]); - - # Use IKE grouptype if no ESP group type has been selected - # (for backwards compatibility) - if ($lconfighash{$key}[23] eq "") { - @groups = split('\|', $lconfighash{$key}[20]); - } - - my @algos = &make_algos("esp", \@encs, \@ints, \@groups, ($pfs eq "on")); - print CONF "\tesp=" . join(",", @algos); - - if ($lconfighash{$key}[24] eq 'on') { #only proposed algorythms? - print CONF "!\n"; - } else { - print CONF "\n"; - } - } - - # IKE V1 or V2 - if (! $lconfighash{$key}[29]) { - $lconfighash{$key}[29] = "ikev1"; - } - print CONF "\tkeyexchange=$lconfighash{$key}[29]\n"; - - # Lifetimes - print CONF "\tikelifetime=$lconfighash{$key}[16]h\n" if ($lconfighash{$key}[16]); - print CONF "\tkeylife=$lconfighash{$key}[17]h\n" if ($lconfighash{$key}[17]); - - # Compression - print CONF "\tcompress=yes\n" if ($lconfighash{$key}[13] eq 'on'); - - # Force MOBIKE? - if (($lconfighash{$key}[29] eq "ikev2") && ($lconfighash{$key}[32] eq 'on')) { - print CONF "\tmobike=yes\n"; - } - - # Dead Peer Detection - my $dpdaction = $lconfighash{$key}[27]; - print CONF "\tdpdaction=$dpdaction\n"; - - # If the dead peer detection is disabled and IKEv2 is used, - # dpddelay must be set to zero, too. - if ($dpdaction eq "none") { - if ($lconfighash{$key}[29] eq "ikev2") { - print CONF "\tdpddelay=0\n"; - } - } else { - my $dpddelay = $lconfighash{$key}[31]; - if (!$dpddelay) { - $dpddelay = 30; - } - print CONF "\tdpddelay=$dpddelay\n"; - my $dpdtimeout = $lconfighash{$key}[30]; - if (!$dpdtimeout) { - $dpdtimeout = 120; - } - print CONF "\tdpdtimeout=$dpdtimeout\n"; - } - - # Build Authentication details: LEFTid RIGHTid : PSK psk - my $psk_line; - if ($lconfighash{$key}[4] eq 'psk') { - $psk_line = ($lconfighash{$key}[7] ? $lconfighash{$key}[7] : $localside) . " " ; - $psk_line .= $lconfighash{$key}[9] ? $lconfighash{$key}[9] : $lconfighash{$key}[10]; #remoteid or remote address? - $psk_line .= " : PSK '$lconfighash{$key}[5]'\n"; - # if the line contains %any, it is less specific than two IP or ID, so move it at end of file. - if ($psk_line =~ /%any/) { - $last_secrets .= $psk_line; - } else { - print SECRETS $psk_line; - } - print CONF "\tauthby=secret\n"; - } else { - print CONF "\tauthby=rsasig\n"; - print CONF "\tleftrsasigkey=%cert\n"; - print CONF "\trightrsasigkey=%cert\n"; - } - - # Automatically start only if a net-to-net connection - if ($lconfighash{$key}[3] eq 'host') { - print CONF "\tauto=add\n"; - print CONF "\trightsourceip=$lvpnsettings{'RW_NET'}\n"; - } else { - print CONF "\tauto=start\n"; - } - - # Fragmentation - print CONF "\tfragmentation=yes\n"; + my %lconfighash = (); + my %lvpnsettings = (); + &General::readhasharray("${General::swroot}/vpn/config", \%lconfighash); + &General::readhash("${General::swroot}/vpn/settings", \%lvpnsettings); + open(CONF, ">${General::swroot}/vpn/ipsec.conf") or die "Unable to open ${General::swroot}/vpn/ipsec.conf: $!"; + open(SECRETS, ">${General::swroot}/vpn/ipsec.secrets") or die "Unable to open ${General::swroot}/vpn/ipsec.secrets: $!"; + flock CONF, 2; + flock SECRETS, 2; + print CONF "version 2\n\n"; + print CONF "conn %default\n"; + print CONF "\tkeyingtries=%forever\n"; print CONF "\n"; - }#foreach key - # Add post user includes to config file - # After the GUI-connections allows to patch connections. - if (-e "/etc/ipsec.user-post.conf") { - print CONF "include /etc/ipsec.user-post.conf\n"; - print CONF "\n"; - } + # Add user includes to config file + if (-e "/etc/ipsec.user.conf") { + print CONF "include /etc/ipsec.user.conf\n"; + print CONF "\n"; + } - print SECRETS $last_secrets if ($last_secrets); - close(CONF); - close(SECRETS); + print SECRETS "include /etc/ipsec.user.secrets\n"; + + if (-f "${General::swroot}/certs/hostkey.pem") { + print SECRETS ": RSA ${General::swroot}/certs/hostkey.pem\n" + } + my $last_secrets = ''; # old the less specifics connections + + foreach my $key (keys %lconfighash) { + next if ($lconfighash{$key}[0] ne 'on'); + + #remote peer is not set? => use '%any' + $lconfighash{$key}[10] = '%any' if ($lconfighash{$key}[10] eq ''); + + my $localside; + if ($lconfighash{$key}[26] eq 'BLUE') { + $localside = $netsettings{'BLUE_ADDRESS'}; + } elsif ($lconfighash{$key}[26] eq 'GREEN') { + $localside = $netsettings{'GREEN_ADDRESS'}; + } elsif ($lconfighash{$key}[26] eq 'ORANGE') { + $localside = $netsettings{'ORANGE_ADDRESS'}; + } else { # it is RED + $localside = $lvpnsettings{'VPN_IP'}; + } + + print CONF "conn $lconfighash{$key}[1]\n"; + print CONF "\tleft=$localside\n"; + print CONF "\tleftsubnet=" . &make_subnets($lconfighash{$key}[8]) . "\n"; + print CONF "\tleftfirewall=yes\n"; + print CONF "\tlefthostaccess=yes\n"; + print CONF "\tright=$lconfighash{$key}[10]\n"; + + if ($lconfighash{$key}[3] eq 'net') { + print CONF "\trightsubnet=" . &make_subnets($lconfighash{$key}[11]) . "\n"; + } + + # Local Cert and Remote Cert (unless auth is DN dn-auth) + if ($lconfighash{$key}[4] eq 'cert') { + print CONF "\tleftcert=${General::swroot}/certs/hostcert.pem\n"; + print CONF "\trightcert=${General::swroot}/certs/$lconfighash{$key}[1]cert.pem\n" if ($lconfighash{$key}[2] ne '%auth-dn'); + } + + # Local and Remote IDs + print CONF "\tleftid=\"$lconfighash{$key}[7]\"\n" if ($lconfighash{$key}[7]); + print CONF "\trightid=\"$lconfighash{$key}[9]\"\n" if ($lconfighash{$key}[9]); + + # Is PFS enabled? + my $pfs = $lconfighash{$key}[28] eq 'on' ? 'on' : 'off'; + + # Algorithms + if ($lconfighash{$key}[18] && $lconfighash{$key}[19] && $lconfighash{$key}[20]) { + my @encs = split('\|', $lconfighash{$key}[18]); + my @ints = split('\|', $lconfighash{$key}[19]); + my @groups = split('\|', $lconfighash{$key}[20]); + + my @algos = &make_algos("ike", \@encs, \@ints, \@groups, 1); + print CONF "\tike=" . join(",", @algos); + + if ($lconfighash{$key}[24] eq 'on') { #only proposed algorythms? + print CONF "!\n"; + } else { + print CONF "\n"; + } + } + + if ($lconfighash{$key}[21] && $lconfighash{$key}[22]) { + my @encs = split('\|', $lconfighash{$key}[21]); + my @ints = split('\|', $lconfighash{$key}[22]); + my @groups = split('\|', $lconfighash{$key}[23]); + + # Use IKE grouptype if no ESP group type has been selected + # (for backwards compatibility) + if ($lconfighash{$key}[23] eq "") { + @groups = split('\|', $lconfighash{$key}[20]); + } + + my @algos = &make_algos("esp", \@encs, \@ints, \@groups, ($pfs eq "on")); + print CONF "\tesp=" . join(",", @algos); + + if ($lconfighash{$key}[24] eq 'on') { #only proposed algorythms? + print CONF "!\n"; + } else { + print CONF "\n"; + } + } + + # IKE V1 or V2 + if (! $lconfighash{$key}[29]) { + $lconfighash{$key}[29] = "ikev1"; + } + + print CONF "\tkeyexchange=$lconfighash{$key}[29]\n"; + + # Lifetimes + print CONF "\tikelifetime=$lconfighash{$key}[16]h\n" if ($lconfighash{$key}[16]); + print CONF "\tkeylife=$lconfighash{$key}[17]h\n" if ($lconfighash{$key}[17]); + + # Compression + print CONF "\tcompress=yes\n" if ($lconfighash{$key}[13] eq 'on'); + + # Force MOBIKE? + if (($lconfighash{$key}[29] eq "ikev2") && ($lconfighash{$key}[32] eq 'on')) { + print CONF "\tmobike=yes\n"; + } + + # Dead Peer Detection + my $dpdaction = $lconfighash{$key}[27]; + print CONF "\tdpdaction=$dpdaction\n"; + + # If the dead peer detection is disabled and IKEv2 is used, + # dpddelay must be set to zero, too. + if ($dpdaction eq "none") { + if ($lconfighash{$key}[29] eq "ikev2") { + print CONF "\tdpddelay=0\n"; + } + } else { + my $dpddelay = $lconfighash{$key}[31]; + if (!$dpddelay) { + $dpddelay = 30; + } + print CONF "\tdpddelay=$dpddelay\n"; + my $dpdtimeout = $lconfighash{$key}[30]; + if (!$dpdtimeout) { + $dpdtimeout = 120; + } + print CONF "\tdpdtimeout=$dpdtimeout\n"; + } + + # Build Authentication details: LEFTid RIGHTid : PSK psk + my $psk_line; + if ($lconfighash{$key}[4] eq 'psk') { + $psk_line = ($lconfighash{$key}[7] ? $lconfighash{$key}[7] : $localside) . " " ; + $psk_line .= $lconfighash{$key}[9] ? $lconfighash{$key}[9] : $lconfighash{$key}[10]; #remoteid or remote address? + $psk_line .= " : PSK '$lconfighash{$key}[5]'\n"; + # if the line contains %any, it is less specific than two IP or ID, so move it at end of file. + if ($psk_line =~ /%any/) { + $last_secrets .= $psk_line; + } else { + print SECRETS $psk_line; + } + print CONF "\tauthby=secret\n"; + } else { + print CONF "\tauthby=rsasig\n"; + print CONF "\tleftrsasigkey=%cert\n"; + print CONF "\trightrsasigkey=%cert\n"; + } + + # Automatically start only if a net-to-net connection + if ($lconfighash{$key}[3] eq 'host') { + print CONF "\tauto=add\n"; + print CONF "\trightsourceip=$lvpnsettings{'RW_NET'}\n"; + } else { + print CONF "\tauto=start\n"; + } + + # Fragmentation + print CONF "\tfragmentation=yes\n"; + + print CONF "\n"; + } #foreach key + + # Add post user includes to config file + # After the GUI-connections allows to patch connections. + if (-e "/etc/ipsec.user-post.conf") { + print CONF "include /etc/ipsec.user-post.conf\n"; + print CONF "\n"; + } + + print SECRETS $last_secrets if ($last_secrets); + close(CONF); + close(SECRETS); } # Hook to regenerate the configuration files. @@ -444,699 +437,291 @@ if ($ENV{"REMOTE_ADDR"} eq "") { ### Save main settings ### if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cgiparams{'KEY'} eq '') { - &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); - unless (&General::validfqdn($cgiparams{'VPN_IP'}) || &General::validip($cgiparams{'VPN_IP'}) - || $cgiparams{'VPN_IP'} eq '%defaultroute' ) { - $errormessage = $Lang::tr{'invalid input for hostname'}; - goto SAVE_ERROR; - } + &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); - unless ($cgiparams{'VPN_DELAYED_START'} =~ /^[0-9]{1,3}$/ ) { #allow 0-999 seconds ! - $errormessage = $Lang::tr{'invalid time period'}; - goto SAVE_ERROR; - } + unless (&General::validfqdn($cgiparams{'VPN_IP'}) || &General::validip($cgiparams{'VPN_IP'}) + || $cgiparams{'VPN_IP'} eq '%defaultroute' ) { + $errormessage = $Lang::tr{'invalid input for hostname'}; + goto SAVE_ERROR; + } - if ( $cgiparams{'RW_NET'} ne '' and !&General::validipandmask($cgiparams{'RW_NET'}) ) { - $errormessage = $Lang::tr{'urlfilter invalid ip or mask error'}; - goto SAVE_ERROR; - } + unless ($cgiparams{'VPN_DELAYED_START'} =~ /^[0-9]{1,3}$/ ) { #allow 0-999 seconds ! + $errormessage = $Lang::tr{'invalid time period'}; + goto SAVE_ERROR; + } - $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'}; - $vpnsettings{'VPN_IP'} = $cgiparams{'VPN_IP'}; - $vpnsettings{'VPN_DELAYED_START'} = $cgiparams{'VPN_DELAYED_START'}; - $vpnsettings{'RW_NET'} = $cgiparams{'RW_NET'}; - &General::writehash("${General::swroot}/vpn/settings", \%vpnsettings); - &writeipsecfiles(); - if (&vpnenabled) { - system('/usr/local/bin/ipsecctrl', 'S'); - } else { - system('/usr/local/bin/ipsecctrl', 'D'); - } - sleep $sleepDelay; - SAVE_ERROR: + if ( $cgiparams{'RW_NET'} ne '' and !&General::validipandmask($cgiparams{'RW_NET'}) ) { + $errormessage = $Lang::tr{'urlfilter invalid ip or mask error'}; + goto SAVE_ERROR; + } + + $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'}; + $vpnsettings{'VPN_IP'} = $cgiparams{'VPN_IP'}; + $vpnsettings{'VPN_DELAYED_START'} = $cgiparams{'VPN_DELAYED_START'}; + $vpnsettings{'RW_NET'} = $cgiparams{'RW_NET'}; + &General::writehash("${General::swroot}/vpn/settings", \%vpnsettings); + &writeipsecfiles(); + if (&vpnenabled) { + system('/usr/local/bin/ipsecctrl', 'S'); + } else { + system('/usr/local/bin/ipsecctrl', 'D'); + } + sleep $sleepDelay; + SAVE_ERROR: ### ### Reset all step 2 ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove x509'} && $cgiparams{'AREUSURE'} eq 'yes') { - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - foreach my $key (keys %confighash) { - if ($confighash{$key}[4] eq 'cert') { - delete $confighash{$key}; + foreach my $key (keys %confighash) { + if ($confighash{$key}[4] eq 'cert') { + delete $confighash{$key}; + } } - } - while (my $file = glob("${General::swroot}/{ca,certs,crls,private}/*")) { - unlink $file - } - &cleanssldatabase(); - if (open(FILE, ">${General::swroot}/vpn/caconfig")) { - print FILE ""; - close FILE; - } - &General::writehasharray("${General::swroot}/vpn/config", \%confighash); - &writeipsecfiles(); - system('/usr/local/bin/ipsecctrl', 'R'); - sleep $sleepDelay; + while (my $file = glob("${General::swroot}/{ca,certs,crls,private}/*")) { + unlink $file + } + &cleanssldatabase(); + if (open(FILE, ">${General::swroot}/vpn/caconfig")) { + print FILE ""; + close FILE; + } + &General::writehasharray("${General::swroot}/vpn/config", \%confighash); + &writeipsecfiles(); + system('/usr/local/bin/ipsecctrl', 'R'); + sleep $sleepDelay; ### ### Reset all step 1 ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove x509'}) { - &Header::showhttpheaders(); - &Header::openpage($Lang::tr{'ipsec'}, 1, ''); - &Header::openbigbox('100%', 'left', '', ''); - &Header::openbox('100%', 'left', $Lang::tr{'are you sure'}); - print < - - - - - +
- - $Lang::tr{'capswarning'}: - $Lang::tr{'resetting the vpn configuration will remove the root ca, the host certificate and all certificate based connections'}
- + + + + + - -
+ + $Lang::tr{'capswarning'}: $Lang::tr{'resetting the vpn configuration will remove the root ca, the host certificate and all certificate based connections'} +
+
+
END - ; - &Header::closebox(); - &Header::closebigbox(); - &Header::closepage(); - exit (0); +; + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit (0); ### ### Upload CA Certificate ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload ca certificate'}) { - &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); + &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); - if ($cgiparams{'CA_NAME'} !~ /^[a-zA-Z0-9]+$/) { - $errormessage = $Lang::tr{'name must only contain characters'}; - goto UPLOADCA_ERROR; - } - - if (length($cgiparams{'CA_NAME'}) >60) { - $errormessage = $Lang::tr{'name too long'}; - goto VPNCONF_ERROR; - } - - if ($cgiparams{'CA_NAME'} eq 'ca') { - $errormessage = $Lang::tr{'name is invalid'}; - goto UPLOAD_CA_ERROR; - } - - # Check if there is no other entry with this name - foreach my $key (keys %cahash) { - if ($cahash{$key}[0] eq $cgiparams{'CA_NAME'}) { - $errormessage = $Lang::tr{'a ca certificate with this name already exists'}; - goto UPLOADCA_ERROR; + if ($cgiparams{'CA_NAME'} !~ /^[a-zA-Z0-9]+$/) { + $errormessage = $Lang::tr{'name must only contain characters'}; + goto UPLOADCA_ERROR; } - } - if (ref ($cgiparams{'FH'}) ne 'Fh') { - $errormessage = $Lang::tr{'there was no file upload'}; - goto UPLOADCA_ERROR; - } - # Move uploaded ca to a temporary file - (my $fh, my $filename) = tempfile( ); - if (copy ($cgiparams{'FH'}, $fh) != 1) { - $errormessage = $!; - goto UPLOADCA_ERROR; - } - my $temp = `/usr/bin/openssl x509 -text -in $filename`; - if ($temp !~ /CA:TRUE/i) { - $errormessage = $Lang::tr{'not a valid ca certificate'}; - unlink ($filename); - goto UPLOADCA_ERROR; - } else { - move($filename, "${General::swroot}/ca/$cgiparams{'CA_NAME'}cert.pem"); - if ($? ne 0) { - $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; - unlink ($filename); - goto UPLOADCA_ERROR; + if (length($cgiparams{'CA_NAME'}) >60) { + $errormessage = $Lang::tr{'name too long'}; + goto VPNCONF_ERROR; } - } - my $key = &General::findhasharraykey (\%cahash); - $cahash{$key}[0] = $cgiparams{'CA_NAME'}; - $cahash{$key}[1] = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/ca/$cgiparams{'CA_NAME'}cert.pem")); - &General::writehasharray("${General::swroot}/vpn/caconfig", \%cahash); + if ($cgiparams{'CA_NAME'} eq 'ca') { + $errormessage = $Lang::tr{'name is invalid'}; + goto UPLOAD_CA_ERROR; + } - system('/usr/local/bin/ipsecctrl', 'R'); - sleep $sleepDelay; + # Check if there is no other entry with this name + foreach my $key (keys %cahash) { + if ($cahash{$key}[0] eq $cgiparams{'CA_NAME'}) { + $errormessage = $Lang::tr{'a ca certificate with this name already exists'}; + goto UPLOADCA_ERROR; + } + } - UPLOADCA_ERROR: + if (ref ($cgiparams{'FH'}) ne 'Fh') { + $errormessage = $Lang::tr{'there was no file upload'}; + goto UPLOADCA_ERROR; + } + # Move uploaded ca to a temporary file + (my $fh, my $filename) = tempfile( ); + if (copy ($cgiparams{'FH'}, $fh) != 1) { + $errormessage = $!; + goto UPLOADCA_ERROR; + } + my $temp = `/usr/bin/openssl x509 -text -in $filename`; + if ($temp !~ /CA:TRUE/i) { + $errormessage = $Lang::tr{'not a valid ca certificate'}; + unlink ($filename); + goto UPLOADCA_ERROR; + } else { + move($filename, "${General::swroot}/ca/$cgiparams{'CA_NAME'}cert.pem"); + if ($? ne 0) { + $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; + unlink ($filename); + goto UPLOADCA_ERROR; + } + } + + my $key = &General::findhasharraykey (\%cahash); + $cahash{$key}[0] = $cgiparams{'CA_NAME'}; + $cahash{$key}[1] = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/ca/$cgiparams{'CA_NAME'}cert.pem")); + &General::writehasharray("${General::swroot}/vpn/caconfig", \%cahash); + + system('/usr/local/bin/ipsecctrl', 'R'); + sleep $sleepDelay; + + UPLOADCA_ERROR: ### ### Display ca certificate ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show ca certificate'}) { - &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); + &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); - if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem") { - &Header::showhttpheaders(); - &Header::openpage($Lang::tr{'ipsec'}, 1, ''); - &Header::openbigbox('100%', 'left', '', ''); - &Header::openbox('100%', 'left', "$Lang::tr{'ca certificate'}:"); - my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`; - $output = &Header::cleanhtml($output,"y"); - print "
$output
\n"; - &Header::closebox(); - print "
$Lang::tr{'back'}
"; - &Header::closebigbox(); - &Header::closepage(); - exit(0); - } else { - $errormessage = $Lang::tr{'invalid key'}; - } + if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem") { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'ipsec'}, 1, ''); + &Header::openbigbox('100%', 'left', '', ''); + &Header::openbox('100%', 'left', "$Lang::tr{'ca certificate'}:"); + my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`; + $output = &Header::cleanhtml($output,"y"); + print "
$output
\n"; + &Header::closebox(); + print "
$Lang::tr{'back'}
"; + &Header::closebigbox(); + &Header::closepage(); + exit(0); + } else { + $errormessage = $Lang::tr{'invalid key'}; + } ### ### Export ca certificate to browser ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download ca certificate'}) { - &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); + &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); - if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) { - print "Content-Type: application/force-download\n"; - print "Content-Type: application/octet-stream\r\n"; - print "Content-Disposition: attachment; filename=$cahash{$cgiparams{'KEY'}}[0]cert.pem\r\n\r\n"; - print `/usr/bin/openssl x509 -in ${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`; - exit(0); - } else { - $errormessage = $Lang::tr{'invalid key'}; - } + if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) { + print "Content-Type: application/force-download\n"; + print "Content-Type: application/octet-stream\r\n"; + print "Content-Disposition: attachment; filename=$cahash{$cgiparams{'KEY'}}[0]cert.pem\r\n\r\n"; + print `/usr/bin/openssl x509 -in ${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`; + exit(0); + } else { + $errormessage = $Lang::tr{'invalid key'}; + } ### ### Remove ca certificate (step 2) ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'} && $cgiparams{'AREUSURE'} eq 'yes') { - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); - if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) { - foreach my $key (keys %confighash) { - my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/certs/$confighash{$key}[1]cert.pem`; - if ($test =~ /: OK/) { - # Delete connection - system('/usr/local/bin/ipsecctrl', 'D', $key) if (&vpnenabled); - unlink ("${General::swroot}/certs/$confighash{$key}[1]cert.pem"); - unlink ("${General::swroot}/certs/$confighash{$key}[1].p12"); - delete $confighash{$key}; - &General::writehasharray("${General::swroot}/vpn/config", \%confighash); - &writeipsecfiles(); - } + if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) { + foreach my $key (keys %confighash) { + my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/certs/$confighash{$key}[1]cert.pem`; + if ($test =~ /: OK/) { + # Delete connection + system('/usr/local/bin/ipsecctrl', 'D', $key) if (&vpnenabled); + unlink ("${General::swroot}/certs/$confighash{$key}[1]cert.pem"); + unlink ("${General::swroot}/certs/$confighash{$key}[1].p12"); + delete $confighash{$key}; + &General::writehasharray("${General::swroot}/vpn/config", \%confighash); + &writeipsecfiles(); + } + } + unlink ("${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem"); + delete $cahash{$cgiparams{'KEY'}}; + &General::writehasharray("${General::swroot}/vpn/caconfig", \%cahash); + system('/usr/local/bin/ipsecctrl', 'R'); + sleep $sleepDelay; + } else { + $errormessage = $Lang::tr{'invalid key'}; } - unlink ("${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem"); - delete $cahash{$cgiparams{'KEY'}}; - &General::writehasharray("${General::swroot}/vpn/caconfig", \%cahash); - system('/usr/local/bin/ipsecctrl', 'R'); - sleep $sleepDelay; - } else { - $errormessage = $Lang::tr{'invalid key'}; - } ### ### Remove ca certificate (step 1) ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove ca certificate'}) { - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); - my $assignedcerts = 0; - if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) { - foreach my $key (keys %confighash) { - my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/certs/$confighash{$key}[1]cert.pem`; - if ($test =~ /: OK/) { - $assignedcerts++; - } - } - if ($assignedcerts) { - &Header::showhttpheaders(); - &Header::openpage($Lang::tr{'ipsec'}, 1, ''); - &Header::openbigbox('100%', 'left', '', ''); - &Header::openbox('100%', 'left', $Lang::tr{'are you sure'}); - print < - - - - - - - - -
- -
- $Lang::tr{'capswarning'} - $Lang::tr{'connections are associated with this ca. deleting the ca will delete these connections as well.'}
- -
- + my $assignedcerts = 0; + if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) { + foreach my $key (keys %confighash) { + my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/certs/$confighash{$key}[1]cert.pem`; + if ($test =~ /: OK/) { + $assignedcerts++; + } + } + if ($assignedcerts) { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'ipsec'}, 1, ''); + &Header::openbigbox('100%', 'left', '', ''); + &Header::openbox('100%', 'left', $Lang::tr{'are you sure'}); + print < + + + + + + + + +
+ +
+ $Lang::tr{'capswarning'} $Lang::tr{'connections are associated with this ca. deleting the ca will delete these connections as well.'}
+ +
+ END - ; - &Header::closebox(); - &Header::closebigbox(); - &Header::closepage(); - exit (0); +; + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit (0); + } else { + unlink ("${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem"); + delete $cahash{$cgiparams{'KEY'}}; + &General::writehasharray("${General::swroot}/vpn/caconfig", \%cahash); + system('/usr/local/bin/ipsecctrl', 'R'); + sleep $sleepDelay; + } } else { - unlink ("${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem"); - delete $cahash{$cgiparams{'KEY'}}; - &General::writehasharray("${General::swroot}/vpn/caconfig", \%cahash); - system('/usr/local/bin/ipsecctrl', 'R'); - sleep $sleepDelay; + $errormessage = $Lang::tr{'invalid key'}; } - } else { - $errormessage = $Lang::tr{'invalid key'}; - } ### ### Display root certificate ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'} || $cgiparams{'ACTION'} eq $Lang::tr{'show host certificate'}) { - my $output; - &Header::showhttpheaders(); - &Header::openpage($Lang::tr{'ipsec'}, 1, ''); - &Header::openbigbox('100%', 'left', '', ''); - if ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'}) { - &Header::openbox('100%', 'left', "$Lang::tr{'root certificate'}:"); - $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ca/cacert.pem`; - } else { - &Header::openbox('100%', 'left', "$Lang::tr{'host certificate'}:"); - $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/certs/hostcert.pem`; - } - $output = &Header::cleanhtml($output,"y"); - print "
$output
\n"; - &Header::closebox(); - print ""; - &Header::closebigbox(); - &Header::closepage(); - exit(0); - -### -### Export root certificate to browser -### -} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download root certificate'}) { - if ( -f "${General::swroot}/ca/cacert.pem" ) { - print "Content-Type: application/force-download\n"; - print "Content-Disposition: attachment; filename=cacert.pem\r\n\r\n"; - print `/usr/bin/openssl x509 -in ${General::swroot}/ca/cacert.pem`; - exit(0); - } -### -### Export host certificate to browser -### -} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download host certificate'}) { - if ( -f "${General::swroot}/certs/hostcert.pem" ) { - print "Content-Type: application/force-download\n"; - print "Content-Disposition: attachment; filename=hostcert.pem\r\n\r\n"; - print `/usr/bin/openssl x509 -in ${General::swroot}/certs/hostcert.pem`; - exit(0); - } -### -### Form for generating/importing the caroot+host certificate -### -} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate root/host certificates'} || - $cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) { - - if (-f "${General::swroot}/ca/cacert.pem") { - $errormessage = $Lang::tr{'valid root certificate already exists'}; - goto ROOTCERT_SKIP; - } - - &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); - # fill in initial values - if ($cgiparams{'ROOTCERT_HOSTNAME'} eq '') { - if (-e "${General::swroot}/red/active" && open(IPADDR, "${General::swroot}/red/local-ipaddress")) { - my $ipaddr = ; - close IPADDR; - chomp ($ipaddr); - $cgiparams{'ROOTCERT_HOSTNAME'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0]; - if ($cgiparams{'ROOTCERT_HOSTNAME'} eq '') { - $cgiparams{'ROOTCERT_HOSTNAME'} = $ipaddr; - } - } - $cgiparams{'ROOTCERT_COUNTRY'} = $vpnsettings{'ROOTCERT_COUNTRY'} if (!$cgiparams{'ROOTCERT_COUNTRY'}); - } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) { - &General::log("ipsec", "Importing from p12..."); - - if (ref ($cgiparams{'FH'}) ne 'Fh') { - $errormessage = $Lang::tr{'there was no file upload'}; - goto ROOTCERT_ERROR; - } - - # Move uploaded certificate request to a temporary file - (my $fh, my $filename) = tempfile( ); - if (copy ($cgiparams{'FH'}, $fh) != 1) { - $errormessage = $!; - goto ROOTCERT_ERROR; - } - - # Extract the CA certificate from the file - &General::log("ipsec", "Extracting caroot from p12..."); - if (open(STDIN, "-|")) { - my $opt = " pkcs12 -cacerts -nokeys"; - $opt .= " -in $filename"; - $opt .= " -out /tmp/newcacert"; - $errormessage = &callssl ($opt); - } else { #child - print "$cgiparams{'P12_PASS'}\n"; - exit (0); - } - - # Extract the Host certificate from the file - if (!$errormessage) { - &General::log("ipsec", "Extracting host cert from p12..."); - if (open(STDIN, "-|")) { - my $opt = " pkcs12 -clcerts -nokeys"; - $opt .= " -in $filename"; - $opt .= " -out /tmp/newhostcert"; - $errormessage = &callssl ($opt); - } else { #child - print "$cgiparams{'P12_PASS'}\n"; - exit (0); - } - } - - # Extract the Host key from the file - if (!$errormessage) { - &General::log("ipsec", "Extracting private key from p12..."); - if (open(STDIN, "-|")) { - my $opt = " pkcs12 -nocerts -nodes"; - $opt .= " -in $filename"; - $opt .= " -out /tmp/newhostkey"; - $errormessage = &callssl ($opt); - } else { #child - print "$cgiparams{'P12_PASS'}\n"; - exit (0); - } - } - - if (!$errormessage) { - &General::log("ipsec", "Moving cacert..."); - move("/tmp/newcacert", "${General::swroot}/ca/cacert.pem"); - $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); - } - - if (!$errormessage) { - &General::log("ipsec", "Moving host cert..."); - move("/tmp/newhostcert", "${General::swroot}/certs/hostcert.pem"); - $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); - } - - if (!$errormessage) { - &General::log("ipsec", "Moving private key..."); - move("/tmp/newhostkey", "${General::swroot}/certs/hostkey.pem"); - $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); - } - - #cleanup temp files - unlink ($filename); - unlink ('/tmp/newcacert'); - unlink ('/tmp/newhostcert'); - unlink ('/tmp/newhostkey'); - if ($errormessage) { - unlink ("${General::swroot}/ca/cacert.pem"); - unlink ("${General::swroot}/certs/hostcert.pem"); - unlink ("${General::swroot}/certs/hostkey.pem"); - goto ROOTCERT_ERROR; - } - - # Create empty CRL cannot be done because we don't have - # the private key for this CAROOT - # IPFire can only import certificates - - &General::log("ipsec", "p12 import completed!"); - &cleanssldatabase(); - goto ROOTCERT_SUCCESS; - - } elsif ($cgiparams{'ROOTCERT_COUNTRY'} ne '') { - - # Validate input since the form was submitted - if ($cgiparams{'ROOTCERT_ORGANIZATION'} eq ''){ - $errormessage = $Lang::tr{'organization cant be empty'}; - goto ROOTCERT_ERROR; - } - if (length($cgiparams{'ROOTCERT_ORGANIZATION'}) >60) { - $errormessage = $Lang::tr{'organization too long'}; - goto ROOTCERT_ERROR; - } - if ($cgiparams{'ROOTCERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { - $errormessage = $Lang::tr{'invalid input for organization'}; - goto ROOTCERT_ERROR; - } - if ($cgiparams{'ROOTCERT_HOSTNAME'} eq ''){ - $errormessage = $Lang::tr{'hostname cant be empty'}; - goto ROOTCERT_ERROR; - } - unless (&General::validfqdn($cgiparams{'ROOTCERT_HOSTNAME'}) || &General::validip($cgiparams{'ROOTCERT_HOSTNAME'})) { - $errormessage = $Lang::tr{'invalid input for hostname'}; - goto ROOTCERT_ERROR; - } - if ($cgiparams{'ROOTCERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'ROOTCERT_EMAIL'}))) { - $errormessage = $Lang::tr{'invalid input for e-mail address'}; - goto ROOTCERT_ERROR; - } - if (length($cgiparams{'ROOTCERT_EMAIL'}) > 40) { - $errormessage = $Lang::tr{'e-mail address too long'}; - goto ROOTCERT_ERROR; - } - if ($cgiparams{'ROOTCERT_OU'} ne '' && $cgiparams{'ROOTCERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { - $errormessage = $Lang::tr{'invalid input for department'}; - goto ROOTCERT_ERROR; - } - if ($cgiparams{'ROOTCERT_CITY'} ne '' && $cgiparams{'ROOTCERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { - $errormessage = $Lang::tr{'invalid input for city'}; - goto ROOTCERT_ERROR; - } - if ($cgiparams{'ROOTCERT_STATE'} ne '' && $cgiparams{'ROOTCERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { - $errormessage = $Lang::tr{'invalid input for state or province'}; - goto ROOTCERT_ERROR; - } - if ($cgiparams{'ROOTCERT_COUNTRY'} !~ /^[A-Z]*$/) { - $errormessage = $Lang::tr{'invalid input for country'}; - goto ROOTCERT_ERROR; - } - #the exact syntax is a list comma separated of - # email:any-validemail - # URI: a uniform resource indicator - # DNS: a DNS domain name - # RID: a registered OBJECT IDENTIFIER - # IP: an IP address - # example: email:franck@foo.com,IP:10.0.0.10,DNS:franck.foo.com - - if ($cgiparams{'SUBJECTALTNAME'} ne '' && $cgiparams{'SUBJECTALTNAME'} !~ /^(email|URI|DNS|RID|IP):[a-zA-Z0-9 :\/,\.\-_@]*$/) { - $errormessage = $Lang::tr{'vpn altname syntax'}; - goto VPNCONF_ERROR; - } - - # Copy the cgisettings to vpnsettings and save the configfile - $vpnsettings{'ROOTCERT_ORGANIZATION'} = $cgiparams{'ROOTCERT_ORGANIZATION'}; - $vpnsettings{'ROOTCERT_HOSTNAME'} = $cgiparams{'ROOTCERT_HOSTNAME'}; - $vpnsettings{'ROOTCERT_EMAIL'} = $cgiparams{'ROOTCERT_EMAIL'}; - $vpnsettings{'ROOTCERT_OU'} = $cgiparams{'ROOTCERT_OU'}; - $vpnsettings{'ROOTCERT_CITY'} = $cgiparams{'ROOTCERT_CITY'}; - $vpnsettings{'ROOTCERT_STATE'} = $cgiparams{'ROOTCERT_STATE'}; - $vpnsettings{'ROOTCERT_COUNTRY'} = $cgiparams{'ROOTCERT_COUNTRY'}; - &General::writehash("${General::swroot}/vpn/settings", \%vpnsettings); - - # Replace empty strings with a . - (my $ou = $cgiparams{'ROOTCERT_OU'}) =~ s/^\s*$/\./; - (my $city = $cgiparams{'ROOTCERT_CITY'}) =~ s/^\s*$/\./; - (my $state = $cgiparams{'ROOTCERT_STATE'}) =~ s/^\s*$/\./; - - # Create the CA certificate - if (!$errormessage) { - &General::log("ipsec", "Creating cacert..."); - if (open(STDIN, "-|")) { - my $opt = " req -x509 -sha256 -nodes"; - $opt .= " -days 999999"; - $opt .= " -newkey rsa:4096"; - $opt .= " -keyout ${General::swroot}/private/cakey.pem"; - $opt .= " -out ${General::swroot}/ca/cacert.pem"; - - $errormessage = &callssl ($opt); - } else { #child - print "$cgiparams{'ROOTCERT_COUNTRY'}\n"; - print "$state\n"; - print "$city\n"; - print "$cgiparams{'ROOTCERT_ORGANIZATION'}\n"; - print "$ou\n"; - print "$cgiparams{'ROOTCERT_ORGANIZATION'} CA\n"; - print "$cgiparams{'ROOTCERT_EMAIL'}\n"; - exit (0); - } - } - - # Create the Host certificate request - if (!$errormessage) { - &General::log("ipsec", "Creating host cert..."); - if (open(STDIN, "-|")) { - my $opt = " req -sha256 -nodes"; - $opt .= " -newkey rsa:2048"; - $opt .= " -keyout ${General::swroot}/certs/hostkey.pem"; - $opt .= " -out ${General::swroot}/certs/hostreq.pem"; - $errormessage = &callssl ($opt); - } else { #child - print "$cgiparams{'ROOTCERT_COUNTRY'}\n"; - print "$state\n"; - print "$city\n"; - print "$cgiparams{'ROOTCERT_ORGANIZATION'}\n"; - print "$ou\n"; - print "$cgiparams{'ROOTCERT_HOSTNAME'}\n"; - print "$cgiparams{'ROOTCERT_EMAIL'}\n"; - print ".\n"; - print ".\n"; - exit (0); - } - } - - # Sign the host certificate request - if (!$errormessage) { - &General::log("ipsec", "Self signing host cert..."); - - #No easy way for specifying the contain of subjectAltName without writing a config file... - my ($fh, $v3extname) = tempfile ('/tmp/XXXXXXXX'); - print $fh <$errormessage"; - print " "; - &Header::closebox(); - } - &Header::openbox('100%', 'left', "$Lang::tr{'generate root/host certificates'}:"); - print < - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
$Lang::tr{'organization name'}: *
$Lang::tr{'ipfires hostname'}: *
$Lang::tr{'your e-mail'}:
$Lang::tr{'your department'}:
$Lang::tr{'city'}:
$Lang::tr{'state or province'}:
$Lang::tr{'country'}:
$Lang::tr{'vpn subjectaltname'} (subjectAltName=email:*,URI:*,DNS:*,RID:*)
 


- $Lang::tr{'capswarning'}: - $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'} -

$Lang::tr{'upload p12 file'}:
$Lang::tr{'pkcs12 file password'}:
 
- * $Lang::tr{'required field'}
-END - ; - &Header::closebox(); - &Header::closebigbox(); - &Header::closepage(); - exit(0); - - ROOTCERT_SUCCESS: - if (&vpnenabled) { - system('/usr/local/bin/ipsecctrl', 'S'); - sleep $sleepDelay; - } - ROOTCERT_SKIP: -### -### Export PKCS12 file to browser -### -} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download pkcs12 file'}) { - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - print "Content-Type: application/force-download\n"; - print "Content-Disposition: attachment; filename=" . $confighash{$cgiparams{'KEY'}}[1] . ".p12\r\n"; - print "Content-Type: application/octet-stream\r\n\r\n"; - print `/bin/cat ${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1].p12`; - exit (0); - -### -### Display certificate -### -} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show certificate'}) { - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - - if ( -f "${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") { + my $output; &Header::showhttpheaders(); &Header::openpage($Lang::tr{'ipsec'}, 1, ''); &Header::openbigbox('100%', 'left', '', ''); - &Header::openbox('100%', 'left', "$Lang::tr{'cert'}:"); - my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`; + if ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'}) { + &Header::openbox('100%', 'left', "$Lang::tr{'root certificate'}:"); + $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ca/cacert.pem`; + } else { + &Header::openbox('100%', 'left', "$Lang::tr{'host certificate'}:"); + $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/certs/hostcert.pem`; + } $output = &Header::cleanhtml($output,"y"); print "
$output
\n"; &Header::closebox(); @@ -1144,79 +729,487 @@ END &Header::closebigbox(); &Header::closepage(); exit(0); - } + +### +### Export root certificate to browser +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download root certificate'}) { + if ( -f "${General::swroot}/ca/cacert.pem" ) { + print "Content-Type: application/force-download\n"; + print "Content-Disposition: attachment; filename=cacert.pem\r\n\r\n"; + print `/usr/bin/openssl x509 -in ${General::swroot}/ca/cacert.pem`; + exit(0); + } +### +### Export host certificate to browser +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download host certificate'}) { + if ( -f "${General::swroot}/certs/hostcert.pem" ) { + print "Content-Type: application/force-download\n"; + print "Content-Disposition: attachment; filename=hostcert.pem\r\n\r\n"; + print `/usr/bin/openssl x509 -in ${General::swroot}/certs/hostcert.pem`; + exit(0); + } +### +### Form for generating/importing the caroot+host certificate +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate root/host certificates'} || + $cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) { + + if (-f "${General::swroot}/ca/cacert.pem") { + $errormessage = $Lang::tr{'valid root certificate already exists'}; + goto ROOTCERT_SKIP; + } + + &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); + # fill in initial values + if ($cgiparams{'ROOTCERT_HOSTNAME'} eq '') { + if (-e "${General::swroot}/red/active" && open(IPADDR, "${General::swroot}/red/local-ipaddress")) { + my $ipaddr = ; + close IPADDR; + chomp ($ipaddr); + $cgiparams{'ROOTCERT_HOSTNAME'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0]; + if ($cgiparams{'ROOTCERT_HOSTNAME'} eq '') { + $cgiparams{'ROOTCERT_HOSTNAME'} = $ipaddr; + } + } + $cgiparams{'ROOTCERT_COUNTRY'} = $vpnsettings{'ROOTCERT_COUNTRY'} if (!$cgiparams{'ROOTCERT_COUNTRY'}); + } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) { + &General::log("ipsec", "Importing from p12..."); + + if (ref ($cgiparams{'FH'}) ne 'Fh') { + $errormessage = $Lang::tr{'there was no file upload'}; + goto ROOTCERT_ERROR; + } + + # Move uploaded certificate request to a temporary file + (my $fh, my $filename) = tempfile( ); + if (copy ($cgiparams{'FH'}, $fh) != 1) { + $errormessage = $!; + goto ROOTCERT_ERROR; + } + + # Extract the CA certificate from the file + &General::log("ipsec", "Extracting caroot from p12..."); + if (open(STDIN, "-|")) { + my $opt = " pkcs12 -cacerts -nokeys"; + $opt .= " -in $filename"; + $opt .= " -out /tmp/newcacert"; + $errormessage = &callssl ($opt); + } else { #child + print "$cgiparams{'P12_PASS'}\n"; + exit (0); + } + + # Extract the Host certificate from the file + if (!$errormessage) { + &General::log("ipsec", "Extracting host cert from p12..."); + if (open(STDIN, "-|")) { + my $opt = " pkcs12 -clcerts -nokeys"; + $opt .= " -in $filename"; + $opt .= " -out /tmp/newhostcert"; + $errormessage = &callssl ($opt); + } else { #child + print "$cgiparams{'P12_PASS'}\n"; + exit (0); + } + } + + # Extract the Host key from the file + if (!$errormessage) { + &General::log("ipsec", "Extracting private key from p12..."); + if (open(STDIN, "-|")) { + my $opt = " pkcs12 -nocerts -nodes"; + $opt .= " -in $filename"; + $opt .= " -out /tmp/newhostkey"; + $errormessage = &callssl ($opt); + } else { #child + print "$cgiparams{'P12_PASS'}\n"; + exit (0); + } + } + + if (!$errormessage) { + &General::log("ipsec", "Moving cacert..."); + move("/tmp/newcacert", "${General::swroot}/ca/cacert.pem"); + $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); + } + + if (!$errormessage) { + &General::log("ipsec", "Moving host cert..."); + move("/tmp/newhostcert", "${General::swroot}/certs/hostcert.pem"); + $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); + } + + if (!$errormessage) { + &General::log("ipsec", "Moving private key..."); + move("/tmp/newhostkey", "${General::swroot}/certs/hostkey.pem"); + $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); + } + + #cleanup temp files + unlink ($filename); + unlink ('/tmp/newcacert'); + unlink ('/tmp/newhostcert'); + unlink ('/tmp/newhostkey'); + if ($errormessage) { + unlink ("${General::swroot}/ca/cacert.pem"); + unlink ("${General::swroot}/certs/hostcert.pem"); + unlink ("${General::swroot}/certs/hostkey.pem"); + goto ROOTCERT_ERROR; + } + + # Create empty CRL cannot be done because we don't have + # the private key for this CAROOT + # IPFire can only import certificates + + &General::log("ipsec", "p12 import completed!"); + &cleanssldatabase(); + goto ROOTCERT_SUCCESS; + + } elsif ($cgiparams{'ROOTCERT_COUNTRY'} ne '') { + + # Validate input since the form was submitted + if ($cgiparams{'ROOTCERT_ORGANIZATION'} eq ''){ + $errormessage = $Lang::tr{'organization cant be empty'}; + goto ROOTCERT_ERROR; + } + if (length($cgiparams{'ROOTCERT_ORGANIZATION'}) >60) { + $errormessage = $Lang::tr{'organization too long'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for organization'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_HOSTNAME'} eq ''){ + $errormessage = $Lang::tr{'hostname cant be empty'}; + goto ROOTCERT_ERROR; + } + unless (&General::validfqdn($cgiparams{'ROOTCERT_HOSTNAME'}) || &General::validip($cgiparams{'ROOTCERT_HOSTNAME'})) { + $errormessage = $Lang::tr{'invalid input for hostname'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'ROOTCERT_EMAIL'}))) { + $errormessage = $Lang::tr{'invalid input for e-mail address'}; + goto ROOTCERT_ERROR; + } + if (length($cgiparams{'ROOTCERT_EMAIL'}) > 40) { + $errormessage = $Lang::tr{'e-mail address too long'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_OU'} ne '' && $cgiparams{'ROOTCERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for department'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_CITY'} ne '' && $cgiparams{'ROOTCERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for city'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_STATE'} ne '' && $cgiparams{'ROOTCERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for state or province'}; + goto ROOTCERT_ERROR; + } + if ($cgiparams{'ROOTCERT_COUNTRY'} !~ /^[A-Z]*$/) { + $errormessage = $Lang::tr{'invalid input for country'}; + goto ROOTCERT_ERROR; + } + #the exact syntax is a list comma separated of + # email:any-validemail + # URI: a uniform resource indicator + # DNS: a DNS domain name + # RID: a registered OBJECT IDENTIFIER + # IP: an IP address + # example: email:franck@foo.com,IP:10.0.0.10,DNS:franck.foo.com + + if ($cgiparams{'SUBJECTALTNAME'} ne '' && $cgiparams{'SUBJECTALTNAME'} !~ /^(email|URI|DNS|RID|IP):[a-zA-Z0-9 :\/,\.\-_@]*$/) { + $errormessage = $Lang::tr{'vpn altname syntax'}; + goto VPNCONF_ERROR; + } + + # Copy the cgisettings to vpnsettings and save the configfile + $vpnsettings{'ROOTCERT_ORGANIZATION'} = $cgiparams{'ROOTCERT_ORGANIZATION'}; + $vpnsettings{'ROOTCERT_HOSTNAME'} = $cgiparams{'ROOTCERT_HOSTNAME'}; + $vpnsettings{'ROOTCERT_EMAIL'} = $cgiparams{'ROOTCERT_EMAIL'}; + $vpnsettings{'ROOTCERT_OU'} = $cgiparams{'ROOTCERT_OU'}; + $vpnsettings{'ROOTCERT_CITY'} = $cgiparams{'ROOTCERT_CITY'}; + $vpnsettings{'ROOTCERT_STATE'} = $cgiparams{'ROOTCERT_STATE'}; + $vpnsettings{'ROOTCERT_COUNTRY'} = $cgiparams{'ROOTCERT_COUNTRY'}; + &General::writehash("${General::swroot}/vpn/settings", \%vpnsettings); + + # Replace empty strings with a . + (my $ou = $cgiparams{'ROOTCERT_OU'}) =~ s/^\s*$/\./; + (my $city = $cgiparams{'ROOTCERT_CITY'}) =~ s/^\s*$/\./; + (my $state = $cgiparams{'ROOTCERT_STATE'}) =~ s/^\s*$/\./; + + # Create the CA certificate + if (!$errormessage) { + &General::log("ipsec", "Creating cacert..."); + if (open(STDIN, "-|")) { + my $opt = " req -x509 -sha256 -nodes"; + $opt .= " -days 999999"; + $opt .= " -newkey rsa:4096"; + $opt .= " -keyout ${General::swroot}/private/cakey.pem"; + $opt .= " -out ${General::swroot}/ca/cacert.pem"; + + $errormessage = &callssl ($opt); + } else { #child + print "$cgiparams{'ROOTCERT_COUNTRY'}\n"; + print "$state\n"; + print "$city\n"; + print "$cgiparams{'ROOTCERT_ORGANIZATION'}\n"; + print "$ou\n"; + print "$cgiparams{'ROOTCERT_ORGANIZATION'} CA\n"; + print "$cgiparams{'ROOTCERT_EMAIL'}\n"; + exit (0); + } + } + + # Create the Host certificate request + if (!$errormessage) { + &General::log("ipsec", "Creating host cert..."); + if (open(STDIN, "-|")) { + my $opt = " req -sha256 -nodes"; + $opt .= " -newkey rsa:2048"; + $opt .= " -keyout ${General::swroot}/certs/hostkey.pem"; + $opt .= " -out ${General::swroot}/certs/hostreq.pem"; + $errormessage = &callssl ($opt); + } else { #child + print "$cgiparams{'ROOTCERT_COUNTRY'}\n"; + print "$state\n"; + print "$city\n"; + print "$cgiparams{'ROOTCERT_ORGANIZATION'}\n"; + print "$ou\n"; + print "$cgiparams{'ROOTCERT_HOSTNAME'}\n"; + print "$cgiparams{'ROOTCERT_EMAIL'}\n"; + print ".\n"; + print ".\n"; + exit (0); + } + } + + # Sign the host certificate request + if (!$errormessage) { + &General::log("ipsec", "Self signing host cert..."); + + #No easy way for specifying the contain of subjectAltName without writing a config file... + my ($fh, $v3extname) = tempfile ('/tmp/XXXXXXXX'); + print $fh <$errormessage"; + print " "; + &Header::closebox(); + } + &Header::openbox('100%', 'left', "$Lang::tr{'generate root/host certificates'}:"); + print < + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$Lang::tr{'organization name'}: *
$Lang::tr{'ipfires hostname'}: *
$Lang::tr{'your e-mail'}:
$Lang::tr{'your department'}:
$Lang::tr{'city'}:
$Lang::tr{'state or province'}:
$Lang::tr{'country'}:
$Lang::tr{'vpn subjectaltname'} (subjectAltName=email:*,URI:*,DNS:*,RID:*)
 


+ $Lang::tr{'capswarning'}: + $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'} +

$Lang::tr{'upload p12 file'}:
$Lang::tr{'pkcs12 file password'}:
 
+ * $Lang::tr{'required field'}
+END +; + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit(0); + + ROOTCERT_SUCCESS: + if (&vpnenabled) { + system('/usr/local/bin/ipsecctrl', 'S'); + sleep $sleepDelay; + } + ROOTCERT_SKIP: +### +### Export PKCS12 file to browser +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download pkcs12 file'}) { + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + print "Content-Type: application/force-download\n"; + print "Content-Disposition: attachment; filename=" . $confighash{$cgiparams{'KEY'}}[1] . ".p12\r\n"; + print "Content-Type: application/octet-stream\r\n\r\n"; + print `/bin/cat ${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1].p12`; + exit (0); + +### +### Display certificate +### +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show certificate'}) { + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + + if ( -f "${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") { + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'ipsec'}, 1, ''); + &Header::openbigbox('100%', 'left', '', ''); + &Header::openbox('100%', 'left', "$Lang::tr{'cert'}:"); + my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`; + $output = &Header::cleanhtml($output,"y"); + print "
$output
\n"; + &Header::closebox(); + print ""; + &Header::closebigbox(); + &Header::closepage(); + exit(0); + } ### ### Export Certificate to browser ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download certificate'}) { - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - if ( -f "${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") { - print "Content-Type: application/force-download\n"; - print "Content-Disposition: attachment; filename=" . $confighash{$cgiparams{'KEY'}}[1] . "cert.pem\n\n"; - print `/bin/cat ${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`; - exit (0); - } + if ( -f "${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") { + print "Content-Type: application/force-download\n"; + print "Content-Disposition: attachment; filename=" . $confighash{$cgiparams{'KEY'}}[1] . "cert.pem\n\n"; + print `/bin/cat ${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`; + exit (0); + } ### ### Enable/Disable connection ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'toggle enable disable'}) { - - &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - if ($confighash{$cgiparams{'KEY'}}) { - if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') { - $confighash{$cgiparams{'KEY'}}[0] = 'on'; - &General::writehasharray("${General::swroot}/vpn/config", \%confighash); - &writeipsecfiles(); - system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}) if (&vpnenabled); + &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + + if ($confighash{$cgiparams{'KEY'}}) { + if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') { + $confighash{$cgiparams{'KEY'}}[0] = 'on'; + &General::writehasharray("${General::swroot}/vpn/config", \%confighash); + &writeipsecfiles(); + system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}) if (&vpnenabled); + } else { + system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'}) if (&vpnenabled); + $confighash{$cgiparams{'KEY'}}[0] = 'off'; + &General::writehasharray("${General::swroot}/vpn/config", \%confighash); + &writeipsecfiles(); + } + sleep $sleepDelay; } else { - system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'}) if (&vpnenabled); - $confighash{$cgiparams{'KEY'}}[0] = 'off'; - &General::writehasharray("${General::swroot}/vpn/config", \%confighash); - &writeipsecfiles(); + $errormessage = $Lang::tr{'invalid key'}; } - sleep $sleepDelay; - } else { - $errormessage = $Lang::tr{'invalid key'}; - } ### ### Restart connection ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'restart'}) { - &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - if ($confighash{$cgiparams{'KEY'}}) { - if (&vpnenabled) { - system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}); - sleep $sleepDelay; + if ($confighash{$cgiparams{'KEY'}}) { + if (&vpnenabled) { + system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}); + sleep $sleepDelay; + } + } else { + $errormessage = $Lang::tr{'invalid key'}; } - } else { - $errormessage = $Lang::tr{'invalid key'}; - } ### ### Remove connection ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove'}) { - &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - if ($confighash{$cgiparams{'KEY'}}) { - system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'}) if (&vpnenabled); - unlink ("${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem"); - unlink ("${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1].p12"); - delete $confighash{$cgiparams{'KEY'}}; - &General::writehasharray("${General::swroot}/vpn/config", \%confighash); - &writeipsecfiles(); - } else { - $errormessage = $Lang::tr{'invalid key'}; - } + if ($confighash{$cgiparams{'KEY'}}) { + system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'}) if (&vpnenabled); + unlink ("${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem"); + unlink ("${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1].p12"); + delete $confighash{$cgiparams{'KEY'}}; + &General::writehasharray("${General::swroot}/vpn/config", \%confighash); + &writeipsecfiles(); + } else { + $errormessage = $Lang::tr{'invalid key'}; + } &General::firewall_reload(); ### ### Choose between adding a host-net or net-net connection @@ -1227,535 +1220,545 @@ END &Header::openbigbox('100%', 'left', '', ''); &Header::openbox('100%', 'left', $Lang::tr{'connection type'}); print < - $Lang::tr{'connection type'}:
- - + + $Lang::tr{'connection type'}:
+
+ - + - + - -
$Lang::tr{'host to net vpn'}
$Lang::tr{'net to net vpn'}
+ + END - ; +; &Header::closebox(); &Header::closebigbox(); &Header::closepage(); exit (0); ### -### Adding/Editing/Saving a connection +### Adding/Editing/Saving a connection ### } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) || - ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) || - ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq '')) { + ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) || + ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq '')) { - &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); - &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) { - if (! $confighash{$cgiparams{'KEY'}}[0]) { - $errormessage = $Lang::tr{'invalid key'}; - goto VPNCONF_END; - } - $cgiparams{'ENABLED'} = $confighash{$cgiparams{'KEY'}}[0]; - $cgiparams{'NAME'} = $confighash{$cgiparams{'KEY'}}[1]; - $cgiparams{'TYPE'} = $confighash{$cgiparams{'KEY'}}[3]; - $cgiparams{'AUTH'} = $confighash{$cgiparams{'KEY'}}[4]; - $cgiparams{'PSK'} = $confighash{$cgiparams{'KEY'}}[5]; - #$cgiparams{'free'} = $confighash{$cgiparams{'KEY'}}[6]; - $cgiparams{'LOCAL_ID'} = $confighash{$cgiparams{'KEY'}}[7]; - $cgiparams{'LOCAL_SUBNET'} = $confighash{$cgiparams{'KEY'}}[8]; - $cgiparams{'REMOTE_ID'} = $confighash{$cgiparams{'KEY'}}[9]; - $cgiparams{'REMOTE'} = $confighash{$cgiparams{'KEY'}}[10]; - $cgiparams{'REMOTE_SUBNET'} = $confighash{$cgiparams{'KEY'}}[11]; - $cgiparams{'REMARK'} = $confighash{$cgiparams{'KEY'}}[25]; - $cgiparams{'DPD_ACTION'} = $confighash{$cgiparams{'KEY'}}[27]; - $cgiparams{'IKE_VERSION'} = $confighash{$cgiparams{'KEY'}}[29]; - $cgiparams{'IKE_ENCRYPTION'} = $confighash{$cgiparams{'KEY'}}[18]; - $cgiparams{'IKE_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[19]; - $cgiparams{'IKE_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[20]; - $cgiparams{'IKE_LIFETIME'} = $confighash{$cgiparams{'KEY'}}[16]; - $cgiparams{'ESP_ENCRYPTION'} = $confighash{$cgiparams{'KEY'}}[21]; - $cgiparams{'ESP_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[22]; - $cgiparams{'ESP_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[23]; - if ($cgiparams{'ESP_GROUPTYPE'} eq "") { - $cgiparams{'ESP_GROUPTYPE'} = $cgiparams{'IKE_GROUPTYPE'}; - } - $cgiparams{'ESP_KEYLIFE'} = $confighash{$cgiparams{'KEY'}}[17]; - $cgiparams{'COMPRESSION'} = $confighash{$cgiparams{'KEY'}}[13]; - $cgiparams{'ONLY_PROPOSED'} = $confighash{$cgiparams{'KEY'}}[24]; - $cgiparams{'PFS'} = $confighash{$cgiparams{'KEY'}}[28]; - $cgiparams{'VHOST'} = $confighash{$cgiparams{'KEY'}}[14]; - $cgiparams{'DPD_TIMEOUT'} = $confighash{$cgiparams{'KEY'}}[30]; - $cgiparams{'DPD_DELAY'} = $confighash{$cgiparams{'KEY'}}[31]; - $cgiparams{'FORCE_MOBIKE'} = $confighash{$cgiparams{'KEY'}}[32]; - - if (!$cgiparams{'DPD_DELAY'}) { - $cgiparams{'DPD_DELAY'} = 30; - } - - if (!$cgiparams{'DPD_TIMEOUT'}) { - $cgiparams{'DPD_TIMEOUT'} = 120; - } - - } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { - $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'}); - if ($cgiparams{'TYPE'} !~ /^(host|net)$/) { - $errormessage = $Lang::tr{'connection type is invalid'}; - goto VPNCONF_ERROR; - } - - if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) { - $errormessage = $Lang::tr{'name must only contain characters'}; - goto VPNCONF_ERROR; - } - - if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) { - $errormessage = $Lang::tr{'name is invalid'}; - goto VPNCONF_ERROR; - } - - if (length($cgiparams{'NAME'}) >60) { - $errormessage = $Lang::tr{'name too long'}; - goto VPNCONF_ERROR; - } - - # Check if there is no other entry with this name - if (! $cgiparams{'KEY'}) { #only for add - 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; + if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) { + if (! $confighash{$cgiparams{'KEY'}}[0]) { + $errormessage = $Lang::tr{'invalid key'}; + goto VPNCONF_END; } - } - } - - if (($cgiparams{'TYPE'} eq 'net') && (! $cgiparams{'REMOTE'})) { - $errormessage = $Lang::tr{'invalid input for remote host/ip'}; - goto VPNCONF_ERROR; - } - - if ($cgiparams{'REMOTE'}) { - if (($cgiparams{'REMOTE'} ne '%any') && (! &General::validip($cgiparams{'REMOTE'}))) { - if (! &General::validfqdn ($cgiparams{'REMOTE'})) { - $errormessage = $Lang::tr{'invalid input for remote host/ip'}; - goto VPNCONF_ERROR; - } else { - if (&valid_dns_host($cgiparams{'REMOTE'})) { - $warnmessage = "$Lang::tr{'check vpn lr'} $cgiparams{'REMOTE'}. $Lang::tr{'dns check failed'}"; - } + $cgiparams{'ENABLED'} = $confighash{$cgiparams{'KEY'}}[0]; + $cgiparams{'NAME'} = $confighash{$cgiparams{'KEY'}}[1]; + $cgiparams{'TYPE'} = $confighash{$cgiparams{'KEY'}}[3]; + $cgiparams{'AUTH'} = $confighash{$cgiparams{'KEY'}}[4]; + $cgiparams{'PSK'} = $confighash{$cgiparams{'KEY'}}[5]; + #$cgiparams{'free'} = $confighash{$cgiparams{'KEY'}}[6]; + $cgiparams{'LOCAL_ID'} = $confighash{$cgiparams{'KEY'}}[7]; + my @local_subnets = split(",", $confighash{$cgiparams{'KEY'}}[8]); + $cgiparams{'LOCAL_SUBNET'} = join(/\|/, @local_subnets); + $cgiparams{'REMOTE_ID'} = $confighash{$cgiparams{'KEY'}}[9]; + $cgiparams{'REMOTE'} = $confighash{$cgiparams{'KEY'}}[10]; + my @remote_subnets = split(",", $confighash{$cgiparams{'KEY'}}[11]); + $cgiparams{'REMOTE_SUBNET'} = join(/\|/, @remote_subnets); + $cgiparams{'REMARK'} = $confighash{$cgiparams{'KEY'}}[25]; + $cgiparams{'DPD_ACTION'} = $confighash{$cgiparams{'KEY'}}[27]; + $cgiparams{'IKE_VERSION'} = $confighash{$cgiparams{'KEY'}}[29]; + $cgiparams{'IKE_ENCRYPTION'} = $confighash{$cgiparams{'KEY'}}[18]; + $cgiparams{'IKE_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[19]; + $cgiparams{'IKE_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[20]; + $cgiparams{'IKE_LIFETIME'} = $confighash{$cgiparams{'KEY'}}[16]; + $cgiparams{'ESP_ENCRYPTION'} = $confighash{$cgiparams{'KEY'}}[21]; + $cgiparams{'ESP_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[22]; + $cgiparams{'ESP_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[23]; + if ($cgiparams{'ESP_GROUPTYPE'} eq "") { + $cgiparams{'ESP_GROUPTYPE'} = $cgiparams{'IKE_GROUPTYPE'}; } - } - } + $cgiparams{'ESP_KEYLIFE'} = $confighash{$cgiparams{'KEY'}}[17]; + $cgiparams{'COMPRESSION'} = $confighash{$cgiparams{'KEY'}}[13]; + $cgiparams{'ONLY_PROPOSED'} = $confighash{$cgiparams{'KEY'}}[24]; + $cgiparams{'PFS'} = $confighash{$cgiparams{'KEY'}}[28]; + $cgiparams{'DPD_TIMEOUT'} = $confighash{$cgiparams{'KEY'}}[30]; + $cgiparams{'DPD_DELAY'} = $confighash{$cgiparams{'KEY'}}[31]; + $cgiparams{'FORCE_MOBIKE'} = $confighash{$cgiparams{'KEY'}}[32]; - unless (&General::validipandmask($cgiparams{'LOCAL_SUBNET'})) { - $errormessage = $Lang::tr{'local subnet is invalid'}; - goto VPNCONF_ERROR; - } + if (!$cgiparams{'DPD_DELAY'}) { + $cgiparams{'DPD_DELAY'} = 30; + } - # Allow only one roadwarrior/psk without remote IP-address - if ($cgiparams{'REMOTE'} eq '' && $cgiparams{'AUTH'} eq 'psk') { - foreach my $key (keys %confighash) { - if ( ($cgiparams{'KEY'} ne $key) && - ($confighash{$key}[4] eq 'psk') && - ($confighash{$key}[10] eq '') ) { - $errormessage = $Lang::tr{'you can only define one roadwarrior connection when using pre-shared key authentication'}; + if (!$cgiparams{'DPD_TIMEOUT'}) { + $cgiparams{'DPD_TIMEOUT'} = 120; + } + + } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { + $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'}); + if ($cgiparams{'TYPE'} !~ /^(host|net)$/) { + $errormessage = $Lang::tr{'connection type is invalid'}; goto VPNCONF_ERROR; } - } - } - if (($cgiparams{'TYPE'} eq 'net') && (! &General::validipandmask($cgiparams{'REMOTE_SUBNET'}))) { - $errormessage = $Lang::tr{'remote subnet is invalid'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'EDIT_ADVANCED'} !~ /^(on|off)$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto VPNCONF_ERROR; - } - - # Allow nothing or a string (DN,FDQN,) beginning with @ - # with no comma but slashes between RID eg @O=FR/C=Paris/OU=myhome/CN=franck - if ( ($cgiparams{'LOCAL_ID'} !~ /^(|[\w.-]*@[\w. =*\/-]+|\d+\.\d+\.\d+\.\d+)$/) || - ($cgiparams{'REMOTE_ID'} !~ /^(|[\w.-]*@[\w. =*\/-]+|\d+\.\d+\.\d+\.\d+)$/) || - (($cgiparams{'REMOTE_ID'} eq $cgiparams{'LOCAL_ID'}) && ($cgiparams{'LOCAL_ID'} ne '')) - ) { - $errormessage = $Lang::tr{'invalid local-remote id'} . '
' . - 'DER_ASN1_DN: @c=FR/ou=Paris/ou=Home/cn=*
' . - 'FQDN: @ipfire.org
' . - 'USER_FQDN: info@ipfire.org
' . - 'IPV4_ADDR: 123.123.123.123'; - goto VPNCONF_ERROR; - } - # If Auth is DN, verify existance of Remote ID. - if ( $cgiparams{'REMOTE_ID'} eq '' && ( - $cgiparams{'AUTH'} eq 'auth-dn'|| # while creation - $confighash{$cgiparams{'KEY'}}[2] eq '%auth-dn')){ # while editing - $errormessage = $Lang::tr{'vpn missing remote id'}; - goto VPNCONF_ERROR; - } - - if ($cgiparams{'TYPE'} eq 'net'){ - $warnmessage=&General::checksubnets('',$cgiparams{'REMOTE_SUBNET'},'ipsec'); - if ($warnmessage ne ''){ - $warnmessage=$Lang::tr{'remote subnet'}." ($cgiparams{'REMOTE_SUBNET'})
".$warnmessage; + if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) { + $errormessage = $Lang::tr{'name must only contain characters'}; + goto VPNCONF_ERROR; } - } - if ($cgiparams{'AUTH'} eq 'psk') { - if (! length($cgiparams{'PSK'}) ) { - $errormessage = $Lang::tr{'pre-shared key is too short'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'PSK'} =~ /'/) { - $cgiparams{'PSK'} =~ tr/'/ /; - $errormessage = $Lang::tr{'invalid characters found in pre-shared key'}; - goto VPNCONF_ERROR; - } + if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) { + $errormessage = $Lang::tr{'name is invalid'}; + goto VPNCONF_ERROR; + } + + if (length($cgiparams{'NAME'}) >60) { + $errormessage = $Lang::tr{'name too long'}; + goto VPNCONF_ERROR; + } + + # Check if there is no other entry with this name + if (! $cgiparams{'KEY'}) { #only for add + 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; + } + } + } + + if (($cgiparams{'TYPE'} eq 'net') && (! $cgiparams{'REMOTE'})) { + $errormessage = $Lang::tr{'invalid input for remote host/ip'}; + goto VPNCONF_ERROR; + } + + if ($cgiparams{'REMOTE'}) { + if (($cgiparams{'REMOTE'} ne '%any') && (! &General::validip($cgiparams{'REMOTE'}))) { + if (! &General::validfqdn ($cgiparams{'REMOTE'})) { + $errormessage = $Lang::tr{'invalid input for remote host/ip'}; + goto VPNCONF_ERROR; + } else { + if (&valid_dns_host($cgiparams{'REMOTE'})) { + $warnmessage = "$Lang::tr{'check vpn lr'} $cgiparams{'REMOTE'}. $Lang::tr{'dns check failed'}"; + } + } + } + } + + my @local_subnets = split(",", $cgiparams{'LOCAL_SUBNET'}); + foreach my $subnet (@local_subnets) { + unless (&Network::check_subnet($subnet)) { + $errormessage = $Lang::tr{'local subnet is invalid'}; + goto VPNCONF_ERROR; + } + } + + # Allow only one roadwarrior/psk without remote IP-address + if ($cgiparams{'REMOTE'} eq '' && $cgiparams{'AUTH'} eq 'psk') { + foreach my $key (keys %confighash) { + if ( ($cgiparams{'KEY'} ne $key) && + ($confighash{$key}[4] eq 'psk') && + ($confighash{$key}[10] eq '') ) { + $errormessage = $Lang::tr{'you can only define one roadwarrior connection when using pre-shared key authentication'}; + goto VPNCONF_ERROR; + } + } + } + + if ($cgiparams{'TYPE'} eq 'net') { + my @remote_subnets = split(",", $cgiparams{'REMOTE_SUBNET'}); + foreach my $subnet (@remote_subnets) { + unless (&Network::check_subnet($subnet)) { + $errormessage = $Lang::tr{'remote subnet is invalid'}; + goto VPNCONF_ERROR; + } + } + } + + if ($cgiparams{'ENABLED'} !~ /^(on|off)$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'EDIT_ADVANCED'} !~ /^(on|off)$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto VPNCONF_ERROR; + } + + # Allow nothing or a string (DN,FDQN,) beginning with @ + # with no comma but slashes between RID eg @O=FR/C=Paris/OU=myhome/CN=franck + if ( ($cgiparams{'LOCAL_ID'} !~ /^(|[\w.-]*@[\w. =*\/-]+|\d+\.\d+\.\d+\.\d+)$/) || + ($cgiparams{'REMOTE_ID'} !~ /^(|[\w.-]*@[\w. =*\/-]+|\d+\.\d+\.\d+\.\d+)$/) || + (($cgiparams{'REMOTE_ID'} eq $cgiparams{'LOCAL_ID'}) && ($cgiparams{'LOCAL_ID'} ne '')) + ) { + $errormessage = $Lang::tr{'invalid local-remote id'} . '
' . + 'DER_ASN1_DN: @c=FR/ou=Paris/ou=Home/cn=*
' . + 'FQDN: @ipfire.org
' . + 'USER_FQDN: info@ipfire.org
' . + 'IPV4_ADDR: 123.123.123.123'; + goto VPNCONF_ERROR; + } + # If Auth is DN, verify existance of Remote ID. + if ( $cgiparams{'REMOTE_ID'} eq '' && ( + $cgiparams{'AUTH'} eq 'auth-dn'|| # while creation + $confighash{$cgiparams{'KEY'}}[2] eq '%auth-dn')){ # while editing + $errormessage = $Lang::tr{'vpn missing remote id'}; + goto VPNCONF_ERROR; + } + + if ($cgiparams{'TYPE'} eq 'net'){ + $warnmessage=&General::checksubnets('',$cgiparams{'REMOTE_SUBNET'},'ipsec'); + if ($warnmessage ne ''){ + $warnmessage=$Lang::tr{'remote subnet'}." ($cgiparams{'REMOTE_SUBNET'})
".$warnmessage; + } + } + + if ($cgiparams{'AUTH'} eq 'psk') { + if (! length($cgiparams{'PSK'}) ) { + $errormessage = $Lang::tr{'pre-shared key is too short'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'PSK'} =~ /'/) { + $cgiparams{'PSK'} =~ tr/'/ /; + $errormessage = $Lang::tr{'invalid characters found in pre-shared key'}; + goto VPNCONF_ERROR; + } } elsif ($cgiparams{'AUTH'} eq 'certreq') { - if ($cgiparams{'KEY'}) { - $errormessage = $Lang::tr{'cant change certificates'}; - goto VPNCONF_ERROR; - } - if (ref ($cgiparams{'FH'}) ne 'Fh') { - $errormessage = $Lang::tr{'there was no file upload'}; - goto VPNCONF_ERROR; - } - - # Move uploaded certificate request to a temporary file - (my $fh, my $filename) = tempfile( ); - if (copy ($cgiparams{'FH'}, $fh) != 1) { - $errormessage = $!; - goto VPNCONF_ERROR; - } - - # Sign the certificate request - &General::log("ipsec", "Signing your cert $cgiparams{'NAME'}..."); - my $opt = " ca -md sha256 -days 999999"; - $opt .= " -batch -notext"; - $opt .= " -in $filename"; - $opt .= " -out ${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"; - - if ( $errormessage = &callssl ($opt) ) { - unlink ($filename); - unlink ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); - &cleanssldatabase(); - goto VPNCONF_ERROR; - } else { - unlink ($filename); - &cleanssldatabase(); - } - - $cgiparams{'CERT_NAME'} = getCNfromcert ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); - if ($cgiparams{'CERT_NAME'} eq '') { - $errormessage = $Lang::tr{'could not retrieve common name from certificate'}; - goto VPNCONF_ERROR; - } - } elsif ($cgiparams{'AUTH'} eq 'pkcs12') { - &General::log("ipsec", "Importing from p12..."); - + if ($cgiparams{'KEY'}) { + $errormessage = $Lang::tr{'cant change certificates'}; + goto VPNCONF_ERROR; + } if (ref ($cgiparams{'FH'}) ne 'Fh') { - $errormessage = $Lang::tr{'there was no file upload'}; - goto ROOTCERT_ERROR; + $errormessage = $Lang::tr{'there was no file upload'}; + goto VPNCONF_ERROR; } # Move uploaded certificate request to a temporary file (my $fh, my $filename) = tempfile( ); if (copy ($cgiparams{'FH'}, $fh) != 1) { - $errormessage = $!; - goto ROOTCERT_ERROR; + $errormessage = $!; + goto VPNCONF_ERROR; + } + + # Sign the certificate request + &General::log("ipsec", "Signing your cert $cgiparams{'NAME'}..."); + my $opt = " ca -md sha256 -days 999999"; + $opt .= " -batch -notext"; + $opt .= " -in $filename"; + $opt .= " -out ${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"; + + if ( $errormessage = &callssl ($opt) ) { + unlink ($filename); + unlink ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); + &cleanssldatabase(); + goto VPNCONF_ERROR; + } else { + unlink ($filename); + &cleanssldatabase(); + } + + $cgiparams{'CERT_NAME'} = getCNfromcert ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); + if ($cgiparams{'CERT_NAME'} eq '') { + $errormessage = $Lang::tr{'could not retrieve common name from certificate'}; + goto VPNCONF_ERROR; + } + } elsif ($cgiparams{'AUTH'} eq 'pkcs12') { + &General::log("ipsec", "Importing from p12..."); + + if (ref ($cgiparams{'FH'}) ne 'Fh') { + $errormessage = $Lang::tr{'there was no file upload'}; + goto ROOTCERT_ERROR; + } + + # Move uploaded certificate request to a temporary file + (my $fh, my $filename) = tempfile( ); + if (copy ($cgiparams{'FH'}, $fh) != 1) { + $errormessage = $!; + goto ROOTCERT_ERROR; } # Extract the CA certificate from the file &General::log("ipsec", "Extracting caroot from p12..."); if (open(STDIN, "-|")) { - my $opt = " pkcs12 -cacerts -nokeys"; + my $opt = " pkcs12 -cacerts -nokeys"; $opt .= " -in $filename"; $opt .= " -out /tmp/newcacert"; - $errormessage = &callssl ($opt); - } else { #child - print "$cgiparams{'P12_PASS'}\n"; - exit (0); - } - - # Extract the Host certificate from the file - if (!$errormessage) { - &General::log("ipsec", "Extracting host cert from p12..."); - if (open(STDIN, "-|")) { - my $opt = " pkcs12 -clcerts -nokeys"; - $opt .= " -in $filename"; - $opt .= " -out /tmp/newhostcert"; $errormessage = &callssl ($opt); - } else { #child + } else { #child print "$cgiparams{'P12_PASS'}\n"; exit (0); - } } - if (!$errormessage) { - &General::log("ipsec", "Moving cacert..."); - #If CA have new subject, add it to our list of CA - my $casubject = &Header::cleanhtml(getsubjectfromcert ('/tmp/newcacert')); - my @names; - foreach my $x (keys %cahash) { - $casubject='' if ($cahash{$x}[1] eq $casubject); - unshift (@names,$cahash{$x}[0]); - } - if ($casubject) { # a new one! - my $temp = `/usr/bin/openssl x509 -text -in /tmp/newcacert`; - if ($temp !~ /CA:TRUE/i) { - $errormessage = $Lang::tr{'not a valid ca certificate'}; - } else { - #compute a name for it - my $idx=0; - while (grep(/Imported-$idx/, @names) ) {$idx++}; - $cgiparams{'CA_NAME'}="Imported-$idx"; - $cgiparams{'CERT_NAME'}=&Header::cleanhtml(getCNfromcert ('/tmp/newhostcert')); - move("/tmp/newcacert", "${General::swroot}/ca/$cgiparams{'CA_NAME'}cert.pem"); - $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); - if (!$errormessage) { - my $key = &General::findhasharraykey (\%cahash); - $cahash{$key}[0] = $cgiparams{'CA_NAME'}; - $cahash{$key}[1] = $casubject; - &General::writehasharray("${General::swroot}/vpn/caconfig", \%cahash); - system('/usr/local/bin/ipsecctrl', 'R'); - } - } - } + # Extract the Host certificate from the file + if (!$errormessage) { + &General::log("ipsec", "Extracting host cert from p12..."); + if (open(STDIN, "-|")) { + my $opt = " pkcs12 -clcerts -nokeys"; + $opt .= " -in $filename"; + $opt .= " -out /tmp/newhostcert"; + $errormessage = &callssl ($opt); + } else { #child + print "$cgiparams{'P12_PASS'}\n"; + exit (0); + } + } + + if (!$errormessage) { + &General::log("ipsec", "Moving cacert..."); + #If CA have new subject, add it to our list of CA + my $casubject = &Header::cleanhtml(getsubjectfromcert ('/tmp/newcacert')); + my @names; + foreach my $x (keys %cahash) { + $casubject='' if ($cahash{$x}[1] eq $casubject); + unshift (@names,$cahash{$x}[0]); + } + if ($casubject) { # a new one! + my $temp = `/usr/bin/openssl x509 -text -in /tmp/newcacert`; + if ($temp !~ /CA:TRUE/i) { + $errormessage = $Lang::tr{'not a valid ca certificate'}; + } else { + #compute a name for it + my $idx=0; + while (grep(/Imported-$idx/, @names) ) {$idx++}; + $cgiparams{'CA_NAME'}="Imported-$idx"; + $cgiparams{'CERT_NAME'}=&Header::cleanhtml(getCNfromcert ('/tmp/newhostcert')); + move("/tmp/newcacert", "${General::swroot}/ca/$cgiparams{'CA_NAME'}cert.pem"); + $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); + if (!$errormessage) { + my $key = &General::findhasharraykey (\%cahash); + $cahash{$key}[0] = $cgiparams{'CA_NAME'}; + $cahash{$key}[1] = $casubject; + &General::writehasharray("${General::swroot}/vpn/caconfig", \%cahash); + system('/usr/local/bin/ipsecctrl', 'R'); + } + } + } } if (!$errormessage) { - &General::log("ipsec", "Moving host cert..."); - move("/tmp/newhostcert", "${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); - $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); - } + &General::log("ipsec", "Moving host cert..."); + move("/tmp/newhostcert", "${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); + $errormessage = "$Lang::tr{'certificate file move failed'}: $!" if ($? ne 0); + } #cleanup temp files unlink ($filename); unlink ('/tmp/newcacert'); unlink ('/tmp/newhostcert'); if ($errormessage) { - unlink ("${General::swroot}/ca/$cgiparams{'CA_NAME'}cert.pem"); - unlink ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); - goto VPNCONF_ERROR; + unlink ("${General::swroot}/ca/$cgiparams{'CA_NAME'}cert.pem"); + unlink ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); + goto VPNCONF_ERROR; } &General::log("ipsec", "p12 import completed!"); } elsif ($cgiparams{'AUTH'} eq 'certfile') { - if ($cgiparams{'KEY'}) { - $errormessage = $Lang::tr{'cant change certificates'}; - goto VPNCONF_ERROR; - } - if (ref ($cgiparams{'FH'}) ne 'Fh') { - $errormessage = $Lang::tr{'there was no file upload'}; - goto VPNCONF_ERROR; - } - # Move uploaded certificate to a temporary file - (my $fh, my $filename) = tempfile( ); - if (copy ($cgiparams{'FH'}, $fh) != 1) { - $errormessage = $!; - goto VPNCONF_ERROR; - } - - # Verify the certificate has a valid CA and move it - &General::log("ipsec", "Validating imported cert against our known CA..."); - my $validca = 1; #assume ok - my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ca/cacert.pem $filename`; - if ($test !~ /: OK/) { - my $validca = 0; - foreach my $key (keys %cahash) { - $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ca/$cahash{$key}[0]cert.pem $filename`; - if ($test =~ /: OK/) { - $validca = 1; - last; - } + if ($cgiparams{'KEY'}) { + $errormessage = $Lang::tr{'cant change certificates'}; + goto VPNCONF_ERROR; } - } - if (! $validca) { - $errormessage = $Lang::tr{'certificate does not have a valid ca associated with it'}; - unlink ($filename); - goto VPNCONF_ERROR; - } else { - move($filename, "${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); - if ($? ne 0) { - $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; - unlink ($filename); - goto VPNCONF_ERROR; + if (ref ($cgiparams{'FH'}) ne 'Fh') { + $errormessage = $Lang::tr{'there was no file upload'}; + goto VPNCONF_ERROR; + } + # Move uploaded certificate to a temporary file + (my $fh, my $filename) = tempfile( ); + if (copy ($cgiparams{'FH'}, $fh) != 1) { + $errormessage = $!; + goto VPNCONF_ERROR; } - } - $cgiparams{'CERT_NAME'} = getCNfromcert ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); - if ($cgiparams{'CERT_NAME'} eq '') { - unlink ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); - $errormessage = $Lang::tr{'could not retrieve common name from certificate'}; - goto VPNCONF_ERROR; - } + # Verify the certificate has a valid CA and move it + &General::log("ipsec", "Validating imported cert against our known CA..."); + my $validca = 1; #assume ok + my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ca/cacert.pem $filename`; + if ($test !~ /: OK/) { + my $validca = 0; + foreach my $key (keys %cahash) { + $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ca/$cahash{$key}[0]cert.pem $filename`; + if ($test =~ /: OK/) { + $validca = 1; + last; + } + } + } + if (! $validca) { + $errormessage = $Lang::tr{'certificate does not have a valid ca associated with it'}; + unlink ($filename); + goto VPNCONF_ERROR; + } else { + move($filename, "${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); + if ($? ne 0) { + $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; + unlink ($filename); + goto VPNCONF_ERROR; + } + } + + $cgiparams{'CERT_NAME'} = getCNfromcert ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); + if ($cgiparams{'CERT_NAME'} eq '') { + unlink ("${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); + $errormessage = $Lang::tr{'could not retrieve common name from certificate'}; + goto VPNCONF_ERROR; + } } elsif ($cgiparams{'AUTH'} eq 'certgen') { - if ($cgiparams{'KEY'}) { - $errormessage = $Lang::tr{'cant change certificates'}; - goto VPNCONF_ERROR; - } - # Validate input since the form was submitted - if (length($cgiparams{'CERT_NAME'}) >60) { - $errormessage = $Lang::tr{'name too long'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'CERT_NAME'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) { - $errormessage = $Lang::tr{'invalid input for name'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'CERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'CERT_EMAIL'}))) { - $errormessage = $Lang::tr{'invalid input for e-mail address'}; - goto VPNCONF_ERROR; - } - if (length($cgiparams{'CERT_EMAIL'}) > 40) { - $errormessage = $Lang::tr{'e-mail address too long'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'CERT_OU'} ne '' && $cgiparams{'CERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { - $errormessage = $Lang::tr{'invalid input for department'}; - goto VPNCONF_ERROR; - } - if (length($cgiparams{'CERT_ORGANIZATION'}) >60) { - $errormessage = $Lang::tr{'organization too long'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'CERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) { - $errormessage = $Lang::tr{'invalid input for organization'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'CERT_CITY'} ne '' && $cgiparams{'CERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { - $errormessage = $Lang::tr{'invalid input for city'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'CERT_STATE'} ne '' && $cgiparams{'CERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { - $errormessage = $Lang::tr{'invalid input for state or province'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'CERT_COUNTRY'} !~ /^[A-Z]*$/) { - $errormessage = $Lang::tr{'invalid input for country'}; - goto VPNCONF_ERROR; - } - #the exact syntax is a list comma separated of - # email:any-validemail - # URI: a uniform resource indicator - # DNS: a DNS domain name - # RID: a registered OBJECT IDENTIFIER - # IP: an IP address - # example: email:franck@foo.com,IP:10.0.0.10,DNS:franck.foo.com + if ($cgiparams{'KEY'}) { + $errormessage = $Lang::tr{'cant change certificates'}; + goto VPNCONF_ERROR; + } + # Validate input since the form was submitted + if (length($cgiparams{'CERT_NAME'}) >60) { + $errormessage = $Lang::tr{'name too long'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_NAME'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) { + $errormessage = $Lang::tr{'invalid input for name'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'CERT_EMAIL'}))) { + $errormessage = $Lang::tr{'invalid input for e-mail address'}; + goto VPNCONF_ERROR; + } + if (length($cgiparams{'CERT_EMAIL'}) > 40) { + $errormessage = $Lang::tr{'e-mail address too long'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_OU'} ne '' && $cgiparams{'CERT_OU'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for department'}; + goto VPNCONF_ERROR; + } + if (length($cgiparams{'CERT_ORGANIZATION'}) >60) { + $errormessage = $Lang::tr{'organization too long'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_ORGANIZATION'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) { + $errormessage = $Lang::tr{'invalid input for organization'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_CITY'} ne '' && $cgiparams{'CERT_CITY'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for city'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_STATE'} ne '' && $cgiparams{'CERT_STATE'} !~ /^[a-zA-Z0-9 ,\.\-_]*$/) { + $errormessage = $Lang::tr{'invalid input for state or province'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_COUNTRY'} !~ /^[A-Z]*$/) { + $errormessage = $Lang::tr{'invalid input for country'}; + goto VPNCONF_ERROR; + } + #the exact syntax is a list comma separated of + # email:any-validemail + # URI: a uniform resource indicator + # DNS: a DNS domain name + # RID: a registered OBJECT IDENTIFIER + # IP: an IP address + # example: email:franck@foo.com,IP:10.0.0.10,DNS:franck.foo.com - if ($cgiparams{'SUBJECTALTNAME'} ne '' && $cgiparams{'SUBJECTALTNAME'} !~ /^(email|URI|DNS|RID|IP):[a-zA-Z0-9 :\/,\.\-_@]*$/) { - $errormessage = $Lang::tr{'vpn altname syntax'}; - goto VPNCONF_ERROR; - } + if ($cgiparams{'SUBJECTALTNAME'} ne '' && $cgiparams{'SUBJECTALTNAME'} !~ /^(email|URI|DNS|RID|IP):[a-zA-Z0-9 :\/,\.\-_@]*$/) { + $errormessage = $Lang::tr{'vpn altname syntax'}; + goto VPNCONF_ERROR; + } - if (length($cgiparams{'CERT_PASS1'}) < 5) { - $errormessage = $Lang::tr{'password too short'}; - goto VPNCONF_ERROR; - } - if ($cgiparams{'CERT_PASS1'} ne $cgiparams{'CERT_PASS2'}) { - $errormessage = $Lang::tr{'passwords do not match'}; - goto VPNCONF_ERROR; - } + if (length($cgiparams{'CERT_PASS1'}) < 5) { + $errormessage = $Lang::tr{'password too short'}; + goto VPNCONF_ERROR; + } + if ($cgiparams{'CERT_PASS1'} ne $cgiparams{'CERT_PASS2'}) { + $errormessage = $Lang::tr{'passwords do not match'}; + goto VPNCONF_ERROR; + } - # Replace empty strings with a . - (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./; - (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./; - (my $state = $cgiparams{'CERT_STATE'}) =~ s/^\s*$/\./; + # Replace empty strings with a . + (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./; + (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./; + (my $state = $cgiparams{'CERT_STATE'}) =~ s/^\s*$/\./; - # Create the Client certificate request - &General::log("ipsec", "Creating a cert..."); + # Create the Client certificate request + &General::log("ipsec", "Creating a cert..."); - if (open(STDIN, "-|")) { - my $opt = " req -nodes -rand /proc/interrupts:/proc/net/rt_cache"; - $opt .= " -newkey rsa:2048"; - $opt .= " -keyout ${General::swroot}/certs/$cgiparams{'NAME'}key.pem"; - $opt .= " -out ${General::swroot}/certs/$cgiparams{'NAME'}req.pem"; + if (open(STDIN, "-|")) { + my $opt = " req -nodes -rand /proc/interrupts:/proc/net/rt_cache"; + $opt .= " -newkey rsa:2048"; + $opt .= " -keyout ${General::swroot}/certs/$cgiparams{'NAME'}key.pem"; + $opt .= " -out ${General::swroot}/certs/$cgiparams{'NAME'}req.pem"; - if ( $errormessage = &callssl ($opt) ) { - unlink ("${General::swroot}/certs/$cgiparams{'NAME'}key.pem"); - unlink ("${General::swroot}/certs/$cgiparams{'NAME'}req.pem"); - goto VPNCONF_ERROR; - } - } else { #child - print "$cgiparams{'CERT_COUNTRY'}\n"; - print "$state\n"; - print "$city\n"; - print "$cgiparams{'CERT_ORGANIZATION'}\n"; - print "$ou\n"; - print "$cgiparams{'CERT_NAME'}\n"; - print "$cgiparams{'CERT_EMAIL'}\n"; - print ".\n"; - print ".\n"; - exit (0); - } - - # Sign the client certificate request - &General::log("ipsec", "Signing the cert $cgiparams{'NAME'}..."); + if ( $errormessage = &callssl ($opt) ) { + unlink ("${General::swroot}/certs/$cgiparams{'NAME'}key.pem"); + unlink ("${General::swroot}/certs/$cgiparams{'NAME'}req.pem"); + goto VPNCONF_ERROR; + } + } else { #child + print "$cgiparams{'CERT_COUNTRY'}\n"; + print "$state\n"; + print "$city\n"; + print "$cgiparams{'CERT_ORGANIZATION'}\n"; + print "$ou\n"; + print "$cgiparams{'CERT_NAME'}\n"; + print "$cgiparams{'CERT_EMAIL'}\n"; + print ".\n"; + print ".\n"; + exit (0); + } - #No easy way for specifying the contain of subjectAltName without writing a config file... - my ($fh, $v3extname) = tempfile ('/tmp/XXXXXXXX'); - print $fh <$errormessage"; - print " "; - &Header::closebox(); - } + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'ipsec'}, 1, ''); + &Header::openbigbox('100%', 'left', '', $errormessage); + if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage"; + print " "; + &Header::closebox(); + } - if ($warnmessage) { - &Header::openbox('100%', 'left', "$Lang::tr{'warning messages'}:"); - print "$warnmessage"; - print " "; - &Header::closebox(); - } + if ($warnmessage) { + &Header::openbox('100%', 'left', "$Lang::tr{'warning messages'}:"); + print "$warnmessage"; + print " "; + &Header::closebox(); + } - print "
"; - print<"; + print< @@ -1943,178 +1946,183 @@ END - END - ; - if ($cgiparams{'KEY'}) { - print ""; - print ""; - print ""; - } +; + if ($cgiparams{'KEY'}) { + print ""; + print ""; + print ""; + } - &Header::openbox('100%', 'left', "$Lang::tr{'connection'}: $cgiparams{'NAME'}"); - print ""; - if (!$cgiparams{'KEY'}) { - print < - - - - + &Header::openbox('100%', 'left', "$Lang::tr{'connection'}: $cgiparams{'NAME'}"); + print "
$Lang::tr{'name'}: * - -
"; + if (!$cgiparams{'KEY'}) { + print < + + + + EOF - } + } - my $disabled; - my $blob; - if ($cgiparams{'TYPE'} eq 'host') { + my $disabled; + my $blob; + if ($cgiparams{'TYPE'} eq 'host') { $disabled = "disabled='disabled'"; - } elsif ($cgiparams{'TYPE'} eq 'net') { + } elsif ($cgiparams{'TYPE'} eq 'net') { $blob = "*"; - }; + }; - print < - - + + - - - - + + + + - - - - + + + + - - + + END - ; - if (!$cgiparams{'KEY'}) { - print ""; - } - print "
$Lang::tr{'name'}: * + +
$Lang::tr{'enabled'} $Lang::tr{'local subnet'} * - - $Lang::tr{'local subnet'} * + +
$Lang::tr{'remote host/ip'}: $blob - - $Lang::tr{'remote subnet'} $blob - - $Lang::tr{'remote host/ip'}: $blob + + $Lang::tr{'remote subnet'} $blob + +
$Lang::tr{'vpn local id'}: - - $Lang::tr{'vpn remote id'}: - - $Lang::tr{'vpn local id'}: + + $Lang::tr{'vpn remote id'}: + +

$Lang::tr{'remark title'} - - $Lang::tr{'remark title'} + +
$Lang::tr{'edit advanced settings when done'}
"; - &Header::closebox(); - - if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') { - &Header::openbox('100%', 'left', $Lang::tr{'authentication'}); - print < - $Lang::tr{'use a pre-shared key'} - - - -END - ; - &Header::closebox(); - } elsif (! $cgiparams{'KEY'}) { - my $cakeydisabled = ( ! -f "${General::swroot}/private/cakey.pem" ) ? "disabled='disabled'" : ''; - $cgiparams{'CERT_NAME'} = $Lang::tr{'vpn no full pki'} if ($cakeydisabled); - my $cacrtdisabled = ( ! -f "${General::swroot}/ca/cacert.pem" ) ? "disabled='disabled'" : ''; - - &Header::openbox('100%', 'left', $Lang::tr{'authentication'}); - print < - - $Lang::tr{'use a pre-shared key'} - - - -
$Lang::tr{'upload a certificate request'} - - - $Lang::tr{'upload a certificate'} - - $Lang::tr{'upload p12 file'} $Lang::tr{'pkcs12 file password'}: - -
$Lang::tr{'vpn auth-dn'} - - -
$Lang::tr{'generate a certificate'}  -   - $Lang::tr{'users fullname or system hostname'}: * - -   - $Lang::tr{'users email'}: - -   - $Lang::tr{'users department'}: - -   - $Lang::tr{'organization name'}: - -   - $Lang::tr{'city'}: - -   - $Lang::tr{'state or province'}: - -   - $Lang::tr{'country'}: - $Lang::tr{'edit advanced settings when done'}"; } - print < - -  $Lang::tr{'vpn subjectaltname'} (subjectAltName=email:*,URI:*,DNS:*,RID:*) - -   - $Lang::tr{'pkcs12 file password'}: * - -  $Lang::tr{'pkcs12 file password'} ($Lang::tr{'confirmation'}): * - - -END - ; + print ""; &Header::closebox(); - } - print "
"; - if ($cgiparams{'KEY'}) { - print ""; - } - print "
"; - &Header::closebigbox(); - &Header::closepage(); - exit (0); - - VPNCONF_END: + if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') { + &Header::openbox('100%', 'left', $Lang::tr{'authentication'}); + print < + $Lang::tr{'use a pre-shared key'} + + + +END +; + &Header::closebox(); + } elsif (! $cgiparams{'KEY'}) { + my $cakeydisabled = ( ! -f "${General::swroot}/private/cakey.pem" ) ? "disabled='disabled'" : ''; + $cgiparams{'CERT_NAME'} = $Lang::tr{'vpn no full pki'} if ($cakeydisabled); + my $cacrtdisabled = ( ! -f "${General::swroot}/ca/cacert.pem" ) ? "disabled='disabled'" : ''; + + &Header::openbox('100%', 'left', $Lang::tr{'authentication'}); + print < + + $Lang::tr{'use a pre-shared key'} + + + +
$Lang::tr{'upload a certificate request'} + + + $Lang::tr{'upload a certificate'} + + $Lang::tr{'upload p12 file'} $Lang::tr{'pkcs12 file password'}: + +
$Lang::tr{'vpn auth-dn'} + + +
$Lang::tr{'generate a certificate'}  +   + $Lang::tr{'users fullname or system hostname'}: * + +   + $Lang::tr{'users email'}: + +   + $Lang::tr{'users department'}: + +   + $Lang::tr{'organization name'}: + +   + $Lang::tr{'city'}: + +   + $Lang::tr{'state or province'}: + +   + $Lang::tr{'country'}: + +   + $Lang::tr{'pkcs12 file password'}: * + +  $Lang::tr{'pkcs12 file password'} ($Lang::tr{'confirmation'}): * + + +END +; + &Header::closebox(); + } + + print "
"; + if ($cgiparams{'KEY'}) { + print ""; + } + print "
"; + &Header::closebigbox(); + &Header::closepage(); + exit (0); + + VPNCONF_END: } ### @@ -2122,303 +2130,288 @@ END ### if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq 'yes')) { - &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - if (! $confighash{$cgiparams{'KEY'}}) { - $errormessage = $Lang::tr{'invalid key'}; - goto ADVANCED_END; - } + &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + if (! $confighash{$cgiparams{'KEY'}}) { + $errormessage = $Lang::tr{'invalid key'}; + goto ADVANCED_END; + } - if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { - # I didn't read any incompatibilities here.... - #if ($cgiparams{'VHOST'} eq 'on' && $cgiparams{'COMPRESSION'} eq 'on') { - # $errormessage = $Lang::tr{'cannot enable both nat traversal and compression'}; - # goto ADVANCED_ERROR; - #} + if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { + my @temp = split('\|', $cgiparams{'IKE_ENCRYPTION'}); + if ($#temp < 0) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + foreach my $val (@temp) { + if ($val !~ /^(aes(256|192|128)(gcm(128|96|64))?|3des|camellia(256|192|128))$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + } + @temp = split('\|', $cgiparams{'IKE_INTEGRITY'}); + if ($#temp < 0) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + foreach my $val (@temp) { + if ($val !~ /^(sha2_(512|384|256)|sha|md5|aesxcbc)$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + } + @temp = split('\|', $cgiparams{'IKE_GROUPTYPE'}); + if ($#temp < 0) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + foreach my $val (@temp) { + if ($val !~ /^(e521|e384|e256|e224|e192|e512bp|e384bp|e256bp|e224bp|1024|1536|2048|2048s256|2048s224|2048s160|3072|4096|6144|8192)$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + } + if ($cgiparams{'IKE_LIFETIME'} !~ /^\d+$/) { + $errormessage = $Lang::tr{'invalid input for ike lifetime'}; + goto ADVANCED_ERROR; + } + if ($cgiparams{'IKE_LIFETIME'} < 1 || $cgiparams{'IKE_LIFETIME'} > 8) { + $errormessage = $Lang::tr{'ike lifetime should be between 1 and 8 hours'}; + goto ADVANCED_ERROR; + } + @temp = split('\|', $cgiparams{'ESP_ENCRYPTION'}); + if ($#temp < 0) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + foreach my $val (@temp) { + if ($val !~ /^(aes(256|192|128)(gcm(128|96|64))?|3des|camellia(256|192|128))$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + } + @temp = split('\|', $cgiparams{'ESP_INTEGRITY'}); + if ($#temp < 0) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + foreach my $val (@temp) { + if ($val !~ /^(sha2_(512|384|256)|sha1|md5|aesxcbc)$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + } + @temp = split('\|', $cgiparams{'ESP_GROUPTYPE'}); + if ($#temp < 0) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + foreach my $val (@temp) { + if ($val !~ /^(e521|e384|e256|e224|e192|e512bp|e384bp|e256bp|e224bp|1024|1536|2048|2048s256|2048s224|2048s160|3072|4096|6144|8192|none)$/) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + } + if ($cgiparams{'ESP_KEYLIFE'} !~ /^\d+$/) { + $errormessage = $Lang::tr{'invalid input for esp keylife'}; + goto ADVANCED_ERROR; + } + if ($cgiparams{'ESP_KEYLIFE'} < 1 || $cgiparams{'ESP_KEYLIFE'} > 24) { + $errormessage = $Lang::tr{'esp keylife should be between 1 and 24 hours'}; + goto ADVANCED_ERROR; + } + + if (($cgiparams{'COMPRESSION'} !~ /^(|on|off)$/) || + ($cgiparams{'FORCE_MOBIKE'} !~ /^(|on|off)$/) || + ($cgiparams{'ONLY_PROPOSED'} !~ /^(|on|off)$/) || + ($cgiparams{'PFS'} !~ /^(|on|off)$/)) { + $errormessage = $Lang::tr{'invalid input'}; + goto ADVANCED_ERROR; + } + + if ($cgiparams{'DPD_DELAY'} !~ /^\d+$/) { + $errormessage = $Lang::tr{'invalid input for dpd delay'}; + goto ADVANCED_ERROR; + } + + if ($cgiparams{'DPD_TIMEOUT'} !~ /^\d+$/) { + $errormessage = $Lang::tr{'invalid input for dpd timeout'}; + goto ADVANCED_ERROR; + } + + $confighash{$cgiparams{'KEY'}}[29] = $cgiparams{'IKE_VERSION'}; + $confighash{$cgiparams{'KEY'}}[18] = $cgiparams{'IKE_ENCRYPTION'}; + $confighash{$cgiparams{'KEY'}}[19] = $cgiparams{'IKE_INTEGRITY'}; + $confighash{$cgiparams{'KEY'}}[20] = $cgiparams{'IKE_GROUPTYPE'}; + $confighash{$cgiparams{'KEY'}}[16] = $cgiparams{'IKE_LIFETIME'}; + $confighash{$cgiparams{'KEY'}}[21] = $cgiparams{'ESP_ENCRYPTION'}; + $confighash{$cgiparams{'KEY'}}[22] = $cgiparams{'ESP_INTEGRITY'}; + $confighash{$cgiparams{'KEY'}}[23] = $cgiparams{'ESP_GROUPTYPE'}; + $confighash{$cgiparams{'KEY'}}[17] = $cgiparams{'ESP_KEYLIFE'}; + $confighash{$cgiparams{'KEY'}}[12] = 'off'; #$cgiparams{'AGGRMODE'}; + $confighash{$cgiparams{'KEY'}}[13] = $cgiparams{'COMPRESSION'}; + $confighash{$cgiparams{'KEY'}}[24] = $cgiparams{'ONLY_PROPOSED'}; + $confighash{$cgiparams{'KEY'}}[28] = $cgiparams{'PFS'}; + $confighash{$cgiparams{'KEY'}}[27] = $cgiparams{'DPD_ACTION'}; + $confighash{$cgiparams{'KEY'}}[30] = $cgiparams{'DPD_TIMEOUT'}; + $confighash{$cgiparams{'KEY'}}[31] = $cgiparams{'DPD_DELAY'}; + $confighash{$cgiparams{'KEY'}}[32] = $cgiparams{'FORCE_MOBIKE'}; + &General::writehasharray("${General::swroot}/vpn/config", \%confighash); + &writeipsecfiles(); + if (&vpnenabled) { + system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}); + sleep $sleepDelay; + } + goto ADVANCED_END; + } else { + $cgiparams{'IKE_VERSION'} = $confighash{$cgiparams{'KEY'}}[29]; + $cgiparams{'IKE_ENCRYPTION'} = $confighash{$cgiparams{'KEY'}}[18]; + $cgiparams{'IKE_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[19]; + $cgiparams{'IKE_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[20]; + $cgiparams{'IKE_LIFETIME'} = $confighash{$cgiparams{'KEY'}}[16]; + $cgiparams{'ESP_ENCRYPTION'} = $confighash{$cgiparams{'KEY'}}[21]; + $cgiparams{'ESP_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[22]; + $cgiparams{'ESP_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[23]; + if ($cgiparams{'ESP_GROUPTYPE'} eq "") { + $cgiparams{'ESP_GROUPTYPE'} = $cgiparams{'IKE_GROUPTYPE'}; + } + $cgiparams{'ESP_KEYLIFE'} = $confighash{$cgiparams{'KEY'}}[17]; + $cgiparams{'COMPRESSION'} = $confighash{$cgiparams{'KEY'}}[13]; + $cgiparams{'ONLY_PROPOSED'} = $confighash{$cgiparams{'KEY'}}[24]; + $cgiparams{'PFS'} = $confighash{$cgiparams{'KEY'}}[28]; + $cgiparams{'DPD_ACTION'} = $confighash{$cgiparams{'KEY'}}[27]; + $cgiparams{'DPD_TIMEOUT'} = $confighash{$cgiparams{'KEY'}}[30]; + $cgiparams{'DPD_DELAY'} = $confighash{$cgiparams{'KEY'}}[31]; + $cgiparams{'FORCE_MOBIKE'} = $confighash{$cgiparams{'KEY'}}[32]; + + if (!$cgiparams{'DPD_DELAY'}) { + $cgiparams{'DPD_DELAY'} = 30; + } + + if (!$cgiparams{'DPD_TIMEOUT'}) { + $cgiparams{'DPD_TIMEOUT'} = 120; + } + } + + ADVANCED_ERROR: + $checked{'IKE_ENCRYPTION'}{'aes256'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes192'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes128'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes256gcm128'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes192gcm128'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes128gcm128'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes256gcm96'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes192gcm96'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes128gcm96'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes256gcm64'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes192gcm64'} = ''; + $checked{'IKE_ENCRYPTION'}{'aes128gcm64'} = ''; + $checked{'IKE_ENCRYPTION'}{'3des'} = ''; + $checked{'IKE_ENCRYPTION'}{'camellia256'} = ''; + $checked{'IKE_ENCRYPTION'}{'camellia192'} = ''; + $checked{'IKE_ENCRYPTION'}{'camellia128'} = ''; my @temp = split('\|', $cgiparams{'IKE_ENCRYPTION'}); - if ($#temp < 0) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - foreach my $val (@temp) { - if ($val !~ /^(aes(256|192|128)(gcm(128|96|64))?|3des|camellia(256|192|128))$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - } + foreach my $key (@temp) {$checked{'IKE_ENCRYPTION'}{$key} = "selected='selected'"; } + $checked{'IKE_INTEGRITY'}{'sha2_512'} = ''; + $checked{'IKE_INTEGRITY'}{'sha2_384'} = ''; + $checked{'IKE_INTEGRITY'}{'sha2_256'} = ''; + $checked{'IKE_INTEGRITY'}{'sha'} = ''; + $checked{'IKE_INTEGRITY'}{'md5'} = ''; + $checked{'IKE_INTEGRITY'}{'aesxcbc'} = ''; @temp = split('\|', $cgiparams{'IKE_INTEGRITY'}); - if ($#temp < 0) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - foreach my $val (@temp) { - if ($val !~ /^(sha2_(512|384|256)|sha|md5|aesxcbc)$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - } + foreach my $key (@temp) {$checked{'IKE_INTEGRITY'}{$key} = "selected='selected'"; } + $checked{'IKE_GROUPTYPE'}{'768'} = ''; + $checked{'IKE_GROUPTYPE'}{'1024'} = ''; + $checked{'IKE_GROUPTYPE'}{'1536'} = ''; + $checked{'IKE_GROUPTYPE'}{'2048'} = ''; + $checked{'IKE_GROUPTYPE'}{'3072'} = ''; + $checked{'IKE_GROUPTYPE'}{'4096'} = ''; + $checked{'IKE_GROUPTYPE'}{'6144'} = ''; + $checked{'IKE_GROUPTYPE'}{'8192'} = ''; @temp = split('\|', $cgiparams{'IKE_GROUPTYPE'}); - if ($#temp < 0) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - foreach my $val (@temp) { - if ($val !~ /^(e521|e384|e256|e224|e192|e512bp|e384bp|e256bp|e224bp|1024|1536|2048|2048s256|2048s224|2048s160|3072|4096|6144|8192)$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - } - if ($cgiparams{'IKE_LIFETIME'} !~ /^\d+$/) { - $errormessage = $Lang::tr{'invalid input for ike lifetime'}; - goto ADVANCED_ERROR; - } - if ($cgiparams{'IKE_LIFETIME'} < 1 || $cgiparams{'IKE_LIFETIME'} > 8) { - $errormessage = $Lang::tr{'ike lifetime should be between 1 and 8 hours'}; - goto ADVANCED_ERROR; - } + foreach my $key (@temp) {$checked{'IKE_GROUPTYPE'}{$key} = "selected='selected'"; } + + # 768 is not supported by strongswan + $checked{'IKE_GROUPTYPE'}{'768'} = ''; + + $checked{'ESP_ENCRYPTION'}{'aes256'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes192'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes128'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes256gcm128'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes192gcm128'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes128gcm128'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes256gcm96'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes192gcm96'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes128gcm96'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes256gcm64'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes192gcm64'} = ''; + $checked{'ESP_ENCRYPTION'}{'aes128gcm64'} = ''; + $checked{'ESP_ENCRYPTION'}{'3des'} = ''; + $checked{'ESP_ENCRYPTION'}{'camellia256'} = ''; + $checked{'ESP_ENCRYPTION'}{'camellia192'} = ''; + $checked{'ESP_ENCRYPTION'}{'camellia128'} = ''; @temp = split('\|', $cgiparams{'ESP_ENCRYPTION'}); - if ($#temp < 0) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - foreach my $val (@temp) { - if ($val !~ /^(aes(256|192|128)(gcm(128|96|64))?|3des|camellia(256|192|128))$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - } + foreach my $key (@temp) {$checked{'ESP_ENCRYPTION'}{$key} = "selected='selected'"; } + $checked{'ESP_INTEGRITY'}{'sha2_512'} = ''; + $checked{'ESP_INTEGRITY'}{'sha2_384'} = ''; + $checked{'ESP_INTEGRITY'}{'sha2_256'} = ''; + $checked{'ESP_INTEGRITY'}{'sha1'} = ''; + $checked{'ESP_INTEGRITY'}{'md5'} = ''; + $checked{'ESP_INTEGRITY'}{'aesxcbc'} = ''; @temp = split('\|', $cgiparams{'ESP_INTEGRITY'}); - if ($#temp < 0) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - foreach my $val (@temp) { - if ($val !~ /^(sha2_(512|384|256)|sha1|md5|aesxcbc)$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - } + foreach my $key (@temp) {$checked{'ESP_INTEGRITY'}{$key} = "selected='selected'"; } + $checked{'ESP_GROUPTYPE'}{'768'} = ''; + $checked{'ESP_GROUPTYPE'}{'1024'} = ''; + $checked{'ESP_GROUPTYPE'}{'1536'} = ''; + $checked{'ESP_GROUPTYPE'}{'2048'} = ''; + $checked{'ESP_GROUPTYPE'}{'3072'} = ''; + $checked{'ESP_GROUPTYPE'}{'4096'} = ''; + $checked{'ESP_GROUPTYPE'}{'6144'} = ''; + $checked{'ESP_GROUPTYPE'}{'8192'} = ''; + $checked{'ESP_GROUPTYPE'}{'none'} = ''; @temp = split('\|', $cgiparams{'ESP_GROUPTYPE'}); - if ($#temp < 0) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - foreach my $val (@temp) { - if ($val !~ /^(e521|e384|e256|e224|e192|e512bp|e384bp|e256bp|e224bp|1024|1536|2048|2048s256|2048s224|2048s160|3072|4096|6144|8192|none)$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - } - if ($cgiparams{'ESP_KEYLIFE'} !~ /^\d+$/) { - $errormessage = $Lang::tr{'invalid input for esp keylife'}; - goto ADVANCED_ERROR; - } - if ($cgiparams{'ESP_KEYLIFE'} < 1 || $cgiparams{'ESP_KEYLIFE'} > 24) { - $errormessage = $Lang::tr{'esp keylife should be between 1 and 24 hours'}; - goto ADVANCED_ERROR; + foreach my $key (@temp) {$checked{'ESP_GROUPTYPE'}{$key} = "selected='selected'"; } + + $checked{'COMPRESSION'} = $cgiparams{'COMPRESSION'} eq 'on' ? "checked='checked'" : '' ; + $checked{'FORCE_MOBIKE'} = $cgiparams{'FORCE_MOBIKE'} eq 'on' ? "checked='checked'" : '' ; + $checked{'ONLY_PROPOSED'} = $cgiparams{'ONLY_PROPOSED'} eq 'on' ? "checked='checked'" : '' ; + $checked{'PFS'} = $cgiparams{'PFS'} eq 'on' ? "checked='checked'" : '' ; + + $selected{'IKE_VERSION'}{'ikev1'} = ''; + $selected{'IKE_VERSION'}{'ikev2'} = ''; + $selected{'IKE_VERSION'}{$cgiparams{'IKE_VERSION'}} = "selected='selected'"; + + $selected{'DPD_ACTION'}{'clear'} = ''; + $selected{'DPD_ACTION'}{'hold'} = ''; + $selected{'DPD_ACTION'}{'restart'} = ''; + $selected{'DPD_ACTION'}{'none'} = ''; + $selected{'DPD_ACTION'}{$cgiparams{'DPD_ACTION'}} = "selected='selected'"; + + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'ipsec'}, 1, ''); + &Header::openbigbox('100%', 'left', '', $errormessage); + + if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage"; + print " "; + &Header::closebox(); } - if ( - ($cgiparams{'COMPRESSION'} !~ /^(|on|off)$/) || - ($cgiparams{'FORCE_MOBIKE'} !~ /^(|on|off)$/) || - ($cgiparams{'ONLY_PROPOSED'} !~ /^(|on|off)$/) || - ($cgiparams{'PFS'} !~ /^(|on|off)$/) || - ($cgiparams{'VHOST'} !~ /^(|on|off)$/) - ){ - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; + if ($warnmessage) { + &Header::openbox('100%', 'left', $Lang::tr{'warning messages'}); + print "$warnmessage"; + print " "; + &Header::closebox(); } - if ($cgiparams{'DPD_DELAY'} !~ /^\d+$/) { - $errormessage = $Lang::tr{'invalid input for dpd delay'}; - goto ADVANCED_ERROR; - } + &Header::openbox('100%', 'left', "$Lang::tr{'advanced'}:"); + print < + + - if ($cgiparams{'DPD_TIMEOUT'} !~ /^\d+$/) { - $errormessage = $Lang::tr{'invalid input for dpd timeout'}; - goto ADVANCED_ERROR; - } - - $confighash{$cgiparams{'KEY'}}[29] = $cgiparams{'IKE_VERSION'}; - $confighash{$cgiparams{'KEY'}}[18] = $cgiparams{'IKE_ENCRYPTION'}; - $confighash{$cgiparams{'KEY'}}[19] = $cgiparams{'IKE_INTEGRITY'}; - $confighash{$cgiparams{'KEY'}}[20] = $cgiparams{'IKE_GROUPTYPE'}; - $confighash{$cgiparams{'KEY'}}[16] = $cgiparams{'IKE_LIFETIME'}; - $confighash{$cgiparams{'KEY'}}[21] = $cgiparams{'ESP_ENCRYPTION'}; - $confighash{$cgiparams{'KEY'}}[22] = $cgiparams{'ESP_INTEGRITY'}; - $confighash{$cgiparams{'KEY'}}[23] = $cgiparams{'ESP_GROUPTYPE'}; - $confighash{$cgiparams{'KEY'}}[17] = $cgiparams{'ESP_KEYLIFE'}; - $confighash{$cgiparams{'KEY'}}[12] = 'off'; #$cgiparams{'AGGRMODE'}; - $confighash{$cgiparams{'KEY'}}[13] = $cgiparams{'COMPRESSION'}; - $confighash{$cgiparams{'KEY'}}[24] = $cgiparams{'ONLY_PROPOSED'}; - $confighash{$cgiparams{'KEY'}}[28] = $cgiparams{'PFS'}; - $confighash{$cgiparams{'KEY'}}[14] = $cgiparams{'VHOST'}; - $confighash{$cgiparams{'KEY'}}[27] = $cgiparams{'DPD_ACTION'}; - $confighash{$cgiparams{'KEY'}}[30] = $cgiparams{'DPD_TIMEOUT'}; - $confighash{$cgiparams{'KEY'}}[31] = $cgiparams{'DPD_DELAY'}; - $confighash{$cgiparams{'KEY'}}[32] = $cgiparams{'FORCE_MOBIKE'}; - &General::writehasharray("${General::swroot}/vpn/config", \%confighash); - &writeipsecfiles(); - if (&vpnenabled) { - system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}); - sleep $sleepDelay; - } - goto ADVANCED_END; - } else { - $cgiparams{'IKE_VERSION'} = $confighash{$cgiparams{'KEY'}}[29]; - $cgiparams{'IKE_ENCRYPTION'} = $confighash{$cgiparams{'KEY'}}[18]; - $cgiparams{'IKE_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[19]; - $cgiparams{'IKE_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[20]; - $cgiparams{'IKE_LIFETIME'} = $confighash{$cgiparams{'KEY'}}[16]; - $cgiparams{'ESP_ENCRYPTION'} = $confighash{$cgiparams{'KEY'}}[21]; - $cgiparams{'ESP_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[22]; - $cgiparams{'ESP_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[23]; - if ($cgiparams{'ESP_GROUPTYPE'} eq "") { - $cgiparams{'ESP_GROUPTYPE'} = $cgiparams{'IKE_GROUPTYPE'}; - } - $cgiparams{'ESP_KEYLIFE'} = $confighash{$cgiparams{'KEY'}}[17]; - $cgiparams{'COMPRESSION'} = $confighash{$cgiparams{'KEY'}}[13]; - $cgiparams{'ONLY_PROPOSED'} = $confighash{$cgiparams{'KEY'}}[24]; - $cgiparams{'PFS'} = $confighash{$cgiparams{'KEY'}}[28]; - $cgiparams{'VHOST'} = $confighash{$cgiparams{'KEY'}}[14]; - $cgiparams{'DPD_ACTION'} = $confighash{$cgiparams{'KEY'}}[27]; - $cgiparams{'DPD_TIMEOUT'} = $confighash{$cgiparams{'KEY'}}[30]; - $cgiparams{'DPD_DELAY'} = $confighash{$cgiparams{'KEY'}}[31]; - $cgiparams{'FORCE_MOBIKE'} = $confighash{$cgiparams{'KEY'}}[32]; - - if (!$cgiparams{'DPD_DELAY'}) { - $cgiparams{'DPD_DELAY'} = 30; - } - - if (!$cgiparams{'DPD_TIMEOUT'}) { - $cgiparams{'DPD_TIMEOUT'} = 120; - } - - if ($confighash{$cgiparams{'KEY'}}[3] eq 'net' || $confighash{$cgiparams{'KEY'}}[10]) { - $cgiparams{'VHOST'} = 'off'; - } - } - - ADVANCED_ERROR: - $checked{'IKE_ENCRYPTION'}{'aes256'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes192'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes128'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes256gcm128'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes192gcm128'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes128gcm128'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes256gcm96'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes192gcm96'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes128gcm96'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes256gcm64'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes192gcm64'} = ''; - $checked{'IKE_ENCRYPTION'}{'aes128gcm64'} = ''; - $checked{'IKE_ENCRYPTION'}{'3des'} = ''; - $checked{'IKE_ENCRYPTION'}{'camellia256'} = ''; - $checked{'IKE_ENCRYPTION'}{'camellia192'} = ''; - $checked{'IKE_ENCRYPTION'}{'camellia128'} = ''; - my @temp = split('\|', $cgiparams{'IKE_ENCRYPTION'}); - foreach my $key (@temp) {$checked{'IKE_ENCRYPTION'}{$key} = "selected='selected'"; } - $checked{'IKE_INTEGRITY'}{'sha2_512'} = ''; - $checked{'IKE_INTEGRITY'}{'sha2_384'} = ''; - $checked{'IKE_INTEGRITY'}{'sha2_256'} = ''; - $checked{'IKE_INTEGRITY'}{'sha'} = ''; - $checked{'IKE_INTEGRITY'}{'md5'} = ''; - $checked{'IKE_INTEGRITY'}{'aesxcbc'} = ''; - @temp = split('\|', $cgiparams{'IKE_INTEGRITY'}); - foreach my $key (@temp) {$checked{'IKE_INTEGRITY'}{$key} = "selected='selected'"; } - $checked{'IKE_GROUPTYPE'}{'768'} = ''; - $checked{'IKE_GROUPTYPE'}{'1024'} = ''; - $checked{'IKE_GROUPTYPE'}{'1536'} = ''; - $checked{'IKE_GROUPTYPE'}{'2048'} = ''; - $checked{'IKE_GROUPTYPE'}{'3072'} = ''; - $checked{'IKE_GROUPTYPE'}{'4096'} = ''; - $checked{'IKE_GROUPTYPE'}{'6144'} = ''; - $checked{'IKE_GROUPTYPE'}{'8192'} = ''; - @temp = split('\|', $cgiparams{'IKE_GROUPTYPE'}); - foreach my $key (@temp) {$checked{'IKE_GROUPTYPE'}{$key} = "selected='selected'"; } - - # 768 is not supported by strongswan - $checked{'IKE_GROUPTYPE'}{'768'} = ''; - - $checked{'ESP_ENCRYPTION'}{'aes256'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes192'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes128'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes256gcm128'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes192gcm128'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes128gcm128'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes256gcm96'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes192gcm96'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes128gcm96'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes256gcm64'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes192gcm64'} = ''; - $checked{'ESP_ENCRYPTION'}{'aes128gcm64'} = ''; - $checked{'ESP_ENCRYPTION'}{'3des'} = ''; - $checked{'ESP_ENCRYPTION'}{'camellia256'} = ''; - $checked{'ESP_ENCRYPTION'}{'camellia192'} = ''; - $checked{'ESP_ENCRYPTION'}{'camellia128'} = ''; - @temp = split('\|', $cgiparams{'ESP_ENCRYPTION'}); - foreach my $key (@temp) {$checked{'ESP_ENCRYPTION'}{$key} = "selected='selected'"; } - $checked{'ESP_INTEGRITY'}{'sha2_512'} = ''; - $checked{'ESP_INTEGRITY'}{'sha2_384'} = ''; - $checked{'ESP_INTEGRITY'}{'sha2_256'} = ''; - $checked{'ESP_INTEGRITY'}{'sha1'} = ''; - $checked{'ESP_INTEGRITY'}{'md5'} = ''; - $checked{'ESP_INTEGRITY'}{'aesxcbc'} = ''; - @temp = split('\|', $cgiparams{'ESP_INTEGRITY'}); - foreach my $key (@temp) {$checked{'ESP_INTEGRITY'}{$key} = "selected='selected'"; } - $checked{'ESP_GROUPTYPE'}{'768'} = ''; - $checked{'ESP_GROUPTYPE'}{'1024'} = ''; - $checked{'ESP_GROUPTYPE'}{'1536'} = ''; - $checked{'ESP_GROUPTYPE'}{'2048'} = ''; - $checked{'ESP_GROUPTYPE'}{'3072'} = ''; - $checked{'ESP_GROUPTYPE'}{'4096'} = ''; - $checked{'ESP_GROUPTYPE'}{'6144'} = ''; - $checked{'ESP_GROUPTYPE'}{'8192'} = ''; - $checked{'ESP_GROUPTYPE'}{'none'} = ''; - @temp = split('\|', $cgiparams{'ESP_GROUPTYPE'}); - foreach my $key (@temp) {$checked{'ESP_GROUPTYPE'}{$key} = "selected='selected'"; } - - $checked{'COMPRESSION'} = $cgiparams{'COMPRESSION'} eq 'on' ? "checked='checked'" : '' ; - $checked{'FORCE_MOBIKE'} = $cgiparams{'FORCE_MOBIKE'} eq 'on' ? "checked='checked'" : '' ; - $checked{'ONLY_PROPOSED'} = $cgiparams{'ONLY_PROPOSED'} eq 'on' ? "checked='checked'" : '' ; - $checked{'PFS'} = $cgiparams{'PFS'} eq 'on' ? "checked='checked'" : '' ; - $checked{'VHOST'} = $cgiparams{'VHOST'} eq 'on' ? "checked='checked'" : '' ; - - $selected{'IKE_VERSION'}{'ikev1'} = ''; - $selected{'IKE_VERSION'}{'ikev2'} = ''; - $selected{'IKE_VERSION'}{$cgiparams{'IKE_VERSION'}} = "selected='selected'"; - - $selected{'DPD_ACTION'}{'clear'} = ''; - $selected{'DPD_ACTION'}{'hold'} = ''; - $selected{'DPD_ACTION'}{'restart'} = ''; - $selected{'DPD_ACTION'}{'none'} = ''; - $selected{'DPD_ACTION'}{$cgiparams{'DPD_ACTION'}} = "selected='selected'"; - - &Header::showhttpheaders(); - &Header::openpage($Lang::tr{'ipsec'}, 1, ''); - &Header::openbigbox('100%', 'left', '', $errormessage); - - if ($errormessage) { - &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); - print "$errormessage"; - print " "; - &Header::closebox(); - } - - if ($warnmessage) { - &Header::openbox('100%', 'left', $Lang::tr{'warning messages'}); - print "$warnmessage"; - print " "; - &Header::closebox(); - } - - &Header::openbox('100%', 'left', "$Lang::tr{'advanced'}:"); - print < - - - - +
@@ -2564,14 +2557,14 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || -
+

$Lang::tr{'dead peer detection'}

- - +
+ -
$Lang::tr{'dpd action'}:
+ -
+
- +
EOF - ; - if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') { - print ""; - } elsif ($confighash{$cgiparams{'KEY'}}[10]) { - print ""; - } else { - print ""; - } +; - print < -
* $Lang::tr{'required field'} @@ -2651,58 +2635,58 @@ EOF
+ EOF - &Header::closebox(); - &Header::closebigbox(); - &Header::closepage(); - exit(0); + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit(0); - ADVANCED_END: + ADVANCED_END: } ### ### Default status page ### - %cgiparams = (); - %cahash = (); - %confighash = (); - &General::readhash("${General::swroot}/vpn/settings", \%cgiparams); - &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); - &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - $cgiparams{'CA_NAME'} = ''; + %cgiparams = (); + %cahash = (); + %confighash = (); + &General::readhash("${General::swroot}/vpn/settings", \%cgiparams); + &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash); + &General::readhasharray("${General::swroot}/vpn/config", \%confighash); + $cgiparams{'CA_NAME'} = ''; - my @status = `/usr/local/bin/ipsecctrl I 2>/dev/null`; + my @status = `/usr/local/bin/ipsecctrl I 2>/dev/null`; - # suggest a default name for this side - if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") { - if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) { - my $ipaddr = ; - close IPADDR; - chomp ($ipaddr); - $cgiparams{'VPN_IP'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0]; - if ($cgiparams{'VPN_IP'} eq '') { - $cgiparams{'VPN_IP'} = $ipaddr; - } + # suggest a default name for this side + if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") { + if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) { + my $ipaddr = ; + close IPADDR; + chomp ($ipaddr); + $cgiparams{'VPN_IP'} = (gethostbyaddr(pack("C4", split(/\./, $ipaddr)), 2))[0]; + if ($cgiparams{'VPN_IP'} eq '') { + $cgiparams{'VPN_IP'} = $ipaddr; + } + } } - } - # no IP found, use %defaultroute - $cgiparams{'VPN_IP'} ='%defaultroute' if ($cgiparams{'VPN_IP'} eq ''); - - $cgiparams{'VPN_DELAYED_START'} = 0 if (! defined ($cgiparams{'VPN_DELAYED_START'})); - $checked{'ENABLED'} = $cgiparams{'ENABLED'} eq 'on' ? "checked='checked'" : ''; + # no IP found, use %defaultroute + $cgiparams{'VPN_IP'} ='%defaultroute' if ($cgiparams{'VPN_IP'} eq ''); - &Header::showhttpheaders(); - &Header::openpage($Lang::tr{'ipsec'}, 1, ''); - &Header::openbigbox('100%', 'left', '', $errormessage); + $cgiparams{'VPN_DELAYED_START'} = 0 if (! defined ($cgiparams{'VPN_DELAYED_START'})); + $checked{'ENABLED'} = $cgiparams{'ENABLED'} eq 'on' ? "checked='checked'" : ''; - if ($errormessage) { - &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); - print "$errormessage\n"; - print " \n"; - &Header::closebox(); - } + &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'ipsec'}, 1, ''); + &Header::openbigbox('100%', 'left', '', $errormessage); + + if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage\n"; + print " \n"; + &Header::closebox(); + } if ($warnmessage) { &Header::openbox('100%', 'left', $Lang::tr{'warning messages'}); @@ -2714,61 +2698,61 @@ EOF exit 0; } - &Header::openbox('100%', 'left', $Lang::tr{'global settings'}); - print < - - + &Header::openbox('100%', 'left', $Lang::tr{'global settings'}); + print < +
+ - + END - ; +; print < - + + - - - + + + - +
$Lang::tr{'vpn red name'}: * $Lang::tr{'enabled'}
$Lang::tr{'vpn delayed start'}: **
$Lang::tr{'vpn delayed start'}: **
$Lang::tr{'host to net vpn'}:
$Lang::tr{'host to net vpn'}:


- - + + - - - + + +
*$Lang::tr{'required field'}*$Lang::tr{'required field'}
**  $Lang::tr{'vpn delayed start help'}**  $Lang::tr{'vpn delayed start help'}
END -; - print ""; - &Header::closebox(); +; + print ""; + &Header::closebox(); - &Header::openbox('100%', 'left', $Lang::tr{'connection status and controlc'}); - print < - + &Header::openbox('100%', 'left', $Lang::tr{'connection status and controlc'}); + print < + $Lang::tr{'name'} $Lang::tr{'type'} $Lang::tr{'common name'} $Lang::tr{'remark'} $Lang::tr{'status'} $Lang::tr{'action'} - + END - ; - my $id = 0; - my $gif; - foreach my $key (sort { ncmp ($confighash{$a}[1],$confighash{$b}[1]) } keys %confighash) { +; + my $id = 0; + my $gif; + foreach my $key (sort { ncmp ($confighash{$a}[1],$confighash{$b}[1]) } keys %confighash) { if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; } if ($id % 2) { @@ -2781,302 +2765,304 @@ END print "$confighash{$key}[1]"; print "" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ") $confighash{$key}[29]"; if ($confighash{$key}[2] eq '%auth-dn') { - print "$confighash{$key}[9]"; + print "$confighash{$key}[9]"; } elsif ($confighash{$key}[4] eq 'cert') { - print "$confighash{$key}[2]"; + print "$confighash{$key}[2]"; } else { - print " "; + print " "; } print "$confighash{$key}[25]"; my $col1="bgcolor='${Header::colourred}'"; # get real state my $active = "$Lang::tr{'capsclosed'}"; foreach my $line (@status) { - if (($line =~ /\"$confighash{$key}[1]\".*IPsec SA established/) || - ($line =~ /$confighash{$key}[1]\{.*INSTALLED/)) - { - $col1="bgcolor='${Header::colourgreen}'"; - $active = "$Lang::tr{'capsopen'}"; - } + if (($line =~ /\"$confighash{$key}[1]\".*IPsec SA established/) || + ($line =~ /$confighash{$key}[1]\{.*INSTALLED/)) { + $col1="bgcolor='${Header::colourgreen}'"; + $active = "$Lang::tr{'capsopen'}"; + } } - # move to blueif really down + # move to blue if really down if ($confighash{$key}[0] eq 'off' && $col1 =~ /${Header::colourred}/ ) { $col1="bgcolor='${Header::colourblue}'"; - $active = "$Lang::tr{'capsclosed'}"; + $active = "$Lang::tr{'capsclosed'}"; } print <$active -
- - - -
+
+ + + +
END - ; +; if (($confighash{$key}[4] eq 'cert') && ($confighash{$key}[2] ne '%auth-dn')) { - print < -
+ print < + - - + + END - ; } else { - print " "; +; + } else { + print " "; } - if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/certs/$confighash{$key}[1].p12") { - print < -
+ if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/certs/$confighash{$key}[1].p12") { + print < + - + END - ; } elsif (($confighash{$key}[4] eq 'cert') && ($confighash{$key}[2] ne '%auth-dn')) { - print < -
+; + } elsif (($confighash{$key}[4] eq 'cert') && ($confighash{$key}[2] ne '%auth-dn')) { + print < + - + END - ; } else { - print " "; +; + } else { + print " "; } print < -
- - - -
+
+ + + +
-
- - - -
+
+ + + +
-
- - - -
+
+ + + +
END - ; +; $id++; - } - print ""; + } + print ""; - # If the config file contains entries, print Key to action icons - if ( $id ) { - print < - -   $Lang::tr{'legend'}: -   $Lang::tr{ - $Lang::tr{'click to disable'} -     $Lang::tr{ - $Lang::tr{'show certificate'} -     $Lang::tr{ - $Lang::tr{'edit'} -     $Lang::tr{ - $Lang::tr{'remove'} - - -   -   ?OFF - $Lang::tr{'click to enable'} -     ?FLOPPY - $Lang::tr{'download certificate'} -     ?RELOAD - $Lang::tr{'restart'} - - + # If the config file contains entries, print Key to action icons + if ( $id ) { + print < + +   $Lang::tr{'legend'}: +   $Lang::tr{ + $Lang::tr{'click to disable'} +     $Lang::tr{ + $Lang::tr{'show certificate'} +     $Lang::tr{ + $Lang::tr{'edit'} +     $Lang::tr{ + $Lang::tr{'remove'} + + +   +   ?OFF + $Lang::tr{'click to enable'} +     ?FLOPPY + $Lang::tr{'download certificate'} +     ?RELOAD + $Lang::tr{'restart'} + + END - ; - } +; + } - print < - + print < +
- - + + END - ; - &Header::closebox(); +; + &Header::closebox(); - &Header::openbox('100%', 'left', "$Lang::tr{'certificate authorities'}"); - print < - + &Header::openbox('100%', 'left', "$Lang::tr{'certificate authorities'}"); + print < + $Lang::tr{'name'} $Lang::tr{'subject'} $Lang::tr{'action'} - + EOF - ; - my $col1="bgcolor='$color{'color22'}'"; +; + my $col1="bgcolor='$color{'color22'}'"; my $col2="bgcolor='$color{'color20'}'"; - if (-f "${General::swroot}/ca/cacert.pem") { - my $casubject = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/ca/cacert.pem")); - print < - $Lang::tr{'root certificate'} - $casubject - -
- - -
- - -
- - -
- -   + if (-f "${General::swroot}/ca/cacert.pem") { + my $casubject = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/ca/cacert.pem")); + print < + $Lang::tr{'root certificate'} + $casubject + +
+ + +
+ + +
+ + +
+ +   END - ; - } else { - # display rootcert generation buttons - print < - $Lang::tr{'root certificate'}: - $Lang::tr{'not present'} -   +; + } else { + # display rootcert generation buttons + print < + $Lang::tr{'root certificate'}: + $Lang::tr{'not present'} +   END - ; - } +; + } - if (-f "${General::swroot}/certs/hostcert.pem") { - my $hostsubject = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/certs/hostcert.pem")); + if (-f "${General::swroot}/certs/hostcert.pem") { + my $hostsubject = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/certs/hostcert.pem")); - print < - $Lang::tr{'host certificate'} - $hostsubject - -
- - -
- - -
- - -
- -   + print < + $Lang::tr{'host certificate'} + $hostsubject + +
+ + +
+ + +
+ + +
+ +   END - ; - } else { - # Nothing - print < - $Lang::tr{'host certificate'}: - $Lang::tr{'not present'} -   +; + } else { + # Nothing + print < + $Lang::tr{'host certificate'}: + $Lang::tr{'not present'} +   END - ; - } - +; + } + my $rowcolor = 0; if (keys %cahash > 0) { foreach my $key (keys %cahash) { - if ($rowcolor++ % 2) { - print ""; - $col="bgcolor='$color{'color20'}'"; - } else { - print ""; - $col="bgcolor='$color{'color22'}'"; - } - print "$cahash{$key}[0]\n"; - print "$cahash{$key}[1]\n"; - print < -
- - - -
- - -
- - - -
- - -
- - - -
- - + if ($rowcolor++ % 2) { + print ""; + $col="bgcolor='$color{'color20'}'"; + } else { + print ""; + $col="bgcolor='$color{'color22'}'"; + } + print "$cahash{$key}[0]\n"; + print "$cahash{$key}[1]\n"; + print < +
+ + + +
+ + +
+ + + +
+ + +
+ + + +
+ + END - ; +; + } } - } - print ""; + print ""; - # If the file contains entries, print Key to action icons - if ( -f "${General::swroot}/ca/cacert.pem") { - print < -   $Lang::tr{'legend'}: -     $Lang::tr{ - $Lang::tr{'show certificate'} -     $Lang::tr{ - $Lang::tr{'download certificate'} - + # If the file contains entries, print Key to action icons + if ( -f "${General::swroot}/ca/cacert.pem") { + print < +   $Lang::tr{'legend'}: +     $Lang::tr{ + $Lang::tr{'show certificate'} +     $Lang::tr{ + $Lang::tr{'download certificate'} + END - ; - } - my $createCA = -f "${General::swroot}/ca/cacert.pem" ? '' : ""; - print < -
-
- - $createCA - +; + } + my $createCA = -f "${General::swroot}/ca/cacert.pem" ? '' : ""; + print < +
+ +
+ $createCA + - - + + - -
$Lang::tr{'ca name'}: *
$Lang::tr{'resetting the vpn configuration will remove the root ca, the host certificate and all certificate based connections'}:
-
+ + + END - ; - &Header::closebox(); - &Header::closebigbox(); - &Header::closepage(); +; + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); sub array_unique($) { my $array = shift; @@ -3132,3 +3118,16 @@ sub make_algos($$$$$) { return &array_unique(\@algos); } + +sub make_subnets($) { + my $subnets = shift; + + my @nets = split(/\|/, $subnets); + my @cidr_nets = (); + foreach my $net (@nets) { + my $cidr_net = &General::ipcidr($net); + push(@cidr_nets, $cidr_net); + } + + return join(",", @cidr_nets); +} diff --git a/langs/de/cgi-bin/de.pl b/langs/de/cgi-bin/de.pl index c21bac54a..a3c8228ad 100644 --- a/langs/de/cgi-bin/de.pl +++ b/langs/de/cgi-bin/de.pl @@ -2620,7 +2620,6 @@ 'vpn statistic n2n' => 'OpenVPN-Netz-zu-Netz-Statistik', 'vpn statistic rw' => 'OpenVPN-Roadwarrior-Statistik', 'vpn subjectaltname' => 'Subjekt Alternativer Name', -'vpn vhost' => 'Roadwarrior virtuelle IP (manchmal auch Inner-IP genannt)', 'vpn watch' => 'Netz-zu-Netz VPN neu starten, wenn sich Remote-IP ändert (DynDNS).', 'waiting to synchronize clock' => 'Bitte warten, die Uhr wird synchronisiert', 'warn when traffic reaches' => 'Warnen wenn Traffic x % erreicht', diff --git a/langs/en/cgi-bin/en.pl b/langs/en/cgi-bin/en.pl index 783fd0f52..55cf22802 100644 --- a/langs/en/cgi-bin/en.pl +++ b/langs/en/cgi-bin/en.pl @@ -2664,7 +2664,6 @@ 'vpn statistic n2n' => 'OpenVPN Net-to-Net Statistics', 'vpn statistic rw' => 'OpenVPN Roadwarrior Statistics', 'vpn subjectaltname' => 'Subject Alt Name', -'vpn vhost' => 'Roadwarrior virtual IP (sometimes called Inner-IP)', 'vpn watch' => 'Restart net-to-net vpn when remote peer IP changes (dyndns).', 'waiting to synchronize clock' => 'Waiting to synchronize clock', 'warn when traffic reaches' => 'Warn when traffic reaches x %', diff --git a/langs/es/cgi-bin/es.pl b/langs/es/cgi-bin/es.pl index c0422b1fe..e24e75e56 100644 --- a/langs/es/cgi-bin/es.pl +++ b/langs/es/cgi-bin/es.pl @@ -2107,7 +2107,6 @@ 'vpn red name' => 'Dirección IP pública o FQDN para la interfaz RED o<%defaultroute>', 'vpn remote id' => 'ID Remoto', 'vpn subjectaltname' => 'Nombre alternativo en Asunto', -'vpn vhost' => 'IP virtual Roadwarris (también referida como ip-interior)', 'vpn watch' => 'Reinciar vpn net-to-net cuando la ip remota cambie (dyndns)', 'waiting to synchronize clock' => 'Esperando sincronización con el reloj', 'warn when traffic reaches' => 'Advertir cuando el tráfico alcance x %', diff --git a/langs/fr/cgi-bin/fr.pl b/langs/fr/cgi-bin/fr.pl index 43e69a7e2..0d173aef3 100644 --- a/langs/fr/cgi-bin/fr.pl +++ b/langs/fr/cgi-bin/fr.pl @@ -2111,7 +2111,6 @@ 'vpn red name' => 'IP publique ou nom de domaine complet pour l\'interface ROUGE ou <%defaultroute>', 'vpn remote id' => 'ID Distant', 'vpn subjectaltname' => 'Subject Alt Name', -'vpn vhost' => 'IP Virtuelle Roadwarrior (parfois appelée Inner-IP)', 'vpn watch' => 'Redémarrer net-to-net VPN si IP hôte distant change (dyndns).', 'waiting to synchronize clock' => 'Attendre la synchronisation de l\'horloge', 'warn when traffic reaches' => 'Avertir lorsque le trafic atteint x %', diff --git a/langs/it/cgi-bin/it.pl b/langs/it/cgi-bin/it.pl index 0623bd5ab..950f70026 100644 --- a/langs/it/cgi-bin/it.pl +++ b/langs/it/cgi-bin/it.pl @@ -2586,7 +2586,6 @@ 'vpn red name' => 'IP pubblico o il nome di dominio completo per l\'interfaccia RED o <%defaultroute>', 'vpn remote id' => 'Remote ID', 'vpn subjectaltname' => 'Subject Alt Name', -'vpn vhost' => 'Roadwarrior virtual IP (sometimes called Inner-IP)', 'vpn watch' => 'Restart net-to-net vpn when remote peer IP changes (dyndns).', 'waiting to synchronize clock' => 'Waiting to synchronize clock', 'warn when traffic reaches' => 'Warn when traffic reaches x %', diff --git a/langs/nl/cgi-bin/nl.pl b/langs/nl/cgi-bin/nl.pl index f748b74cb..9d90a0815 100644 --- a/langs/nl/cgi-bin/nl.pl +++ b/langs/nl/cgi-bin/nl.pl @@ -2529,7 +2529,6 @@ 'vpn red name' => 'Publiek IP of FQDN voor RODE interface of <%defaultroute>', 'vpn remote id' => 'Remote ID', 'vpn subjectaltname' => 'Onderwerp Alt Naam', -'vpn vhost' => 'Roadwarrior virtual IP (Ook wel Inner-IP genoemd)', 'vpn watch' => 'Herstart net-to-net vpn wanneer remote peer IP verandert (dyndns).', 'waiting to synchronize clock' => 'Wachten op synchronisatie van klok', 'warn when traffic reaches' => 'Waarschuw wanneer verkeer x % bereikt', diff --git a/langs/pl/cgi-bin/pl.pl b/langs/pl/cgi-bin/pl.pl index 30cc81edb..47abf2c5f 100644 --- a/langs/pl/cgi-bin/pl.pl +++ b/langs/pl/cgi-bin/pl.pl @@ -2120,7 +2120,6 @@ 'vpn red name' => 'Publiczne IP lub FQDN interfejsu RED lub <%defaultroute>', 'vpn remote id' => 'Zdalne ID', 'vpn subjectaltname' => 'Subject Alt Name', -'vpn vhost' => 'Roadwarrior virtual IP (sometimes called Inner-IP)', 'vpn watch' => 'Uruchom ponownie vpn net-to-net kiedy zmieni się IP zdalnej końcówki (dyndns).', 'waiting to synchronize clock' => 'Oczekiwanie na synchronizację zegara', 'warn when traffic reaches' => 'Ostrzegaj kiedy ruch osiągnie x %', diff --git a/langs/ru/cgi-bin/ru.pl b/langs/ru/cgi-bin/ru.pl index 8cf985bd3..6840f8120 100644 --- a/langs/ru/cgi-bin/ru.pl +++ b/langs/ru/cgi-bin/ru.pl @@ -2115,7 +2115,6 @@ 'vpn red name' => 'Внешний IP или FQDN для RED интерфейса или <%defaultroute>', 'vpn remote id' => 'Удалённый ID', 'vpn subjectaltname' => 'Subject Alt Name', -'vpn vhost' => 'Roadwarrior virtual IP (sometimes called Inner-IP)', 'vpn watch' => 'Перезапускать net-to-net vpn когда удалённый IP меняется (dyndns).', 'waiting to synchronize clock' => 'Ожидается синхронизация', 'warn when traffic reaches' => 'Предупреждать когда трафик возрастает до x %', diff --git a/langs/tr/cgi-bin/tr.pl b/langs/tr/cgi-bin/tr.pl index 5426a063b..782bc007e 100644 --- a/langs/tr/cgi-bin/tr.pl +++ b/langs/tr/cgi-bin/tr.pl @@ -2609,7 +2609,6 @@ 'vpn red name' => 'KIRMIZI arabirim veya <%defaultroute> için gerçek IP veya FQDN', 'vpn remote id' => 'Uzak kimlik (ID)', 'vpn subjectaltname' => 'Alternatif konu adı', -'vpn vhost' => 'Roadwarrior sanal IP (bazen iç IP olarakta adlandırılır)', 'vpn watch' => 'Karşı eş IP değiştirdiğinde (dyndns) ağdan-ağa VPN bağlantısını yeniden başlat. Bu DPD ye yardımcı olur.', 'waiting to synchronize clock' => 'Saat eşleştirmesi bekleniyor', 'warn when traffic reaches' => 'Trafik x % değere ulaştığında uyar', diff --git a/lfs/initscripts b/lfs/initscripts index 400594136..141fd66d8 100755 --- a/lfs/initscripts +++ b/lfs/initscripts @@ -177,7 +177,6 @@ $(TARGET) : ln -sf ../init.d/localnet /etc/rc.d/rcsysinit.d/S80localnet ln -sf ../init.d/firewall /etc/rc.d/rcsysinit.d/S85firewall ln -sf ../init.d/network-trigger /etc/rc.d/rcsysinit.d/S90network-trigger - ln -sf ../init.d/network-vlans /etc/rc.d/rcsysinit.d/S91network-vlans ln -sf ../init.d/rngd /etc/rc.d/rcsysinit.d/S92rngd ln -sf ../init.d/wlanclient /etc/rc.d/rc0.d/K82wlanclient ln -sf ../init.d/wlanclient /etc/rc.d/rc3.d/S19wlanclient diff --git a/lfs/udev b/lfs/udev index e58839c40..7d5bdbca1 100644 --- a/lfs/udev +++ b/lfs/udev @@ -107,6 +107,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) # Install network rules. install -v -m 755 $(DIR_SRC)/config/udev/network-hotplug-rename \ /lib/udev/network-hotplug-rename + install -v -m 755 $(DIR_SRC)/config/udev/network-hotplug-vlan \ + /lib/udev/network-hotplug-vlan install -v -m 644 $(DIR_SRC)/config/udev/60-net.rules \ /lib/udev/rules.d diff --git a/make.sh b/make.sh index 90d49ace1..ed902c9cc 100755 --- a/make.sh +++ b/make.sh @@ -25,7 +25,7 @@ NAME="IPFire" # Software name SNAME="ipfire" # Short name VERSION="2.17" # Version number -CORE="94" # Core Level (Filename) +CORE="95" # Core Level (Filename) PAKFIRE_CORE="94" # Core Level (PAKFIRE) GIT_BRANCH=`git rev-parse --abbrev-ref HEAD` # Git Branch SLOGAN="www.ipfire.org" # Software slogan