Merge remote-tracking branch 'ms/ipsec-subnets' into next
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 28 Sep 2015 13:21:18 +0000 (14:21 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 28 Sep 2015 13:21:18 +0000 (14:21 +0100)
1  2 
html/cgi-bin/vpnmain.cgi

@@@ -235,198 -237,193 +235,196 @@@ sub makeconnname ($) 
  ###
  
  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";
 -      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";
 -      } 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";
 -              }
 +      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";
        }
  
 -      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]);
 +      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
  
 -              # Use IKE grouptype if no ESP group type has been selected
 -              # (for backwards compatibility)
 -              if ($lconfighash{$key}[23] eq "") {
 -                      @groups = split('\|', $lconfighash{$key}[20]);
 +      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'};
                }
  
 -              my @algos = &make_algos("esp", \@encs, \@ints, \@groups, ($pfs eq "on"));
 -              print CONF "\tesp=" . join(",", @algos);
 +              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 "\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}[24] eq 'on') {   #only proposed algorythms?
 -                      print CONF "!\n";
 -              } else {
 -                      print CONF "\n";
 +              if ($lconfighash{$key}[3] eq 'net') {
-                       my $cidr_net=&General::ipcidr($lconfighash{$key}[11]);
-                       print CONF "\trightsubnet=$cidr_net\n";
++                      print CONF "\trightsubnet=" . &make_subnets($lconfighash{$key}[11]) . "\n";
                }
 -      }
  
 -      # IKE V1 or V2
 -      if (! $lconfighash{$key}[29]) {
 -         $lconfighash{$key}[29] = "ikev1";
 -      }
 -      print CONF "\tkeyexchange=$lconfighash{$key}[29]\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]);
  
 -      # 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]);
 +              # Is PFS enabled?
 +              my $pfs = $lconfighash{$key}[28] eq 'on' ? 'on' : 'off';
  
 -      # Compression
 -      print CONF "\tcompress=yes\n" if ($lconfighash{$key}[13] eq 'on');
 +              # 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]);
  
 -      # Dead Peer Detection
 -      my $dpdaction = $lconfighash{$key}[27];
 -      print CONF "\tdpdaction=$dpdaction\n";
 +                      my @algos = &make_algos("ike", \@encs, \@ints, \@groups, 1);
 +                      print CONF "\tike=" . join(",", @algos);
  
 -      # 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";
 +                      if ($lconfighash{$key}[24] eq 'on') { #only proposed algorythms?
 +                              print CONF "!\n";
 +                      } else {
 +                              print CONF "\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";
 -      }
 +              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]);
 +                      }
  
 -      # Fragmentation
 -      print CONF "\tfragmentation=yes\n";
 +                      my @algos = &make_algos("esp", \@encs, \@ints, \@groups, ($pfs eq "on"));
 +                      print CONF "\tesp=" . join(",", @algos);
  
 -      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);
 +                      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.
        &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 '')) {
 -
 -    &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];
 -      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{'VHOST'}             = $confighash{$cgiparams{'KEY'}}[14];
 -      $cgiparams{'DPD_TIMEOUT'}               = $confighash{$cgiparams{'KEY'}}[30];
 -      $cgiparams{'DPD_DELAY'}         = $confighash{$cgiparams{'KEY'}}[31];
 -
 -      if (!$cgiparams{'DPD_DELAY'}) {
 -              $cgiparams{'DPD_DELAY'} = 30;
 -      }
 +      ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}) ||
 +      ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'ADVANCED'} eq '')) {
  
 -      if (!$cgiparams{'DPD_TIMEOUT'}) {
 -              $cgiparams{'DPD_TIMEOUT'} = 120;
 -      }
 +      &General::readhash("${General::swroot}/vpn/settings", \%vpnsettings);
 +      &General::readhasharray("${General::swroot}/vpn/caconfig", \%cahash);
 +      &General::readhasharray("${General::swroot}/vpn/config", \%confighash);
  
 -    } 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{'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];
++              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];
-               $cgiparams{'REMOTE_SUBNET'}             = $confighash{$cgiparams{'KEY'}}[11];
++              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];
 +
 +              if (!$cgiparams{'DPD_DELAY'}) {
 +                      $cgiparams{'DPD_DELAY'} = 30;
 +              }
  
 -      if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) {
 -          $errormessage = $Lang::tr{'name must only contain characters'};
 -          goto VPNCONF_ERROR;
 -      }
 +              if (!$cgiparams{'DPD_TIMEOUT'}) {
 +                      $cgiparams{'DPD_TIMEOUT'} = 120;
 +              }
  
 -      if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) {
 -          $errormessage = $Lang::tr{'name is invalid'};
 -          goto VPNCONF_ERROR;
 -      }
 +      } 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 (length($cgiparams{'NAME'}) >60) {
 -          $errormessage = $Lang::tr{'name too long'};
 -          goto VPNCONF_ERROR;
 -      }
 +              if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) {
 +                      $errormessage = $Lang::tr{'name must only contain characters'};
 +                      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{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) {
 +                      $errormessage = $Lang::tr{'name is invalid'};
 +                      goto VPNCONF_ERROR;
                }
 -          }
 -      }
  
 -      if (($cgiparams{'TYPE'} eq 'net') && (! $cgiparams{'REMOTE'})) {
 -          $errormessage = $Lang::tr{'invalid input for remote host/ip'};
 -          goto VPNCONF_ERROR;
 -      }
 +              if (length($cgiparams{'NAME'}) >60) {
 +                      $errormessage = $Lang::tr{'name too long'};
 +                      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'}";
 -                  }
 +              # 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;
 +                              }
 +                      }
                }
 -          }
 -      }
  
 -      my @local_subnets = split(",", $cgiparams{'LOCAL_SUBNET'});
 -      foreach my $subnet (@local_subnets) {
 -              unless (&Network::check_subnet($subnet)) {
 -                      $errormessage = $Lang::tr{'local subnet is invalid'};
 +              if (($cgiparams{'TYPE'} eq 'net') && (! $cgiparams{'REMOTE'})) {
 +                      $errormessage = $Lang::tr{'invalid input for remote host/ip'};
                        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{'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'}";
 +                                      }
 +                              }
 +                      }
                }
 -          }
 -      }
  
-               unless (&General::validipandmask($cgiparams{'LOCAL_SUBNET'})) {
-                       $errormessage = $Lang::tr{'local subnet is invalid'};
-                       goto VPNCONF_ERROR;
 -      if ($cgiparams{'TYPE'} eq 'net') {
 -              my @remote_subnets = split(",", $cgiparams{'REMOTE_SUBNET'});
 -              foreach my $subnet (@remote_subnets) {
++              my @local_subnets = split(",", $cgiparams{'LOCAL_SUBNET'});
++              foreach my $subnet (@local_subnets) {
+                       unless (&Network::check_subnet($subnet)) {
 -                              $errormessage = $Lang::tr{'remote subnet is invalid'};
++                              $errormessage = $Lang::tr{'local 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 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') && (! &General::validipandmask($cgiparams{'REMOTE_SUBNET'}))) {
-                       $errormessage = $Lang::tr{'remote subnet is invalid'};
-                       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'} . '<br />' .
 -          'DER_ASN1_DN: @c=FR/ou=Paris/ou=Home/cn=*<br />' .
 -          'FQDN: @ipfire.org<br />' .
 -          'USER_FQDN: info@ipfire.org<br />' .
 -          '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') {
++                      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{'TYPE'} eq 'net'){
 -              $warnmessage=&General::checksubnets('',$cgiparams{'REMOTE_SUBNET'},'ipsec');
 -              if ($warnmessage ne ''){
 -                      $warnmessage=$Lang::tr{'remote subnet'}." ($cgiparams{'REMOTE_SUBNET'}) <br>".$warnmessage;
 +              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;
                }
 -      }
  
 -      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;
 -          }
 +              # 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'} . '<br />' .
 +                      'DER_ASN1_DN: @c=FR/ou=Paris/ou=Home/cn=*<br />' .
 +                      'FQDN: @ipfire.org<br />' .
 +                      'USER_FQDN: info@ipfire.org<br />' .
 +                      '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'}) <br>".$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;
 -          }
 +              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;
 -          }
 +              # 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";
 +              # 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";
        }
        $confighash{$key}[3] = $cgiparams{'TYPE'};
        if ($cgiparams{'AUTH'} eq 'psk') {
 -          $confighash{$key}[4] = 'psk';
 -          $confighash{$key}[5] = $cgiparams{'PSK'};
 +              $confighash{$key}[4] = 'psk';
 +              $confighash{$key}[5] = $cgiparams{'PSK'};
        } else {
 -          $confighash{$key}[4] = 'cert';
 +              $confighash{$key}[4] = 'cert';
        }
        if ($cgiparams{'TYPE'} eq 'net') {
-               $confighash{$key}[11] = $cgiparams{'REMOTE_SUBNET'};
 -          my @remote_subnets = split(",", $cgiparams{'REMOTE_SUBNET'});
 -          $confighash{$key}[11] = join('|', @remote_subnets);
++              my @remote_subnets = split(",", $cgiparams{'REMOTE_SUBNET'});
++              $confighash{$key}[11] = join('|', @remote_subnets);
        }
        $confighash{$key}[7] = $cgiparams{'LOCAL_ID'};
-       $confighash{$key}[8] = $cgiparams{'LOCAL_SUBNET'};
+       my @local_subnets = split(",", $cgiparams{'LOCAL_SUBNET'});
+       $confighash{$key}[8] = join('|', @local_subnets);
        $confighash{$key}[9] = $cgiparams{'REMOTE_ID'};
        $confighash{$key}[10] = $cgiparams{'REMOTE'};
        $confighash{$key}[25] = $cgiparams{'REMARK'};
@@@ -1938,67 -1945,72 +1949,73 @@@ VPNCONF_ERROR
        <input type='hidden' name='DPD_ACTION' value='$cgiparams{'DPD_ACTION'}' />
        <input type='hidden' name='DPD_DELAY' value='$cgiparams{'DPD_DELAY'}' />
        <input type='hidden' name='DPD_TIMEOUT' value='$cgiparams{'DPD_TIMEOUT'}' />
 +      <input type='hidden' name='FORCE_MOBIKE' value='$cgiparams{'FORCE_MOBIKE'}' />
  END
 -    ;
 -    if ($cgiparams{'KEY'}) {
 -      print "<input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />";
 -      print "<input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />";
 -      print "<input type='hidden' name='AUTH' value='$cgiparams{'AUTH'}' />";
 -    }
 -
 -    &Header::openbox('100%', 'left', "$Lang::tr{'connection'}: $cgiparams{'NAME'}");
 -    print "<table width='100%'>";
 -    if (!$cgiparams{'KEY'}) {
 -      print <<EOF;
 -              <tr>
 -                      <td width='20%'>$Lang::tr{'name'}:</td>
 -                      <td width='30%'>
 -                              <input type='text' name='NAME' value='$cgiparams{'NAME'}' size='25' />
 -                      </td>
 -                      <td colspan="2"></td>
 -              </tr>
 +;
 +      if ($cgiparams{'KEY'}) {
 +              print "<input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />";
 +              print "<input type='hidden' name='NAME' value='$cgiparams{'NAME'}' />";
 +              print "<input type='hidden' name='AUTH' value='$cgiparams{'AUTH'}' />";
 +      }
 +
 +      &Header::openbox('100%', 'left', "$Lang::tr{'connection'}: $cgiparams{'NAME'}");
 +      print "<table width='100%'>";
 +      if (!$cgiparams{'KEY'}) {
 +              print <<EOF;
 +                      <tr>
 +                              <td width='20%'>$Lang::tr{'name'}:&nbsp;<img src='/blob.gif' alt='*' /></td>
 +                              <td width='30%'>
 +                                      <input type='text' name='NAME' value='$cgiparams{'NAME'}' size='25' />
 +                              </td>
 +                              <td colspan="2"></td>
 +                      </tr>
  EOF
 -    }
 +      }
  
 -    my $disabled;
 -    my $blob;
 -    if ($cgiparams{'TYPE'} eq 'host') {
 -      $disabled = "disabled='disabled'";
 -      $blob = "<img src='/blob.gif' alt='*' />";
 -    };
 +      my $disabled;
 +      my $blob;
 +      if ($cgiparams{'TYPE'} eq 'host') {
 +              $disabled = "disabled='disabled'";
 +      } elsif ($cgiparams{'TYPE'} eq 'net') {
 +              $blob = "<img src='/blob.gif' alt='*' />";
 +      };
  
 -    my @local_subnets = split(/\|/, $cgiparams{'LOCAL_SUBNET'});
 -    my $local_subnets = join(",", @local_subnets);
++      my @local_subnets = split(/\|/, $cgiparams{'LOCAL_SUBNET'});
++      my $local_subnets = join(",", @local_subnets);
 -    my @remote_subnets = split(/\|/, $cgiparams{'REMOTE_SUBNET'});
 -    my $remote_subnets = join(",", @remote_subnets);
++      my @remote_subnets = split(/\|/, $cgiparams{'REMOTE_SUBNET'});
++      my $remote_subnets = join(",", @remote_subnets);
 -    print <<END
 +      print <<END
        <tr>
                <td width='20%'>$Lang::tr{'enabled'}</td>
                <td width='30%'>
 -                      <input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} />
 +                      <input type='checkbox' name='ENABLED' $checked{'ENABLED'}{'on'} />
 +              </td>
 +              <td class='boldbase' nowrap='nowrap' width='20%'>$Lang::tr{'local subnet'}&nbsp;<img src='/blob.gif' alt='*' /></td>
 +              <td width='30%'>
-                       <input type='text' name='LOCAL_SUBNET' value='$cgiparams{'LOCAL_SUBNET'}' size="25" />
++                      <input type='text' name='LOCAL_SUBNET' value='$local_subnets' />
 +              </td>
 +      </tr>
 +      <tr>
 +              <td class='boldbase' width='20%'>$Lang::tr{'remote host/ip'}:&nbsp;$blob</td>
 +              <td width='30%'>
 +                      <input type='text' name='REMOTE' value='$cgiparams{'REMOTE'}' size="25" />
 +              </td>
 +              <td class='boldbase' nowrap='nowrap' width='20%'>$Lang::tr{'remote subnet'}&nbsp;$blob</td>
 +              <td width='30%'>
-                       <input $disabled type='text' name='REMOTE_SUBNET' value='$cgiparams{'REMOTE_SUBNET'}' size="25" />
++                      <input $disabled type='text' name='REMOTE_SUBNET' value='$remote_subnets' />
                </td>
 -          <td class='boldbase' nowrap='nowrap' width='20%'>$Lang::tr{'local subnet'}</td>
 -          <td width='30%'>
 -              <input type='text' name='LOCAL_SUBNET' value='$local_subnets' />
 -          </td>
 -      </tr>
 -      <tr>
 -          <td class='boldbase' width='20%'>$Lang::tr{'remote host/ip'}:&nbsp;$blob</td>
 -          <td width='30%'>
 -              <input type='text' name='REMOTE' value='$cgiparams{'REMOTE'}' size="25" />
 -          </td>
 -          <td class='boldbase' nowrap='nowrap' width='20%'>$Lang::tr{'remote subnet'}</td>
 -          <td width='30%'>
 -              <input $disabled type='text' name='REMOTE_SUBNET' value='$remote_subnets' />
 -          </td>
        </tr>
        <tr>
 -          <td class='boldbase' width='20%'>$Lang::tr{'vpn local id'}:</td>
 -          <td width='30%'>
 -              <input type='text' name='LOCAL_ID' value='$cgiparams{'LOCAL_ID'}' size="25" />
 -          </td>
 -          <td class='boldbase' width='20%'>$Lang::tr{'vpn remote id'}:</td>
 -          <td width='30%'>
 -              <input type='text' name='REMOTE_ID' value='$cgiparams{'REMOTE_ID'}' size="25" />
 -          </td>
 +              <td class='boldbase' width='20%'>$Lang::tr{'vpn local id'}:</td>
 +              <td width='30%'>
 +                      <input type='text' name='LOCAL_ID' value='$cgiparams{'LOCAL_ID'}' size="25" />
 +              </td>
 +              <td class='boldbase' width='20%'>$Lang::tr{'vpn remote id'}:</td>
 +              <td width='30%'>
 +                      <input type='text' name='REMOTE_ID' value='$cgiparams{'REMOTE_ID'}' size="25" />
 +              </td>
        </tr>
        <tr><td colspan="4"><br /></td></tr>
        <tr>