From: ms Date: Sun, 11 Feb 2007 12:10:37 +0000 (+0000) Subject: IPSec update... X-Git-Tag: v2.3-beta1~847 X-Git-Url: http://git.ipfire.org/?p=people%2Fpmueller%2Fipfire-2.x.git;a=commitdiff_plain;h=ed84e8b81a358bafddaacc3430b76ae868ca9080 IPSec update... Dial.cgi bearbeitet/fix... git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@408 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8 --- diff --git a/html/cgi-bin/dial.cgi b/html/cgi-bin/dial.cgi index a3690973e5..8ca13846ba 100644 --- a/html/cgi-bin/dial.cgi +++ b/html/cgi-bin/dial.cgi @@ -60,10 +60,10 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'dial profile'}) } if ($cgiparams{'ACTION'} eq $Lang::tr{'dial'}) { - system('/etc/rc.d/rc.red','start') == 0 + system('/etc/rc.d/init.d/red','start') == 0 or &General::log("Dial failed: $?"); } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'hangup'}) { - system('/etc/rc.d/rc.red','stop') == 0 + system('/etc/rc.d/init.d/red','stop') == 0 or &General::log("Hangup failed: $?"); } sleep 1; diff --git a/html/cgi-bin/vpnmain.cgi b/html/cgi-bin/vpnmain.cgi index 364036d5ee..794bf7e1be 100644 --- a/html/cgi-bin/vpnmain.cgi +++ b/html/cgi-bin/vpnmain.cgi @@ -1,24 +1,24 @@ #!/usr/bin/perl # -# This file is part of the IPFire Firewall. +# This file is part of the IPCop Firewall. # -# IPFire is free software; you can redistribute it and/or modify +# IPCop 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 2 of the License, or # (at your option) any later version. # -# IPFire is distributed in the hope that it will be useful, +# IPCop 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 +# along with IPCop; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Copyright (C) 2003-05-25 Mark Wormgoor # -# $Id: vpnmain.cgi,v 1.10.2.69 2006/01/31 02:07:19 franck78 Exp $ +# $Id: vpnmain.cgi,v 1.10.2.104 2006/11/30 12:43:10 franck78 Exp $ # use Net::DNS; @@ -33,34 +33,33 @@ use strict; require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; - require "${General::swroot}/countries.pl"; #workaround to suppress a warning when a variable is used only once -my @dummy = ( ${Header::colourgreen} ); +my @dummy = ( ${Header::colourgreen}, ${Header::colourblue} ); undef (@dummy); ### ### Initialize variables ### -my $sleepDelay = '4s'; # after a call to ipsecctrl S or R, wait this delay (seconds) before reading status +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=(); -my %cgiparams=(); -my %vpnsettings=(); +our %cgiparams=(); +our %vpnsettings=(); my %checked=(); my %confighash=(); my %cahash=(); my %selected=(); my $warnmessage = ''; my $errormessage = ''; + &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); $cgiparams{'ENABLED'} = 'off'; +$cgiparams{'ENABLED_GREEN'} = 'off'; +$cgiparams{'ENABLED_ORANGE'} = 'off'; $cgiparams{'ENABLED_BLUE'} = 'off'; $cgiparams{'EDIT_ADVANCED'} = 'off'; -$cgiparams{'NAT'} = 'off'; -$cgiparams{'COMPRESSION'} = 'off'; -$cgiparams{'ONLY_PROPOSED'} = 'off'; $cgiparams{'ACTION'} = ''; $cgiparams{'CA_NAME'} = ''; $cgiparams{'DBG_CRYPT'} = ''; @@ -70,6 +69,37 @@ $cgiparams{'DBG_CONTROL'} = ''; $cgiparams{'DBG_KLIPS'} = ''; $cgiparams{'DBG_DNS'} = ''; $cgiparams{'DBG_NAT_T'} = ''; +$cgiparams{'KEY'} = ''; +$cgiparams{'TYPE'} = ''; +$cgiparams{'ADVANCED'} = ''; +$cgiparams{'INTERFACE'} = ''; +$cgiparams{'NAME'} = ''; +$cgiparams{'LOCAL_SUBNET'} = ''; +$cgiparams{'REMOTE_SUBNET'} = ''; +$cgiparams{'REMOTE'} = ''; +$cgiparams{'LOCAL_ID'} = ''; +$cgiparams{'REMOTE_ID'} = ''; +$cgiparams{'REMARK'} = ''; +$cgiparams{'PSK'} = ''; +$cgiparams{'CERT_NAME'} = ''; +$cgiparams{'CERT_EMAIL'} = ''; +$cgiparams{'CERT_OU'} = ''; +$cgiparams{'CERT_ORGANIZATION'} = ''; +$cgiparams{'CERT_CITY'} = ''; +$cgiparams{'CERT_STATE'} = ''; +$cgiparams{'CERT_COUNTRY'} = ''; +$cgiparams{'SUBJECTALTNAME'} = ''; +$cgiparams{'CERT_PASS1'} = ''; +$cgiparams{'CERT_PASS2'} = ''; +$cgiparams{'ROOTCERT_HOSTNAME'} = ''; +$cgiparams{'ROOTCERT_COUNTRY'} = ''; +$cgiparams{'P12_PASS'} = ''; +$cgiparams{'ROOTCERT_ORGANIZATION'} = ''; +$cgiparams{'ROOTCERT_HOSTNAME'} = ''; +$cgiparams{'ROOTCERT_EMAIL'} = ''; +$cgiparams{'ROOTCERT_OU'} = ''; +$cgiparams{'ROOTCERT_CITY'} = ''; +$cgiparams{'ROOTCERT_STATE'} = ''; &Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'}); @@ -90,11 +120,19 @@ sub valid_dns_host { return $res->errorstring; } } - -# -# old version: maintain serial number to one, without explication. -# this : let the counter go, so that each cert is numbered. -# +### +### Just return true is one interface is vpn enabled +### +sub vpnenabled { + return ($vpnsettings{'ENABLED'} eq 'on' || + $vpnsettings{'ENABLED_GREEN'} eq 'on' || + $vpnsettings{'ENABLED_ORANGE'} eq 'on' || + $vpnsettings{'ENABLED_BLUE'} eq 'on'); +} +### +### 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")) { @@ -123,7 +161,81 @@ sub newcleanssldatabase 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" : '' ; +} +### +### 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; +} +### +### 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; +} +### +### 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; + + $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 +### +###Type=Net : GUI can choose to be left or right. This serve nothing in the conf! +### interface is fixed to RED only. No special reason for this also. +### + sub writeipsecfiles { my %lconfighash = (); my %lvpnsettings = (); @@ -136,28 +248,26 @@ sub writeipsecfiles { flock SECRETS, 2; print CONF "version 2\n\n"; print CONF "config setup\n"; - if ($lvpnsettings{'ENABLED_BLUE'} eq 'on') - { - if ($lvpnsettings{'ENABLED'} eq 'on') - { - print CONF "\tinterfaces=\"%defaultroute ipsec1=$netsettings{'BLUE_DEV'}\"\n"; - } else { - print CONF "\tinterfaces=ipsec0=$netsettings{'BLUE_DEV'}\n"; - } - } else { - print CONF "\tinterfaces=%defaultroute\n"; - } - + #create an ipsec Interface for each 'enabled' ones + my $interfaces = "\tinterfaces=\""; + $interfaces .= "%defaultroute " if ($lvpnsettings{'ENABLED'} eq 'on'); + $interfaces .= "ipsec1=$netsettings{'GREEN_DEV'} " if ($lvpnsettings{'ENABLED_GREEN'} eq 'on'); + $interfaces .= "ipsec2=$netsettings{'BLUE_DEV'} " if ($lvpnsettings{'ENABLED_BLUE'} eq 'on'); + $interfaces .= "ipsec3=$netsettings{'ORANGE_DEV'} " if ($lvpnsettings{'ENABLED_ORANGE'} eq 'on'); + print CONF $interfaces . "\"\n"; + my $plutodebug = ''; # build debug list map ($plutodebug .= $lvpnsettings{$_} eq 'on' ? lc (substr($_,4)).' ' : '', ('DBG_CRYPT','DBG_PARSING','DBG_EMITTING','DBG_CONTROL', 'DBG_KLIPS','DBG_DNS','DBG_NAT_T')); $plutodebug = 'none' if $plutodebug eq ''; # if nothing selected, use 'none'. - print CONF "\tklipsdebug=none\n"; + print CONF "\tklipsdebug=\"none\"\n"; print CONF "\tplutodebug=\"$plutodebug\"\n"; # deprecated in ipsec.conf version 2 #print CONF "\tplutoload=%search\n"; #print CONF "\tplutostart=%search\n"; + print CONF "\tplutoload=%search\n"; + print CONF "\tplutostart=%search\n"; print CONF "\tuniqueids=yes\n"; print CONF "\tnat_traversal=yes\n"; print CONF "\toverridemtu=$lvpnsettings{'VPN_OVERRIDE_MTU'}\n" if ($lvpnsettings{'VPN_OVERRIDE_MTU'} ne ''); @@ -183,163 +293,154 @@ sub writeipsecfiles { 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) { - if ($lconfighash{$key}[0] eq 'on') { - if ($lconfighash{$key}[10] eq '') { $lconfighash{$key}[10] = '%any'; } - - print CONF "conn $lconfighash{$key}[1]\n"; - #always choose LEFT localside for roadwarrior - if ($lconfighash{$key}[3] eq 'host' || $lconfighash{$key}[6] eq 'left') { - if ($lconfighash{$key}[26] eq 'BLUE') - { - print CONF "\tleft=$netsettings{'BLUE_ADDRESS'}\n"; -# print CONF "\tleftnexthop=$netsettings{'BLUE_NETADDRESS'}\n"; - } - elsif ($lconfighash{$key}[26] eq 'ORANGE') - { - print CONF "\tleft=$netsettings{'ORANGE_ADDRESS'}\n"; - } - elsif ($lconfighash{$key}[26] eq 'GREEN') - { - print CONF "\tleft=$netsettings{'GREEN_ADDRESS'}\n"; - } - elsif ($lconfighash{$key}[26] eq 'RED') - { - print CONF "\tleft=$lvpnsettings{'VPN_IP'}\n"; - print CONF "\tleftnexthop=%defaultroute\n" if ($lvpnsettings{'VPN_IP'} ne '%defaultroute'); - } - print CONF "\tleftsubnet=$lconfighash{$key}[8]\n"; - print CONF "\tright=$lconfighash{$key}[10]\n"; - if ($lconfighash{$key}[3] eq 'net') { - print CONF "\trightsubnet=$lconfighash{$key}[11]\n"; - print CONF "\trightnexthop=%defaultroute\n"; - } elsif ($lconfighash{$key}[10] eq '%any' && $lconfighash{$key}[14] eq 'on') { - print CONF "\trightsubnet=vhost:%no,%priv\n"; - } - 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"; - } - } else { - print CONF "\tright=$lvpnsettings{'VPN_IP'}\n"; - print CONF "\trightsubnet=$lconfighash{$key}[8]\n"; - print CONF "\trightnexthop=%defaultroute\n" if ($lvpnsettings{'VPN_IP'} ne '%defaultroute'); - print CONF "\tleft=$lconfighash{$key}[10]\n"; - if ($lconfighash{$key}[3] eq 'net') { - print CONF "\tleftsubnet=$lconfighash{$key}[11]\n"; - print CONF "\tleftnexthop=%defaultroute\n"; - } - if ($lconfighash{$key}[4] eq 'cert') { - print CONF "\trightcert=${General::swroot}/certs/hostcert.pem\n"; - print CONF "\tleftcert=${General::swroot}/certs/$lconfighash{$key}[1]cert.pem\n"; - } - } - print CONF "\tleftid=$lconfighash{$key}[7]\n" if ($lconfighash{$key}[7]); - print CONF "\trightid=$lconfighash{$key}[9]\n" if ($lconfighash{$key}[9]); - - # Algorithms - if ($lconfighash{$key}[18] && $lconfighash{$key}[19] && $lconfighash{$key}[20]) { - print CONF "\tike="; - my @encs = split('\|', $lconfighash{$key}[18]); - my @ints = split('\|', $lconfighash{$key}[19]); - my @groups = split('\|', $lconfighash{$key}[20]); - my $comma = 0; - foreach my $i (@encs) { - foreach my $j (@ints) { - foreach my $k (@groups) { - if ($comma != 0) { print CONF ","; } else { $comma = 1; } - print CONF "$i-$j-modp$k"; - } - } - } - if ($lconfighash{$key}[24] eq 'on') { - print CONF "!\n"; - } else { - print CONF "\n"; - } - } - if ($lconfighash{$key}[21] && $lconfighash{$key}[22]) { - print CONF "\tesp="; - my @encs = split('\|', $lconfighash{$key}[21]); - my @ints = split('\|', $lconfighash{$key}[22]); - my $comma = 0; - foreach my $i (@encs) { - foreach my $j (@ints) { - if ($comma != 0) { print CONF ","; } else { $comma = 1; } - print CONF "$i-$j"; - } - } - if ($lconfighash{$key}[24] eq 'on') { - print CONF "!\n"; - } else { - print CONF "\n"; - } - } - if ($lconfighash{$key}[23]) { - print CONF "\tpfsgroup=$lconfighash{$key}[23]\n"; - } + next if ($lconfighash{$key}[0] ne 'on'); - # Lifetimes - if ($lconfighash{$key}[16]) { - print CONF "\tikelifetime=$lconfighash{$key}[16]h\n"; - } - if ($lconfighash{$key}[17]) { - print CONF "\tkeylife=$lconfighash{$key}[17]h\n"; - } + #remote peer is not set? => use '%any' + $lconfighash{$key}[10] = '%any' if ($lconfighash{$key}[10] eq ''); - # Compression - if ($lconfighash{$key}[13] eq 'on') { - print CONF "\tcompress=yes\n"; - } + my ($L,$R); #Local & Remote sides - # Dead Peer Detection - print CONF "\tdpddelay=30\n"; - print CONF "\tdpdtimeout=120\n"; - print CONF "\tdpdaction=$lconfighash{$key}[27]\n"; - - # Disable pfs ? - print CONF "\tpfs=$lconfighash{$key}[28]\n"; - - # Print Authentication details - if ($lconfighash{$key}[4] eq 'psk') { - if ($lconfighash{$key}[6] eq 'left'){ - if ($lconfighash{$key}[26] eq 'BLUE') { - print SECRETS ($lconfighash{$key}[7] ? $lconfighash{$key}[7] : $netsettings{'BLUE_ADDRESS'}) . " "; - print SECRETS $lconfighash{$key}[9] ? $lconfighash{$key}[9] : $lconfighash{$key}[10]; - print SECRETS " : PSK \"$lconfighash{$key}[5]\"\n"; - } else { - print SECRETS ($lconfighash{$key}[7] ? $lconfighash{$key}[7] : $lvpnsettings{'VPN_IP'}) . " "; - print SECRETS $lconfighash{$key}[9] ? $lconfighash{$key}[9] : $lconfighash{$key}[10]; - print SECRETS " : PSK \"$lconfighash{$key}[5]\"\n"; - } - } else { - if ($lconfighash{$key}[26] eq 'BLUE') { - print SECRETS ($lconfighash{$key}[9] ? $lconfighash{$key}[9] : $netsettings{'BLUE_ADDRESS'}) . " "; - print SECRETS $lconfighash{$key}[7] ? $lconfighash{$key}[7] : $lconfighash{$key}[10]; - print SECRETS " : PSK \"$lconfighash{$key}[5]\"\n"; - } else { - print SECRETS ($lconfighash{$key}[9] ? $lconfighash{$key}[9] : $lvpnsettings{'VPN_IP'}) . " "; - print SECRETS $lconfighash{$key}[7] ? $lconfighash{$key}[7] : $lconfighash{$key}[10]; - print SECRETS " : PSK \"$lconfighash{$key}[5]\"\n"; - } - } + print CONF "conn $lconfighash{$key}[1]\n"; + #always choose LEFT localside for roadwarrior + if ($lconfighash{$key}[3] eq 'host' || $lconfighash{$key}[6] eq 'left') { + $L = 'left'; + $R = 'right'; + } else { + $R = 'left'; + $L = 'right'; + } + print CONF "\t${L}="; + if ($lconfighash{$key}[26] eq 'BLUE') { + print CONF "$netsettings{'BLUE_ADDRESS'}\n"; + } elsif ($lconfighash{$key}[26] eq 'ORANGE') { + print CONF "$netsettings{'ORANGE_ADDRESS'}\n"; + } elsif ($lconfighash{$key}[26] eq 'GREEN') { + print CONF "$netsettings{'GREEN_ADDRESS'}\n"; + } elsif ($lconfighash{$key}[26] eq 'RED') { + print CONF "$lvpnsettings{'VPN_IP'}\n"; + print CONF "\t${L}nexthop=%defaultroute\n" if ($lvpnsettings{'VPN_IP'} ne '%defaultroute'); + } + print CONF "\t${L}subnet=$lconfighash{$key}[8]\n"; + print CONF "\t${R}=$lconfighash{$key}[10]\n"; - print CONF "\tauthby=secret\n"; + if ($lconfighash{$key}[3] eq 'net') { + print CONF "\t${R}subnet=$lconfighash{$key}[11]\n"; + print CONF "\t${R}nexthop=%defaultroute\n"; + } elsif ($lconfighash{$key}[10] eq '%any' && $lconfighash{$key}[14] eq 'on') { #vhost allowed? + 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 "\t${L}cert=${General::swroot}/certs/hostcert.pem\n"; + print CONF "\t${R}cert=${General::swroot}/certs/$lconfighash{$key}[1]cert.pem\n" if ($lconfighash{$key}[2] ne '%auth-dn'); + } + + # Local and Remote IDs + print CONF "\t${L}id=\"$lconfighash{$key}[7]\"\n" if ($lconfighash{$key}[7]); + print CONF "\t${R}id=\"$lconfighash{$key}[9]\"\n" if ($lconfighash{$key}[9]); + + # Algorithms + if ($lconfighash{$key}[18] && $lconfighash{$key}[19] && $lconfighash{$key}[20]) { + print CONF "\tike="; + my @encs = split('\|', $lconfighash{$key}[18]); + my @ints = split('\|', $lconfighash{$key}[19]); + my @groups = split('\|', $lconfighash{$key}[20]); + my $comma = 0; + foreach my $i (@encs) { + foreach my $j (@ints) { + foreach my $k (@groups) { + if ($comma != 0) { print CONF ","; } else { $comma = 1; } + print CONF "$i-$j-modp$k"; + } + } + } + if ($lconfighash{$key}[24] eq 'on') { #only proposed algorythms? + print CONF "!\n"; } else { - print CONF "\tauthby=rsasig\n"; + print CONF "\n"; + } + } + if ($lconfighash{$key}[21] && $lconfighash{$key}[22]) { + print CONF "\tesp="; + my @encs = split('\|', $lconfighash{$key}[21]); + my @ints = split('\|', $lconfighash{$key}[22]); + my $comma = 0; + foreach my $i (@encs) { + foreach my $j (@ints) { + if ($comma != 0) { print CONF ","; } else { $comma = 1; } + print CONF "$i-$j"; + } } - - # Automatically start only if a net-to-net connection - if ($lconfighash{$key}[3] eq 'host') { - print CONF "\tauto=add\n"; + if ($lconfighash{$key}[24] eq 'on') { #only proposed algorythms? + print CONF "!\n"; + } else { + print CONF "\n"; + } + } + if ($lconfighash{$key}[23]) { + print CONF "\tpfsgroup=$lconfighash{$key}[23]\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]); + + # Aggresive mode + print CONF "\taggrmode=yes\n" if ($lconfighash{$key}[12] eq 'on'); + + # Compression + print CONF "\tcompress=yes\n" if ($lconfighash{$key}[13] eq 'on'); + + # Dead Peer Detection + print CONF "\tdpddelay=30\n"; + print CONF "\tdpdtimeout=120\n"; + print CONF "\tdpdaction=$lconfighash{$key}[27]\n"; + + # Disable pfs ? + print CONF "\tpfs=". ($lconfighash{$key}[28] eq 'on' ? "yes\n" : "no\n"); + + # Build Authentication details: LEFTid RIGHTid : PSK psk + my $psk_line; + if ($lconfighash{$key}[4] eq 'psk') { + 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'}; + } + $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 CONF "\tauto=start\n"; + print SECRETS $psk_line; } - print CONF "\n"; - }#on - }#foreach key + 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"; + } else { + print CONF "\tauto=start\n"; + } + print CONF "\n"; + }#foreach key + print SECRETS $last_secrets if ($last_secrets); close(CONF); close(SECRETS); } @@ -365,17 +466,22 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg goto SAVE_ERROR; } + unless ($cgiparams{'VPN_WATCH'} =~ /^(|off|on)$/ ) { + $errormessage = $Lang::tr{'invalid input'}; + goto SAVE_ERROR; + } + map ($vpnsettings{$_} = $cgiparams{$_}, - ('ENABLED','ENABLED_BLUE','DBG_CRYPT','DBG_PARSING','DBG_EMITTING','DBG_CONTROL', + ('ENABLED','ENABLED_GREEN','ENABLED_ORANGE','ENABLED_BLUE','DBG_CRYPT','DBG_PARSING','DBG_EMITTING','DBG_CONTROL', 'DBG_KLIPS','DBG_DNS','DBG_NAT_T')); $vpnsettings{'VPN_IP'} = $cgiparams{'VPN_IP'}; $vpnsettings{'VPN_DELAYED_START'} = $cgiparams{'VPN_DELAYED_START'}; $vpnsettings{'VPN_OVERRIDE_MTU'} = $cgiparams{'VPN_OVERRIDE_MTU'}; + $vpnsettings{'VPN_WATCH'} = $cgiparams{'VPN_WATCH'}; &General::writehash("${General::swroot}/vpn/settings", \%vpnsettings); &writeipsecfiles(); - if ($vpnsettings{'ENABLED'} eq 'on' || - $vpnsettings{'ENABLED_BLUE'} eq 'on') { + if (&vpnenabled) { system('/usr/local/bin/ipsecctrl', 'S'); } else { system('/usr/local/bin/ipsecctrl', 'D'); @@ -385,8 +491,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg ### ### Reset all step 2 ### -} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'reset'} && $cgiparams{'AREUSURE'} eq 'yes') { - my $file = ''; +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove x509'} && $cgiparams{'AREUSURE'} eq 'yes') { &General::readhasharray("${General::swroot}/vpn/config", \%confighash); foreach my $key (keys %confighash) { @@ -394,7 +499,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg delete $confighash{$key}; } } - while ($file = glob("${General::swroot}/{ca,certs,crls,private}/*")) { + while (my $file = glob("${General::swroot}/{ca,certs,crls,private}/*")) { unlink $file } &cleanssldatabase(); @@ -410,19 +515,26 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg ### ### Reset all step 1 ### -} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'reset'}) { +} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove x509'}) { &Header::showhttpheaders(); &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); - &Header::openbigbox('100%', 'LEFT', '', ''); - &Header::openbox('100%', 'LEFT', $Lang::tr{'are you sure'}); + &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(); @@ -483,16 +595,9 @@ END } } - my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ca/$cgiparams{'CA_NAME'}cert.pem`; - $casubject =~ /Subject: (.*)[\n]/; - $casubject = $1; - $casubject =~ s+/Email+, E+; - $casubject =~ s/ ST=/ S=/; - $casubject = &Header::cleanhtml($casubject); - my $key = &General::findhasharraykey (\%cahash); $cahash{$key}[0] = $cgiparams{'CA_NAME'}; - $cahash{$key}[1] = $casubject; + $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; @@ -508,8 +613,8 @@ END if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem") { &Header::showhttpheaders(); &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); - &Header::openbigbox('100%', 'LEFT', '', ''); - &Header::openbox('100%', 'LEFT', "$Lang::tr{'ca certificate'}:"); + &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"; @@ -523,14 +628,15 @@ END } ### -### Download ca certificate +### Export ca certificate to browser ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download ca certificate'}) { &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: filename=$cahash{$cgiparams{'KEY'}}[0]cert.pem\r\n\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 { @@ -549,10 +655,7 @@ END 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 - if ($vpnsettings{'ENABLED'} eq 'on' || - $vpnsettings{'ENABLED_BLUE'} eq 'on') { - system('/usr/local/bin/ipsecctrl', 'D', $key); - } + 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}; @@ -586,17 +689,26 @@ END if ($assignedcerts) { &Header::showhttpheaders(); &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); - &Header::openbigbox('100%', 'LEFT', '', ''); - &Header::openbox('100%', 'LEFT', $Lang::tr{'are you sure'}); + &Header::openbigbox('100%', 'left', '', ''); + &Header::openbox('100%', 'left', $Lang::tr{'are you sure'}); print <
- - - $Lang::tr{'capswarning'}: $assignedcerts - $Lang::tr{'connections are associated with this ca. deleting the ca will delete these connections as well.'} - - -
+
+ + + + + + + + +
+ +
+ $Lang::tr{'capswarning'} + $Lang::tr{'connections are associated with this ca. deleting the ca will delete these connections as well.'}
+ +
+
END ; &Header::closebox(); @@ -622,12 +734,12 @@ END my $output; &Header::showhttpheaders(); &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); - &Header::openbigbox('100%', 'LEFT', '', ''); + &Header::openbigbox('100%', 'left', '', ''); if ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'}) { - &Header::openbox('100%', 'LEFT', "$Lang::tr{'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'}:"); + &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"); @@ -639,40 +751,40 @@ END exit(0); ### -### Download root certificate +### 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/octet-stream\r\n"; - print "Content-Disposition: filename=cacert.pem\r\n\r\n"; + 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); } ### -### Download host certificate +### 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/octet-stream\r\n"; - print "Content-Disposition: filename=hostcert.pem\r\n\r\n"; + 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 a root certificate +### 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'}) { - &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); if (-f "${General::swroot}/ca/cacert.pem") { $errormessage = $Lang::tr{'valid root certificate already exists'}; - $cgiparams{'ACTION'} = ''; - goto ROOTCERT_ERROR; + goto ROOTCERT_SKIP; } - if (($cgiparams{'ROOTCERT_HOSTNAME'} eq '') && -e "${General::swroot}/red/active") { - if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) { + &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); @@ -681,7 +793,9 @@ END $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'}; @@ -695,124 +809,82 @@ END goto ROOTCERT_ERROR; } - # Create a temporary dirctory - my $tempdir = tempdir( CLEANUP => 1 ); - # Extract the CA certificate from the file - my $pid = open(OPENSSL, "|-"); - $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; - if ($pid) { # parent - if ($cgiparams{'P12_PASS'} ne '') { - print OPENSSL "$cgiparams{'P12_PASS'}\n"; - } - close (OPENSSL); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - unlink ($filename); - goto ROOTCERT_ERROR; - } - } else { # child - unless (exec ('/usr/bin/openssl', 'pkcs12', '-cacerts', '-nokeys', - '-in', $filename, - '-out', "$tempdir/cacert.pem")) { - $errormessage = "$Lang::tr{'cant start openssl'}: $!"; - unlink ($filename); - goto ROOTCERT_ERROR; - } + &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 - $pid = open(OPENSSL, "|-"); - $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; - if ($pid) { # parent - if ($cgiparams{'P12_PASS'} ne '') { - print OPENSSL "$cgiparams{'P12_PASS'}\n"; - } - close (OPENSSL); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - unlink ($filename); - goto ROOTCERT_ERROR; - } - } else { # child - unless (exec ('/usr/bin/openssl', 'pkcs12', '-clcerts', '-nokeys', - '-in', $filename, - '-out', "$tempdir/hostcert.pem")) { - $errormessage = "$Lang::tr{'cant start openssl'}: $!"; - unlink ($filename); - goto ROOTCERT_ERROR; + # 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 - $pid = open(OPENSSL, "|-"); - $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; - if ($pid) { # parent - if ($cgiparams{'P12_PASS'} ne '') { - print OPENSSL "$cgiparams{'P12_PASS'}\n"; - } - close (OPENSSL); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - unlink ($filename); - goto ROOTCERT_ERROR; - } - } else { # child - unless (exec ('/usr/bin/openssl', 'pkcs12', '-nocerts', - '-nodes', - '-in', $filename, - '-out', "$tempdir/hostkey.pem")) { - $errormessage = "$Lang::tr{'cant start openssl'}: $!"; - unlink ($filename); - goto ROOTCERT_ERROR; - } - } - - move("$tempdir/cacert.pem", "${General::swroot}/ca/cacert.pem"); - if ($? ne 0) { - $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; - unlink ($filename); - unlink ("${General::swroot}/ca/cacert.pem"); - unlink ("${General::swroot}/certs/hostcert.pem"); - unlink ("${General::swroot}/certs/hostkey.pem"); - goto ROOTCERT_ERROR; + 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); } - move("$tempdir/hostcert.pem", "${General::swroot}/certs/hostcert.pem"); - if ($? ne 0) { - $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; - unlink ($filename); - unlink ("${General::swroot}/ca/cacert.pem"); - unlink ("${General::swroot}/certs/hostcert.pem"); - unlink ("${General::swroot}/certs/hostkey.pem"); - goto ROOTCERT_ERROR; + 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); } - - move("$tempdir/hostkey.pem", "${General::swroot}/certs/hostkey.pem"); - if ($? ne 0) { - $errormessage = "$Lang::tr{'certificate file move failed'}: $!"; - unlink ($filename); + + #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 an empty CRL - system('/usr/bin/openssl', 'ca', '-gencrl', - '-out', "${General::swroot}/crls/cacrl.pem"); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - unlink ("${General::swroot}/certs/hostkey.pem"); - unlink ("${General::swroot}/certs/hostcert.pem"); - unlink ("${General::swroot}/ca/cacert.pem"); - unlink ("${General::swroot}/crls/cacrl.pem"); - &cleanssldatabase(); - goto ROOTCERT_ERROR; - } else { - &cleanssldatabase(); } + # Create empty CRL cannot be done because we don't have + # the private key for this CAROOT + # Ipcop can only import certificates + + &General::log("ipsec", "p12 import completed!"); + &cleanssldatabase(); goto ROOTCERT_SUCCESS; } elsif ($cgiparams{'ROOTCERT_COUNTRY'} ne '') { @@ -862,6 +934,18 @@ END $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'}; @@ -879,193 +963,176 @@ END (my $state = $cgiparams{'ROOTCERT_STATE'}) =~ s/^\s*$/\./; # Create the CA certificate - my $pid = open(OPENSSL, "|-"); - $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; - if ($pid) { # parent - print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n"; - print OPENSSL "$state\n"; - print OPENSSL "$city\n"; - print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n"; - print OPENSSL "$ou\n"; - print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'} CA\n"; - print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n"; - close (OPENSSL); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - unlink ("${General::swroot}/private/cakey.pem"); - unlink ("${General::swroot}/ca/cacert.pem"); - goto ROOTCERT_ERROR; - } - } else { # child - unless (exec ('/usr/bin/openssl', 'req', '-x509', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache', - '-days', '999999', '-newkey', 'rsa:2048', - '-keyout', "${General::swroot}/private/cakey.pem", - '-out', "${General::swroot}/ca/cacert.pem")) { - $errormessage = "$Lang::tr{'cant start openssl'}: $!"; - goto ROOTCERT_ERROR; + if (!$errormessage) { + &General::log("ipsec", "Creating cacert..."); + if (open(STDIN, "-|")) { + my $opt = " req -x509 -nodes -rand /proc/interrupts:/proc/net/rt_cache"; + $opt .= " -days 999999"; + $opt .= " -newkey rsa:2048"; + $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 - $pid = open(OPENSSL, "|-"); - $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto ROOTCERT_ERROR;}; - if ($pid) { # parent - print OPENSSL "$cgiparams{'ROOTCERT_COUNTRY'}\n"; - print OPENSSL "$state\n"; - print OPENSSL "$city\n"; - print OPENSSL "$cgiparams{'ROOTCERT_ORGANIZATION'}\n"; - print OPENSSL "$ou\n"; - print OPENSSL "$cgiparams{'ROOTCERT_HOSTNAME'}\n"; - print OPENSSL "$cgiparams{'ROOTCERT_EMAIL'}\n"; - print OPENSSL ".\n"; - print OPENSSL ".\n"; - close (OPENSSL); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - unlink ("${General::swroot}/certs/hostkey.pem"); - unlink ("${General::swroot}/certs/hostreq.pem"); - goto ROOTCERT_ERROR; - } - } else { # child - unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache', - '-newkey', 'rsa:1024', - '-keyout', "${General::swroot}/certs/hostkey.pem", - '-out', "${General::swroot}/certs/hostreq.pem")) { - $errormessage = "$Lang::tr{'cant start openssl'}: $!"; - unlink ("${General::swroot}/certs/hostkey.pem"); - unlink ("${General::swroot}/certs/hostreq.pem"); - unlink ("${General::swroot}/private/cakey.pem"); - unlink ("${General::swroot}/ca/cacert.pem"); - goto ROOTCERT_ERROR; + if (!$errormessage) { + &General::log("ipsec", "Creating host cert..."); + if (open(STDIN, "-|")) { + my $opt = " req -nodes -rand /proc/interrupts:/proc/net/rt_cache"; + $opt .= " -newkey rsa:1024"; + $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 - system('/usr/bin/openssl', 'ca', '-days', '999999', - '-batch', '-notext', - '-in', "${General::swroot}/certs/hostreq.pem", - '-out', "${General::swroot}/certs/hostcert.pem"); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - unlink ("${General::swroot}/private/cakey.pem"); - unlink ("${General::swroot}/ca/cacert.pem"); - unlink ("${General::swroot}/certs/hostkey.pem"); - unlink ("${General::swroot}/certs/hostreq.pem"); - unlink ("${General::swroot}/certs/hostcert.pem"); - &cleanssldatabase(); - goto ROOTCERT_ERROR; - } else { - unlink ("${General::swroot}/certs/hostreq.pem"); - &cleanssldatabase(); + 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{'this field may be blank'} - $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{'this field may be blank'}
+ &Header::showhttpheaders(); + &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); + &Header::openbigbox('100%', 'left', '', $errormessage); + if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage"; + print " "; + &Header::closebox(); + } + &Header::openbox('100%', 'left', "$Lang::tr{'generate root/host certificates'}:"); + print < + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
$Lang::tr{'organization name'}:
$Lang::tr{'ipcops 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{'this field may be blank'}
+END + ; + &Header::closebox(); + &Header::closebigbox(); + &Header::closepage(); + exit(0); ROOTCERT_SUCCESS: - if ($vpnsettings{'ENABLED'} eq 'on' || - $vpnsettings{'ENABLE_BLUE'} eq 'on') { + if (&vpnenabled) { system('/usr/local/bin/ipsecctrl', 'S'); sleep $sleepDelay; } + ROOTCERT_SKIP: ### -### Download PKCS12 file +### Export PKCS12 file to browser ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download pkcs12 file'}) { &General::readhasharray("${General::swroot}/vpn/config", \%confighash); - - print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . ".p12\r\n"; + 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); @@ -1079,8 +1146,8 @@ END if ( -f "${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") { &Header::showhttpheaders(); &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); - &Header::openbigbox('100%', 'LEFT', '', ''); - &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate'}:"); + &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"; @@ -1092,14 +1159,14 @@ END } ### -### Download Certificate +### Export Certificate to browser ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download certificate'}) { &General::readhasharray("${General::swroot}/vpn/config", \%confighash); if ( -f "${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") { - print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . "cert.pem\r\n"; - print "Content-Type: application/octet-stream\r\n\r\n"; + print "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); } @@ -1117,20 +1184,14 @@ END $confighash{$cgiparams{'KEY'}}[0] = 'on'; &General::writehasharray("${General::swroot}/vpn/config", \%confighash); &writeipsecfiles(); - if ($vpnsettings{'ENABLED'} eq 'on' || - $vpnsettings{'ENABLED_BLUE'} eq 'on') { - system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}); - sleep $sleepDelay; - } + system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}) if (&vpnenabled); } else { $confighash{$cgiparams{'KEY'}}[0] = 'off'; - if ($vpnsettings{'ENABLED'} eq 'on' || - $vpnsettings{'ENABLED_BLUE'} eq 'on') { - system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'}); - } &General::writehasharray("${General::swroot}/vpn/config", \%confighash); &writeipsecfiles(); + system('/usr/local/bin/ipsecctrl', 'D', $cgiparams{'KEY'}) if (&vpnenabled); } + sleep $sleepDelay; } else { $errormessage = $Lang::tr{'invalid key'}; } @@ -1143,8 +1204,7 @@ END &General::readhasharray("${General::swroot}/vpn/config", \%confighash); if ($confighash{$cgiparams{'KEY'}}) { - if ($vpnsettings{'ENABLED'} eq 'on' || - $vpnsettings{'ENABLED_BLUE'} eq 'on') { + if (&vpnenabled) { system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}); sleep $sleepDelay; } @@ -1160,10 +1220,7 @@ END &General::readhasharray("${General::swroot}/vpn/config", \%confighash); if ($confighash{$cgiparams{'KEY'}}) { - if ($vpnsettings{'ENABLED'} eq 'on' || - $vpnsettings{'ENABLED_BLUE'} eq 'on') { - system('/usr/local/bin/ipsecctrl', 'D', $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'}}; @@ -1177,20 +1234,23 @@ END ### Choose between adding a host-net or net-net connection ### } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'add'} && $cgiparams{'TYPE'} eq '') { - &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings); &Header::showhttpheaders(); &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); - &Header::openbigbox('100%', 'LEFT', '', ''); - &Header::openbox('100%', 'LEFT', $Lang::tr{'connection type'}); + &Header::openbigbox('100%', 'left', '', ''); + &Header::openbox('100%', 'left', $Lang::tr{'connection type'}); print < $Lang::tr{'connection type'}:
- - - - - - -
$Lang::tr{'host to net vpn'}
$Lang::tr{'net to net vpn'}
+ + + + + + + + + +
$Lang::tr{'host to net vpn'}
$Lang::tr{'net to net vpn'}
END ; &Header::closebox(); @@ -1198,7 +1258,7 @@ END &Header::closepage(); exit (0); ### -### Adding a new connection +### Adding/Editing/Saving a connection ### } elsif (($cgiparams{'ACTION'} eq $Lang::tr{'add'}) || ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) || @@ -1213,21 +1273,33 @@ END $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{'SIDE'} = $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{'INTERFACE'} = $confighash{$cgiparams{'KEY'}}[26]; - $cgiparams{'DPD_ACTION'}= $confighash{$cgiparams{'KEY'}}[27]; - $cgiparams{'PFS_YES_NO'}= $confighash{$cgiparams{'KEY'}}[28]; + $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{'SIDE'} = $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{'INTERFACE'} = $confighash{$cgiparams{'KEY'}}[26]; + $cgiparams{'DPD_ACTION'} = $confighash{$cgiparams{'KEY'}}[27]; + $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]; + $cgiparams{'ESP_KEYLIFE'} = $confighash{$cgiparams{'KEY'}}[17]; + $cgiparams{'AGGRMODE'} = $confighash{$cgiparams{'KEY'}}[12]; + $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]; } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { $cgiparams{'REMARK'} = &Header::cleanhtml($cgiparams{'REMARK'}); @@ -1252,12 +1324,12 @@ END } if (($cgiparams{'TYPE'} eq 'net') && ($cgiparams{'SIDE'} !~ /^(left|right)$/)) { - $errormessage = $Lang::tr{'ipfire side is invalid'}; + $errormessage = $Lang::tr{'ipcop side is invalid'}; goto VPNCONF_ERROR; } # Check if there is no other entry with this name - if (! $cgiparams{'KEY'}) { + 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'}; @@ -1289,12 +1361,12 @@ END goto VPNCONF_ERROR; } - # Check if there is no other entry without IP-address and PSK - if ($cgiparams{'REMOTE'} eq '') { + # 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' || $cgiparams{'AUTH'} eq 'psk') && - $confighash{$key}[10] eq '') { + 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; } @@ -1314,20 +1386,34 @@ END goto VPNCONF_ERROR; } - if (($cgiparams{'LOCAL_ID'} !~ /^(|@[a-zA-Z0-9_.-]*)$/) || - ($cgiparams{'REMOTE_ID'} !~ /^(|@[a-zA-Z0-9_.-]*)$/) || + # 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'}; + $errormessage = $Lang::tr{'invalid local-remote id'} . '
' . + 'DER_ASN1_DN: @c=FR/ou=Paris/ou=Home/cn=*
' . + 'FQDN: @ipcop.org
' . + 'USER_FQDN: franck@ipcop.org
' . + 'IPV4_ADDR: @123.123.123.123'; goto VPNCONF_ERROR; } - - if ($cgiparams{'AUTH'} eq 'psk') { + # 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{'AUTH'} eq 'psk') { if (! length($cgiparams{'PSK'}) ) { $errormessage = $Lang::tr{'pre-shared key is too short'}; goto VPNCONF_ERROR; } - if ($cgiparams{'PSK'} =~ /['",&]/) { # " ' correct coloring syntax editor ! + if ($cgiparams{'PSK'} =~ /'/) { + $cgiparams{'PSK'} =~ tr/'/ /; $errormessage = $Lang::tr{'invalid characters found in pre-shared key'}; goto VPNCONF_ERROR; } @@ -1348,35 +1434,116 @@ END goto VPNCONF_ERROR; } - # Sign the certificate request and move it - # Sign the host certificate request - system('/usr/bin/openssl', 'ca', '-days', '999999', - '-batch', '-notext', - '-in', $filename, - '-out', "${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + # Sign the certificate request + &General::log("ipsec", "Signing your cert $cgiparams{'NAME'}..."); + my $opt = " ca -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(); + unlink ($filename); + &cleanssldatabase(); } - my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/certs/$cgiparams{'NAME'}cert.pem`; - $temp =~ /Subject:.*CN=(.*)[\n]/; - $temp = $1; - $temp =~ s+/Email+, E+; - $temp =~ s/ ST=/ S=/; - $cgiparams{'CERT_NAME'} = $temp; - $cgiparams{'CERT_NAME'} =~ s/,//g; - $cgiparams{'CERT_NAME'} =~ s/\'//g; + $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"; + $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); + } + } + + 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); + } + + #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; + } + &General::log("ipsec", "p12 import completed!"); } elsif ($cgiparams{'AUTH'} eq 'certfile') { if ($cgiparams{'KEY'}) { $errormessage = $Lang::tr{'cant change certificates'}; @@ -1394,15 +1561,16 @@ END } # Verify the certificate has a valid CA and move it - my $validca = 0; + &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/) { - $validca = 1; - } else { + 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; } } } @@ -1419,14 +1587,7 @@ END } } - my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/certs/$cgiparams{'NAME'}cert.pem`; - $temp =~ /Subject:.*CN=(.*)[\n]/; - $temp = $1; - $temp =~ s+/Email+, E+; - $temp =~ s/ ST=/ S=/; - $cgiparams{'CERT_NAME'} = $temp; - $cgiparams{'CERT_NAME'} =~ s/,//g; - $cgiparams{'CERT_NAME'} =~ s/\'//g; + $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'}; @@ -1478,6 +1639,19 @@ END $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 (length($cgiparams{'CERT_PASS1'}) < 5) { $errormessage = $Lang::tr{'password too short'}; goto VPNCONF_ERROR; @@ -1493,65 +1667,77 @@ END (my $state = $cgiparams{'CERT_STATE'}) =~ s/^\s*$/\./; # Create the Host certificate request - my $pid = open(OPENSSL, "|-"); - $SIG{ALRM} = sub { $errormessage = $Lang::tr{'broken pipe'}; goto VPNCONF_ERROR;}; - if ($pid) { # parent - print OPENSSL "$cgiparams{'CERT_COUNTRY'}\n"; - print OPENSSL "$state\n"; - print OPENSSL "$city\n"; - print OPENSSL "$cgiparams{'CERT_ORGANIZATION'}\n"; - print OPENSSL "$ou\n"; - print OPENSSL "$cgiparams{'CERT_NAME'}\n"; - print OPENSSL "$cgiparams{'CERT_EMAIL'}\n"; - print OPENSSL ".\n"; - print OPENSSL ".\n"; - close (OPENSSL); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - unlink ("${General::swroot}/certs/$cgiparams{'NAME'}key.pem"); - unlink ("${General::swroot}/certs/$cgiparams{'NAME'}req.pem"); - goto VPNCONF_ERROR; - } - } else { # child - unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache', - '-newkey', 'rsa:1024', - '-keyout', "${General::swroot}/certs/$cgiparams{'NAME'}key.pem", - '-out', "${General::swroot}/certs/$cgiparams{'NAME'}req.pem")) { - $errormessage = "$Lang::tr{'cant start openssl'}: $!"; + &General::log("ipsec", "Creating a cert..."); + + if (open(STDIN, "-|")) { + my $opt = " req -nodes -rand /proc/interrupts:/proc/net/rt_cache"; + $opt .= " -newkey rsa:1024"; + $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 host certificate request - system('/usr/bin/openssl', 'ca', '-days', '999999', - '-batch', '-notext', - '-in', "${General::swroot}/certs/$cgiparams{'NAME'}req.pem", - '-out', "${General::swroot}/certs/$cgiparams{'NAME'}cert.pem"); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + &General::log("ipsec", "Signing the cert $cgiparams{'NAME'}..."); + + #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{'vpn configuration main'}, 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 ""; + print< + + + + + + + + + + + + + +END + ; + if ($cgiparams{'KEY'}) { + print ""; + print ""; + } - if ($cgiparams{'KEY'}) { - print ""; - print ""; - } + &Header::openbox('100%', 'left', "$Lang::tr{'connection'}:"); + print ""; + print ""; + if ($cgiparams{'KEY'}) { + print ""; + } else { + print ""; + } + print ""; - &Header::openbox('100%', 'LEFT', "$Lang::tr{'connection'}:"); - print "
$Lang::tr{'name'}:$cgiparams{'NAME'}$Lang::tr{'enabled'}
"; - print ""; - if ($cgiparams{'KEY'}) { - print ""; - } else { - print ""; - } - print ""; - - if ($cgiparams{'TYPE'} eq 'host') { + if ($cgiparams{'TYPE'} eq 'host') { - print ""; - print ""; - print < - - - - - + print ""; + print ""; + print < + + + + + + + END ; - } else { - print < - - - - - - - - + } else { + print < + + + + + + + + + END - ; - } - print < + ; + } + print < + - - + + + +   ? + + + - - - - - - + + + + + + + + + END - ; - if (!$cgiparams{'KEY'}) { - print ""; - } - print "
$Lang::tr{'name'}:$cgiparams{'NAME'}$Lang::tr{'enabled'}
$Lang::tr{'interface'}
$Lang::tr{'local subnet'} 
$Lang::tr{'remote host/ip'}: * 
$Lang::tr{'interface'}
$Lang::tr{'local subnet'} 
$Lang::tr{'remote host/ip'}: * 
$Lang::tr{'ipfire side'}$Lang::tr{'remote host/ip'}:
$Lang::tr{'local subnet'}$Lang::tr{'remote subnet'}
$Lang::tr{'ipcop side'} + $Lang::tr{'remote host/ip'}:
$Lang::tr{'local subnet'}$Lang::tr{'remote subnet'}
$Lang::tr{'dpd action'}:$Lang::tr{'dpd action'}:   ? $Lang::tr{'pfs yes no'}:
$Lang::tr{'options'}
leftid: * -
($Lang::tr{'eg'} @xy.example.com)
rightid: *
$Lang::tr{'remark title'} *
$Lang::tr{'vpn local id'}: * +
($Lang::tr{'eg'} @xy.example.com)
$Lang::tr{'vpn remote id'}: *
$Lang::tr{'remark title'} *
$Lang::tr{'edit advanced settings when done'}
"; - &Header::closebox(); + ; + if (!$cgiparams{'KEY'}) { + print " $Lang::tr{'edit advanced settings when done'}"; + } + print ""; + &Header::closebox(); - if ($cgiparams{'KEY'} && $cgiparams{'AUTH'} eq 'psk') { - &Header::openbox('100%', 'LEFT', $Lang::tr{'authentication'}); - print < - $Lang::tr{'use a pre-shared key'} - - + 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 $disabled=''; - my $cakeydisabled=''; - my $cacrtdisabled=''; - if ( ! -f "${General::swroot}/private/cakey.pem" ) { $cakeydisabled = "disabled='disabled'" } else { $cakeydisabled = "" }; - if ( ! -f "${General::swroot}/ca/cacert.pem" ) { $cacrtdisabled = "disabled='disabled'" } else { $cacrtdisabled = "" }; - &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{'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{'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{'confirmation'}) - - -END - ; - &Header::closebox(); + print ">$country\n"; } + print < - print "
"; - if ($cgiparams{'KEY'}) { - print ""; - } - print "
"; - &Header::closebigbox(); - &Header::closepage(); - exit (0); +  $Lang::tr{'vpn subjectaltname'} (subjectAltName=email:*,URI:*,DNS:*,RID:*)* + +   + $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: } @@ -1893,18 +2143,11 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || } if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) { - if ($cgiparams{'NAT'} !~ /^(on|off)$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - if ($cgiparams{'COMPRESSION'} !~ /^(on|off)$/) { - $errormessage = $Lang::tr{'invalid input'}; - goto ADVANCED_ERROR; - } - if ($cgiparams{'NAT'} eq 'on' && $cgiparams{'COMPRESSION'} eq 'on') { - $errormessage = $Lang::tr{'cannot enable both nat traversal and compression'}; - goto ADVANCED_ERROR; - } + # 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; + #} my @temp = split('\|', $cgiparams{'IKE_ENCRYPTION'}); if ($#temp < 0) { $errormessage = $Lang::tr{'invalid input'}; @@ -1982,12 +2225,18 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || $errormessage = $Lang::tr{'esp keylife should be between 1 and 24 hours'}; goto ADVANCED_ERROR; } - if ($cgiparams{'ONLY_PROPOSED'} !~ /^(on|off)$/) { + + if ( + ($cgiparams{'AGGRMODE'} !~ /^(|on|off)$/) || + ($cgiparams{'COMPRESSION'} !~ /^(|on|off)$/) || + ($cgiparams{'ONLY_PROPOSED'} !~ /^(|on|off)$/) || + ($cgiparams{'PFS'} !~ /^(|on|off)$/) || + ($cgiparams{'VHOST'} !~ /^(|on|off)$/) + ){ $errormessage = $Lang::tr{'invalid input'}; goto ADVANCED_ERROR; } - $confighash{$cgiparams{'KEY'}}[14] = $cgiparams{'NAT'}; - $confighash{$cgiparams{'KEY'}}[13] = $cgiparams{'COMPRESSION'}; + $confighash{$cgiparams{'KEY'}}[18] = $cgiparams{'IKE_ENCRYPTION'}; $confighash{$cgiparams{'KEY'}}[19] = $cgiparams{'IKE_INTEGRITY'}; $confighash{$cgiparams{'KEY'}}[20] = $cgiparams{'IKE_GROUPTYPE'}; @@ -1996,19 +2245,19 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || $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] = $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'}; &General::writehasharray("${General::swroot}/vpn/config", \%confighash); &writeipsecfiles(); - if ($vpnsettings{'ENABLED'} eq 'on' || - $vpnsettings{'ENABLED_BLUE'} eq 'on') { + if (&vpnenabled) { system('/usr/local/bin/ipsecctrl', 'S', $cgiparams{'KEY'}); sleep $sleepDelay; } goto ADVANCED_END; } else { - - $cgiparams{'NAT'} = $confighash{$cgiparams{'KEY'}}[14]; - $cgiparams{'COMPRESSION'} = $confighash{$cgiparams{'KEY'}}[13]; $cgiparams{'IKE_ENCRYPTION'} = $confighash{$cgiparams{'KEY'}}[18]; $cgiparams{'IKE_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[19]; $cgiparams{'IKE_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[20]; @@ -2017,20 +2266,18 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || $cgiparams{'ESP_INTEGRITY'} = $confighash{$cgiparams{'KEY'}}[22]; $cgiparams{'ESP_GROUPTYPE'} = $confighash{$cgiparams{'KEY'}}[23]; $cgiparams{'ESP_KEYLIFE'} = $confighash{$cgiparams{'KEY'}}[17]; + $cgiparams{'AGGRMODE'} = $confighash{$cgiparams{'KEY'}}[12]; + $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]; + if ($confighash{$cgiparams{'KEY'}}[3] eq 'net' || $confighash{$cgiparams{'KEY'}}[10]) { - $cgiparams{'NAT'} = 'off'; + $cgiparams{'VHOST'} = 'off'; } } ADVANCED_ERROR: - $checked{'NAT'}{'off'} = ''; - $checked{'NAT'}{'on'} = ''; - $checked{'NAT'}{$cgiparams{'NAT'}} = "checked='checked'"; - $checked{'COMPRESSION'}{'off'} = ''; - $checked{'COMPRESSION'}{'on'} = ''; - $checked{'COMPRESSION'}{$cgiparams{'COMPRESSION'}} = "checked='checked'"; $checked{'IKE_ENCRYPTION'}{'aes256'} = ''; $checked{'IKE_ENCRYPTION'}{'aes128'} = ''; $checked{'IKE_ENCRYPTION'}{'3des'} = ''; @@ -2083,112 +2330,140 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || $checked{'ESP_GROUPTYPE'}{'modp3072'} = ''; $checked{'ESP_GROUPTYPE'}{'modp4096'} = ''; $checked{'ESP_GROUPTYPE'}{$cgiparams{'ESP_GROUPTYPE'}} = "selected='selected'"; - $checked{'ONLY_PROPOSED'}{'off'} = ''; - $checked{'ONLY_PROPOSED'}{'on'} = ''; - $checked{'ONLY_PROPOSED'}{$cgiparams{'ONLY_PROPOSED'}} = "checked='checked'"; + + $checked{'AGGRMODE'} = $cgiparams{'AGGRMODE'} eq 'on' ? "checked='checked'" : '' ; + $checked{'COMPRESSION'} = $cgiparams{'COMPRESSION'} 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'" : '' ; &Header::showhttpheaders(); &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); - &Header::openbigbox('100%', 'LEFT', '', $errormessage); + &Header::openbigbox('100%', 'left', '', $errormessage); if ($errormessage) { - &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'}); + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); print "$errormessage"; print " "; &Header::closebox(); } if ($warnmessage) { - &Header::openbox('100%', 'LEFT', $Lang::tr{'warning messages'}); + &Header::openbox('100%', 'left', $Lang::tr{'warning messages'}); print "$warnmessage"; print " "; &Header::closebox(); } - print "
\n"; - print "\n"; - print "\n"; + &Header::openbox('100%', 'left', "$Lang::tr{'advanced'}:"); + print < + + - &Header::openbox('100%', 'LEFT', "$Lang::tr{'advanced'}:"); - print "\n"; - print "\n"; - print "\n"; +
$Lang::tr{'compression'}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +EOF + ; if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') { - print "\n"; + print ""; } elsif ($confighash{$cgiparams{'KEY'}}[10]) { - print "\n"; - print "\n"; + print ""; } else { - print "\n"; - print "\n"; + print ""; } - print < - - - - - - - - - - - - - - - - -
$Lang::tr{'ike encryption'} + $Lang::tr{'ike integrity'} + $Lang::tr{'ike grouptype'} +
$Lang::tr{'ike lifetime'} + $Lang::tr{'hours'}

$Lang::tr{'esp encryption'} + $Lang::tr{'esp integrity'} + $Lang::tr{'esp grouptype'} +
$Lang::tr{'esp keylife'} + $Lang::tr{'hours'}

+ IKE+ESP: $Lang::tr{'use only proposed settings'}
+ $Lang::tr{'vpn aggrmode'}
+ $Lang::tr{'pfs yes no'}
+ $Lang::tr{'vpn payload compression'}
 
$Lang::tr{'nat-traversal'}
"; + print " $Lang::tr{'vpn vhost'}
$Lang::tr{'nat-traversal'}
"; + print " $Lang::tr{'vpn vhost'}
$Lang::tr{'ike encryption'}$Lang::tr{'ike integrity'}
$Lang::tr{'ike lifetime'} $Lang::tr{'hours'}$Lang::tr{'ike grouptype'}
$Lang::tr{'esp encryption'}$Lang::tr{'esp integrity'}
$Lang::tr{'esp keylife'} $Lang::tr{'hours'}$Lang::tr{'esp grouptype'}
- $Lang::tr{'use only proposed settings'}
-EOF - ; + + print ""; &Header::closebox(); - print "
"; - print "
"; &Header::closebigbox(); &Header::closepage(); exit(0); @@ -2205,6 +2480,7 @@ EOF &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/sbin/ipsec auto --status`; @@ -2224,64 +2500,86 @@ EOF $cgiparams{'VPN_IP'} ='%defaultroute' if ($cgiparams{'VPN_IP'} eq ''); $cgiparams{'VPN_DELAYED_START'} = 0 if (! defined ($cgiparams{'VPN_DELAYED_START'})); + $checked{'VPN_WATCH'} = $cgiparams{'VPN_WATCH'} eq 'on' ? "checked='checked'" : '' ; map ($checked{$_} = $cgiparams{$_} eq 'on' ? "checked='checked'" : '', - ('ENABLED','ENABLED_BLUE','DBG_CRYPT','DBG_PARSING','DBG_EMITTING','DBG_CONTROL', + ('ENABLED','ENABLED_GREEN','ENABLED_ORANGE','ENABLED_BLUE','DBG_CRYPT','DBG_PARSING','DBG_EMITTING','DBG_CONTROL', 'DBG_KLIPS','DBG_DNS','DBG_NAT_T')); &Header::showhttpheaders(); &Header::openpage($Lang::tr{'vpn configuration main'}, 1, ''); - &Header::openbigbox('100%', 'LEFT', '', $errormessage); + &Header::openbigbox('100%', 'left', '', $errormessage); if ($errormessage) { - &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'}); + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); print "$errormessage\n"; print " \n"; &Header::closebox(); } - &Header::openbox('100%', 'LEFT', $Lang::tr{'global settings'}); + &Header::openbox('100%', 'left', $Lang::tr{'global settings'}); + my $checkbox=""; print < +
- - - + + + + + END ; - if ($netsettings{'BLUE_DEV'} ne '') { + if ($netsettings{'ORANGE_DEV'} ne '') { + $checkbox=<$Lang::tr{'vpn on orange'}: + +END + ;} + print < - + + - + $checkbox END ; - } + if ($netsettings{'BLUE_DEV'} ne '') { + $checkbox=<$Lang::tr{'vpn on blue'}: + +END + ;} print <$Lang::tr{'vpn delayed start'}: * - - - -
$Lang::tr{'local vpn hostname/ip'}:$Lang::tr{'enabled'}$Lang::tr{'local vpn hostname/ip'}:$Lang::tr{'enabled'}$Lang::tr{'vpn on green'}:$Lang::tr{'enabled'}
$Lang::tr{'enabled'}$Lang::tr{'vpn on blue'}:$Lang::tr{'override mtu'}: * $Lang::tr{'enabled'}
$Lang::tr{'enabled'}$Lang::tr{'override mtu'}: *
- - - - - - - - - -
PLUTO DEBUGcrypt:parsing:emitting:control:klips:dns:nat_t:
+ + $Lang::tr{'vpn delayed start'}: ** + + + $checkbox + + +

$Lang::tr{'vpn watch'}:

+

PLUTO DEBUG = +crypt:,  +parsing:,  +emitting:,  +control:,  +klips:,  +dns:,  +nat_t:

+
- + + + + +
*$Lang::tr{'vpn delayed start help'}$Lang::tr{'this field may be blank'}
**  $Lang::tr{'vpn delayed start help'}
@@ -2289,17 +2587,18 @@ END ; print "
"; &Header::closebox(); + undef ($checkbox); - &Header::openbox('100%', 'LEFT', $Lang::tr{'connection status and controlc'}); + &Header::openbox('100%', 'left', $Lang::tr{'connection status and controlc'}); print < $Lang::tr{'name'} $Lang::tr{'type'} $Lang::tr{'common name'} - $Lang::tr{'remark'}
L2089 + $Lang::tr{'remark'} $Lang::tr{'status'} - $Lang::tr{'action'} + $Lang::tr{'action'} END ; @@ -2315,7 +2614,9 @@ END } print "$confighash{$key}[1]"; print "" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")"; - if ($confighash{$key}[4] eq 'cert') { + if ($confighash{$key}[2] eq '%auth-dn') { + print "$confighash{$key}[9]"; + } elsif ($confighash{$key}[4] eq 'cert') { print "$confighash{$key}[2]"; } else { print " "; @@ -2333,66 +2634,80 @@ END } print <$active -
- + + + -
+ + END ; - if ($confighash{$key}[4] eq 'cert') { + if (($confighash{$key}[4] eq 'cert') && ($confighash{$key}[2] ne '%auth-dn')) { print < - + +
+ -
+ + END ; } else { - print " "; + print " "; } if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/certs/$confighash{$key}[1].p12") { print < - + +
+ -
+ + END - ; } elsif ($confighash{$key}[4] eq 'cert') { + ; } elsif (($confighash{$key}[4] eq 'cert') && ($confighash{$key}[2] ne '%auth-dn')) { print < - + +
+ -
+ + END ; } else { - print " "; + print " "; } print < - + +
+ -
+ + -
+ + - + -
-
+
+ + +
- + -
+ + END ; $id++; } - ; + print ""; # If the config file contains entries, print Key to action icons if ( $id ) { @@ -2425,15 +2740,17 @@ END print < -
- -
+ +
+ +
+ END ; &Header::closebox(); - &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate authorities'}:"); + &Header::openbox('100%', 'left', "$Lang::tr{'certificate authorities'}:"); print < @@ -2444,24 +2761,24 @@ END EOF ; if (-f "${General::swroot}/ca/cacert.pem") { - my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ca/cacert.pem`; - $casubject =~ /Subject: (.*)[\n]/; - $casubject = $1; - $casubject =~ s+/Email+, E+; - $casubject =~ s/ ST=/ S=/; + my $casubject = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/ca/cacert.pem")); print < $Lang::tr{'root certificate'} $casubject -
+ + - -
-
- + +
+ + +
+ -
+ +   END ; @@ -2477,24 +2794,24 @@ END } if (-f "${General::swroot}/certs/hostcert.pem") { - my $hostsubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/certs/hostcert.pem`; - $hostsubject =~ /Subject: (.*)[\n]/; - $hostsubject = $1; - $hostsubject =~ s+/Email+, E+; - $hostsubject =~ s/ ST=/ S=/; + my $hostsubject = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/certs/hostcert.pem")); print < $Lang::tr{'host certificate'} $hostsubject -
+ + - -
-
- + +
+ + +
+ -
+ +   END ; @@ -2504,17 +2821,11 @@ END $Lang::tr{'host certificate'}: $Lang::tr{'not present'} -   +   END ; } - if (! -f "${General::swroot}/ca/cacert.pem") { - print "
"; - print ""; - print "
\n"; - } - if (keys %cahash > 0) { foreach my $key (keys %cahash) { if (($key + 1) % 2) { @@ -2525,56 +2836,69 @@ END print "$cahash{$key}[0]\n"; print "$cahash{$key}[1]\n"; print < - + +
+ -
-
- +
+ + +
+ -
-
+
+ + +
- + -
+ + + END ; } } - print ""; # If the file contains entries, print Key to action icons if ( -f "${General::swroot}/ca/cacert.pem") { - print < - + 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 < +
+
- - - -
$Lang::tr{'ca name'}: -
+ $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(); - print "
\n"; print "$Lang::tr{'this feature has been sponsored by'} : "; print "Seminole Canada Gas Company.\n";