]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - html/cgi-bin/vpnmain.cgi
IPsec: Add option to force using MOBIKE
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / vpnmain.cgi
index af68d50a2f928e239d43779067145bd3169033a7..9f3c645e1a11b4cbc778504921383e4106860d9e 100644 (file)
@@ -69,6 +69,8 @@ if (&Header::orange_used() && $netsettings{'ORANGE_DEV'}) {
        $orange_cidr = &General::ipcidr("$netsettings{'ORANGE_NETADDRESS'}/$netsettings{'ORANGE_NETMASK'}");
 }
 
+my $col="";
+
 $cgiparams{'ENABLED'} = 'off';
 $cgiparams{'EDIT_ADVANCED'} = 'off';
 $cgiparams{'ACTION'} = '';
@@ -106,6 +108,7 @@ $cgiparams{'ROOTCERT_STATE'} = '';
 $cgiparams{'RW_NET'} = '';
 $cgiparams{'DPD_DELAY'} = '30';
 $cgiparams{'DPD_TIMEOUT'} = '120';
+$cgiparams{'FORCE_MOBIKE'} = 'off';
 &Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'});
 
 ###
@@ -251,8 +254,10 @@ sub writeipsecfiles {
     print CONF "\n";
 
     # Add user includes to config file
-    print CONF "include /etc/ipsec.user.conf\n";
-    print CONF "\n";
+    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";
 
@@ -308,67 +313,39 @@ sub writeipsecfiles {
 
        # 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; }
-
-                       my @l = split("", $k);
-                       if ($l[0] eq "e") {
-                           shift @l;
-                           print CONF "$i-$j-ecp".join("", @l);
-                       } else {
-                           print CONF "$i-$j-modp$k";
-                       }
-                   }
-               }
-           }
-           if ($lconfighash{$key}[24] eq 'on') {       #only proposed algorythms?
-               print CONF "!\n";
-           } else {
-               print CONF "\n";
-           }
+               my @encs   = split('\|', $lconfighash{$key}[18]);
+               my @ints   = split('\|', $lconfighash{$key}[19]);
+               my @groups = split('\|', $lconfighash{$key}[20]);
+
+               my @algos = &make_algos("ike", \@encs, \@ints, \@groups, 1);
+               print CONF "\tike=" . join(",", @algos);
+
+               if ($lconfighash{$key}[24] eq 'on') {   #only proposed algorythms?
+                       print CONF "!\n";
+               } else {
+                       print CONF "\n";
+               }
        }
+
        if ($lconfighash{$key}[21] && $lconfighash{$key}[22]) {
-           print CONF "\tesp=";
-           my @encs   = split('\|', $lconfighash{$key}[21]);
-           my @ints   = split('\|', $lconfighash{$key}[22]);
-           my @groups = split('\|', $lconfighash{$key}[20]);
-           my $comma = 0;
-           foreach my $i (@encs) {
-               foreach my $j (@ints) {
-                       my $modp = "";
-                       if ($pfs eq "on") {
-                               foreach my $k (@groups) {
-                                   if ($comma != 0) { print CONF ","; } else { $comma = 1; }
-                                   if ($pfs eq "on") {
-                                       my @l = split("", $k);
-                                       if ($l[0] eq "e") {
-                                               $modp = "";
-                                       } else {
-                                               $modp = "-modp$k";
-                                       }
-                                   } else {
-                                       $modp = "";
-                                   }
-                                   print CONF "$i-$j$modp";
-                               }
-                       } else {
-                               if ($comma != 0) { print CONF ","; } else { $comma = 1; }
-                               print CONF "$i-$j";
-                       }
+               my @encs   = split('\|', $lconfighash{$key}[21]);
+               my @ints   = split('\|', $lconfighash{$key}[22]);
+               my @groups = split('\|', $lconfighash{$key}[23]);
+
+               # Use IKE grouptype if no ESP group type has been selected
+               # (for backwards compatibility)
+               if ($lconfighash{$key}[23] eq "") {
+                       @groups = split('\|', $lconfighash{$key}[20]);
+               }
+
+               my @algos = &make_algos("esp", \@encs, \@ints, \@groups, ($pfs eq "on"));
+               print CONF "\tesp=" . join(",", @algos);
+
+               if ($lconfighash{$key}[24] eq 'on') {   #only proposed algorythms?
+                       print CONF "!\n";
+               } else {
+                       print CONF "\n";
                }
-           }
-           if ($lconfighash{$key}[24] eq 'on') {       #only proposed algorythms?
-               print CONF "!\n";
-           } else {
-               print CONF "\n";
-           }
        }
 
        # IKE V1 or V2
@@ -384,6 +361,11 @@ sub writeipsecfiles {
        # 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";
@@ -395,12 +377,12 @@ sub writeipsecfiles {
                        print CONF "\tdpddelay=0\n";
                }
        } else {
-               my $dpddelay = $lconfighash{$key}[30];
+               my $dpddelay = $lconfighash{$key}[31];
                if (!$dpddelay) {
                        $dpddelay = 30;
                }
                print CONF "\tdpddelay=$dpddelay\n";
-               my $dpdtimeout = $lconfighash{$key}[31];
+               my $dpdtimeout = $lconfighash{$key}[30];
                if (!$dpdtimeout) {
                        $dpdtimeout = 120;
                }
@@ -433,8 +415,20 @@ sub writeipsecfiles {
        } 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);
@@ -509,7 +503,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg
 ###
 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'remove x509'}) {
     &Header::showhttpheaders();
-    &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+    &Header::openpage($Lang::tr{'ipsec'}, 1, '');
     &Header::openbigbox('100%', 'left', '', '');
     &Header::openbox('100%', 'left', $Lang::tr{'are you sure'});
     print <<END
@@ -605,7 +599,7 @@ END
 
     if ( -f "${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem") {
        &Header::showhttpheaders();
-       &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+       &Header::openpage($Lang::tr{'ipsec'}, 1, '');
        &Header::openbigbox('100%', 'left', '', '');
        &Header::openbox('100%', 'left', "$Lang::tr{'ca certificate'}:");
        my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`;
@@ -681,7 +675,7 @@ END
        }
        if ($assignedcerts) {
            &Header::showhttpheaders();
-           &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+           &Header::openpage($Lang::tr{'ipsec'}, 1, '');
            &Header::openbigbox('100%', 'left', '', '');
            &Header::openbox('100%', 'left', $Lang::tr{'are you sure'});
            print <<END
@@ -726,7 +720,7 @@ END
        $cgiparams{'ACTION'} eq $Lang::tr{'show host certificate'}) {
     my $output;
     &Header::showhttpheaders();
-    &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+    &Header::openpage($Lang::tr{'ipsec'}, 1, '');
     &Header::openbigbox('100%', 'left', '', '');
     if ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'}) {
        &Header::openbox('100%', 'left', "$Lang::tr{'root certificate'}:");
@@ -959,9 +953,9 @@ END
        if (!$errormessage) {
            &General::log("ipsec", "Creating cacert...");
            if (open(STDIN, "-|")) {
-               my $opt  = " req -x509 -nodes -rand /proc/interrupts:/proc/net/rt_cache";
+               my $opt  = " req -x509 -sha256 -nodes";
                   $opt .= " -days 999999";
-                  $opt .= " -newkey rsa:2048";
+                  $opt .= " -newkey rsa:4096";
                   $opt .= " -keyout ${General::swroot}/private/cakey.pem";
                   $opt .= " -out ${General::swroot}/ca/cacert.pem";
 
@@ -982,8 +976,8 @@ END
        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";
+               my $opt  = " req -sha256 -nodes";
+                  $opt .= " -newkey rsa:2048";
                   $opt .= " -keyout ${General::swroot}/certs/hostkey.pem";
                   $opt .= " -out ${General::swroot}/certs/hostreq.pem";
                $errormessage = &callssl ($opt);
@@ -1018,7 +1012,7 @@ END
            print $fh "subjectAltName=$cgiparams{'SUBJECTALTNAME'}" if ($cgiparams{'SUBJECTALTNAME'});
            close ($fh);
            
-           my  $opt  = " ca -days 999999";
+           my  $opt  = " ca -md sha256 -days 999999";
                $opt .= " -batch -notext";
                $opt .= " -in ${General::swroot}/certs/hostreq.pem";
                $opt .= " -out ${General::swroot}/certs/hostcert.pem";
@@ -1052,7 +1046,7 @@ END
 
     ROOTCERT_ERROR:
     &Header::showhttpheaders();
-    &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+    &Header::openpage($Lang::tr{'ipsec'}, 1, '');
     &Header::openbigbox('100%', 'left', '', $errormessage);
     if ($errormessage) {
         &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
@@ -1097,7 +1091,7 @@ END
         <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}</font></b>: 
         $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'}
     </td></tr>
-    <tr><td colspan='2'><hr /></td></tr>
+    <tr><td colspan='2'><hr></td></tr>
     <tr><td class='base' nowrap='nowrap'>$Lang::tr{'upload p12 file'}:</td>
         <td nowrap='nowrap'><input type='file' name='FH' size='32' /></td></tr>
     <tr><td class='base'>$Lang::tr{'pkcs12 file password'}:&nbsp;<img src='/blob.gif' alt='*' /></td>
@@ -1139,7 +1133,7 @@ END
 
     if ( -f "${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") {
        &Header::showhttpheaders();
-       &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+       &Header::openpage($Lang::tr{'ipsec'}, 1, '');
        &Header::openbigbox('100%', 'left', '', '');
        &Header::openbox('100%', 'left', "$Lang::tr{'cert'}:");
        my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`;
@@ -1223,13 +1217,13 @@ END
     } else {
        $errormessage = $Lang::tr{'invalid key'};
     }
-
+       &General::firewall_reload();
 ###
 ### Choose between adding a host-net or net-net connection
 ###
 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'add'} && $cgiparams{'TYPE'} eq '') {
        &Header::showhttpheaders();
-       &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+       &Header::openpage($Lang::tr{'ipsec'}, 1, '');
        &Header::openbigbox('100%', 'left', '', '');
        &Header::openbox('100%', 'left', $Lang::tr{'connection type'});
        print <<END
@@ -1288,6 +1282,9 @@ END
        $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];
@@ -1295,6 +1292,7 @@ END
        $cgiparams{'VHOST'}             = $confighash{$cgiparams{'KEY'}}[14];
        $cgiparams{'DPD_TIMEOUT'}               = $confighash{$cgiparams{'KEY'}}[30];
        $cgiparams{'DPD_DELAY'}         = $confighash{$cgiparams{'KEY'}}[31];
+       $cgiparams{'FORCE_MOBIKE'}      = $confighash{$cgiparams{'KEY'}}[32];
 
        if (!$cgiparams{'DPD_DELAY'}) {
                $cgiparams{'DPD_DELAY'} = 30;
@@ -1405,14 +1403,13 @@ END
            goto VPNCONF_ERROR;
        }
 
-#temporary disabled (BUG 10294)
-#      if ($cgiparams{'TYPE'} eq 'net'){
-#              $errormessage=&General::checksubnets($cgiparams{'NAME'},$cgiparams{'REMOTE_SUBNET'});
-#              if ($errormessage ne ''){
-#                      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'};
@@ -1442,7 +1439,7 @@ END
 
            # Sign the certificate request
            &General::log("ipsec", "Signing your cert $cgiparams{'NAME'}...");
-           my  $opt  = " ca -days 999999";
+           my  $opt  = " ca -md sha256 -days 999999";
                $opt .= " -batch -notext";
                $opt .= " -in $filename";
                $opt .= " -out ${General::swroot}/certs/$cgiparams{'NAME'}cert.pem";
@@ -1672,12 +1669,12 @@ END
            (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./;
            (my $state = $cgiparams{'CERT_STATE'}) =~ s/^\s*$/\./;
 
-           # Create the Host certificate request
+           # Create the Client certificate request
            &General::log("ipsec", "Creating a cert...");
 
            if (open(STDIN, "-|")) {
                my $opt  = " req -nodes -rand /proc/interrupts:/proc/net/rt_cache";
-                  $opt .= " -newkey rsa:1024";
+                  $opt .= " -newkey rsa:2048";
                   $opt .= " -keyout ${General::swroot}/certs/$cgiparams{'NAME'}key.pem";
                   $opt .= " -out ${General::swroot}/certs/$cgiparams{'NAME'}req.pem";
 
@@ -1699,7 +1696,7 @@ END
                exit (0);
            }
            
-           # Sign the host certificate request
+           # Sign the client certificate request
            &General::log("ipsec", "Signing the cert $cgiparams{'NAME'}...");
 
            #No easy way for specifying the contain of subjectAltName without writing a config file...
@@ -1708,13 +1705,14 @@ END
            basicConstraints=CA:FALSE
            nsComment="OpenSSL Generated Certificate"
            subjectKeyIdentifier=hash
+           extendedKeyUsage=clientAuth
            authorityKeyIdentifier=keyid,issuer:always
 END
 ;
            print $fh "subjectAltName=$cgiparams{'SUBJECTALTNAME'}" if ($cgiparams{'SUBJECTALTNAME'});
            close ($fh);
 
-           my $opt  = " ca -days 999999 -batch -notext";
+           my $opt  = " ca -md sha256 -days 999999 -batch -notext";
               $opt .= " -in ${General::swroot}/certs/$cgiparams{'NAME'}req.pem";
               $opt .= " -out ${General::swroot}/certs/$cgiparams{'NAME'}cert.pem";
               $opt .= " -extfile $v3extname";
@@ -1777,7 +1775,7 @@ END
        my $key = $cgiparams{'KEY'};
        if (! $key) {
            $key = &General::findhasharraykey (\%confighash);
-           foreach my $i (0 .. 31) { $confighash{$key}[$i] = "";}
+           foreach my $i (0 .. 32) { $confighash{$key}[$i] = "";}
        }
        $confighash{$key}[0] = $cgiparams{'ENABLED'};
        $confighash{$key}[1] = $cgiparams{'NAME'};
@@ -1819,6 +1817,7 @@ END
        $confighash{$key}[14] = $cgiparams{'VHOST'};
        $confighash{$key}[30] = $cgiparams{'DPD_TIMEOUT'};
        $confighash{$key}[31] = $cgiparams{'DPD_DELAY'};
+       $confighash{$key}[32] = $cgiparams{'FORCE_MOBIKE'};
 
        #free unused fields!
        $confighash{$key}[6] = 'off';
@@ -1867,6 +1866,10 @@ END
                $cgiparams{'DPD_TIMEOUT'} = 120;
        }
 
+       if (!$cgiparams{'FORCE_MOBIKE'}) {
+               $cgiparams{'FORCE_MOBIKE'} = 'no';
+       }
+
        # Default IKE Version to v2
        if (!$cgiparams{'IKE_VERSION'}) {
            $cgiparams{'IKE_VERSION'} = 'ikev2';
@@ -1877,13 +1880,13 @@ END
        $cgiparams{'REMOTE_ID'} = '';
 
        #use default advanced value
-       $cgiparams{'IKE_ENCRYPTION'} = 'aes256|aes192|aes128|3des';     #[18];
-       $cgiparams{'IKE_INTEGRITY'}  = 'sha2_256|sha|md5';      #[19];
+       $cgiparams{'IKE_ENCRYPTION'} = 'aes256gcm128|aes256gcm96|aes256gcm64|aes256|aes192gcm128|aes192gcm96|aes192gcm64|aes192|aes128gcm128|aes128gcm96|aes128gcm64|aes128';   #[18];
+       $cgiparams{'IKE_INTEGRITY'}  = 'sha2_512|sha2_256|sha'; #[19];
        $cgiparams{'IKE_GROUPTYPE'}  = '4096|3072|2048|1536|1024';              #[20];
        $cgiparams{'IKE_LIFETIME'}   = '3';             #[16];
-       $cgiparams{'ESP_ENCRYPTION'} = 'aes256|aes192|aes128|3des';     #[21];
-       $cgiparams{'ESP_INTEGRITY'}  = 'sha2_256|sha1|md5';     #[22];
-       $cgiparams{'ESP_GROUPTYPE'}  = '';              #[23];
+       $cgiparams{'ESP_ENCRYPTION'} = 'aes256gcm128|aes256gcm96|aes256gcm64|aes256|aes192gcm128|aes192gcm96|aes192gcm64|aes192|aes128gcm128|aes128gcm96|aes128gcm64|aes128';   #[21];
+       $cgiparams{'ESP_INTEGRITY'}  = 'sha2_512|sha2_256|sha1';        #[22];
+       $cgiparams{'ESP_GROUPTYPE'}  = '4096|3072|2048|1536|1024';              #[23];
        $cgiparams{'ESP_KEYLIFE'}    = '1';             #[17];
        $cgiparams{'COMPRESSION'}    = 'on';            #[13];
        $cgiparams{'ONLY_PROPOSED'}  = 'off';           #[24];
@@ -1909,7 +1912,7 @@ END
     $checked{'AUTH'}{$cgiparams{'AUTH'}} = "checked='checked'";
 
     &Header::showhttpheaders();
-    &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+    &Header::openpage($Lang::tr{'ipsec'}, 1, '');
     &Header::openbigbox('100%', 'left', '', $errormessage);
     if ($errormessage) {
        &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
@@ -1944,6 +1947,7 @@ END
        <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'}) {
@@ -2136,7 +2140,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
            goto ADVANCED_ERROR;
        }
        foreach my $val (@temp) {
-           if ($val !~ /^(aes256|aes192|aes128|3des|camellia256|camellia192|camellia128)$/) {
+           if ($val !~ /^(aes(256|192|128)(gcm(128|96|64))?|3des|camellia(256|192|128))$/) {
                $errormessage = $Lang::tr{'invalid input'};
                goto ADVANCED_ERROR;
            }
@@ -2147,7 +2151,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
            goto ADVANCED_ERROR;
        }
        foreach my $val (@temp) {
-           if ($val !~ /^(sha2_512|sha2_384|sha2_256|sha|md5|aesxcbc)$/) {
+           if ($val !~ /^(sha2_(512|384|256)|sha|md5|aesxcbc)$/) {
                $errormessage = $Lang::tr{'invalid input'};
                goto ADVANCED_ERROR;
            }
@@ -2177,7 +2181,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
            goto ADVANCED_ERROR;
        }
        foreach my $val (@temp) {
-           if ($val !~ /^(aes256|aes192|aes128|3des|camellia256|camellia192|camellia128)$/) {
+           if ($val !~ /^(aes(256|192|128)(gcm(128|96|64))?|3des|camellia(256|192|128))$/) {
                $errormessage = $Lang::tr{'invalid input'};
                goto ADVANCED_ERROR;
            }
@@ -2188,18 +2192,22 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
            goto ADVANCED_ERROR;
        }
        foreach my $val (@temp) {
-           if ($val !~ /^(sha2_512|sha2_384|sha2_256|sha1|md5|aesxcbc)$/) {
+           if ($val !~ /^(sha2_(512|384|256)|sha1|md5|aesxcbc)$/) {
                $errormessage = $Lang::tr{'invalid input'};
                goto ADVANCED_ERROR;
            }
        }
-       if ($cgiparams{'ESP_GROUPTYPE'} ne '' &&
-           $cgiparams{'ESP_GROUPTYPE'} !~  /^ecp(192|224|256|384|512)(bp)?$/ &&
-           $cgiparams{'ESP_GROUPTYPE'} !~  /^modp(1024|1536|2048|2048s(256|224|160)|3072|4096|6144|8192)$/) {
+       @temp = split('\|', $cgiparams{'ESP_GROUPTYPE'});
+       if ($#temp < 0) {
            $errormessage = $Lang::tr{'invalid input'};
            goto ADVANCED_ERROR;
        }
-
+       foreach my $val (@temp) {
+           if ($val !~ /^(e521|e384|e256|e224|e192|e512bp|e384bp|e256bp|e224bp|1024|1536|2048|2048s256|2048s224|2048s160|3072|4096|6144|8192|none)$/) {
+               $errormessage = $Lang::tr{'invalid input'};
+               goto ADVANCED_ERROR;
+           }
+       }
        if ($cgiparams{'ESP_KEYLIFE'} !~ /^\d+$/) {
            $errormessage = $Lang::tr{'invalid input for esp keylife'};
            goto ADVANCED_ERROR;
@@ -2211,6 +2219,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
 
        if (
            ($cgiparams{'COMPRESSION'} !~ /^(|on|off)$/) ||
+           ($cgiparams{'FORCE_MOBIKE'} !~ /^(|on|off)$/) ||
            ($cgiparams{'ONLY_PROPOSED'} !~ /^(|on|off)$/) ||
            ($cgiparams{'PFS'} !~ /^(|on|off)$/) ||
            ($cgiparams{'VHOST'} !~ /^(|on|off)$/)
@@ -2246,6 +2255,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
        $confighash{$cgiparams{'KEY'}}[27] = $cgiparams{'DPD_ACTION'};
        $confighash{$cgiparams{'KEY'}}[30] = $cgiparams{'DPD_TIMEOUT'};
        $confighash{$cgiparams{'KEY'}}[31] = $cgiparams{'DPD_DELAY'};
+       $confighash{$cgiparams{'KEY'}}[32] = $cgiparams{'FORCE_MOBIKE'};
        &General::writehasharray("${General::swroot}/vpn/config", \%confighash);
        &writeipsecfiles();
        if (&vpnenabled) {
@@ -2262,6 +2272,9 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
        $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];
@@ -2270,6 +2283,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
        $cgiparams{'DPD_ACTION'}     = $confighash{$cgiparams{'KEY'}}[27];
        $cgiparams{'DPD_TIMEOUT'}    = $confighash{$cgiparams{'KEY'}}[30];
        $cgiparams{'DPD_DELAY'}      = $confighash{$cgiparams{'KEY'}}[31];
+       $cgiparams{'FORCE_MOBIKE'}   = $confighash{$cgiparams{'KEY'}}[32];
 
        if (!$cgiparams{'DPD_DELAY'}) {
                $cgiparams{'DPD_DELAY'} = 30;
@@ -2288,6 +2302,15 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
     $checked{'IKE_ENCRYPTION'}{'aes256'} = '';
     $checked{'IKE_ENCRYPTION'}{'aes192'} = '';
     $checked{'IKE_ENCRYPTION'}{'aes128'} = '';
+    $checked{'IKE_ENCRYPTION'}{'aes256gcm128'} = '';
+    $checked{'IKE_ENCRYPTION'}{'aes192gcm128'} = '';
+    $checked{'IKE_ENCRYPTION'}{'aes128gcm128'} = '';
+    $checked{'IKE_ENCRYPTION'}{'aes256gcm96'} = '';
+    $checked{'IKE_ENCRYPTION'}{'aes192gcm96'} = '';
+    $checked{'IKE_ENCRYPTION'}{'aes128gcm96'} = '';
+    $checked{'IKE_ENCRYPTION'}{'aes256gcm64'} = '';
+    $checked{'IKE_ENCRYPTION'}{'aes192gcm64'} = '';
+    $checked{'IKE_ENCRYPTION'}{'aes128gcm64'} = '';
     $checked{'IKE_ENCRYPTION'}{'3des'} = '';
     $checked{'IKE_ENCRYPTION'}{'camellia256'} = '';
     $checked{'IKE_ENCRYPTION'}{'camellia192'} = '';
@@ -2319,6 +2342,15 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
     $checked{'ESP_ENCRYPTION'}{'aes256'} = '';
     $checked{'ESP_ENCRYPTION'}{'aes192'} = '';
     $checked{'ESP_ENCRYPTION'}{'aes128'} = '';
+    $checked{'ESP_ENCRYPTION'}{'aes256gcm128'} = '';
+    $checked{'ESP_ENCRYPTION'}{'aes192gcm128'} = '';
+    $checked{'ESP_ENCRYPTION'}{'aes128gcm128'} = '';
+    $checked{'ESP_ENCRYPTION'}{'aes256gcm96'} = '';
+    $checked{'ESP_ENCRYPTION'}{'aes192gcm96'} = '';
+    $checked{'ESP_ENCRYPTION'}{'aes128gcm96'} = '';
+    $checked{'ESP_ENCRYPTION'}{'aes256gcm64'} = '';
+    $checked{'ESP_ENCRYPTION'}{'aes192gcm64'} = '';
+    $checked{'ESP_ENCRYPTION'}{'aes128gcm64'} = '';
     $checked{'ESP_ENCRYPTION'}{'3des'} = '';
     $checked{'ESP_ENCRYPTION'}{'camellia256'} = '';
     $checked{'ESP_ENCRYPTION'}{'camellia192'} = '';
@@ -2333,9 +2365,20 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
     $checked{'ESP_INTEGRITY'}{'aesxcbc'} = '';
     @temp = split('\|', $cgiparams{'ESP_INTEGRITY'});
     foreach my $key (@temp) {$checked{'ESP_INTEGRITY'}{$key} = "selected='selected'"; }
-    $checked{'ESP_GROUPTYPE'}{$cgiparams{'ESP_GROUPTYPE'}} = "selected='selected'";
+    $checked{'ESP_GROUPTYPE'}{'768'} = '';
+    $checked{'ESP_GROUPTYPE'}{'1024'} = '';
+    $checked{'ESP_GROUPTYPE'}{'1536'} = '';
+    $checked{'ESP_GROUPTYPE'}{'2048'} = '';
+    $checked{'ESP_GROUPTYPE'}{'3072'} = '';
+    $checked{'ESP_GROUPTYPE'}{'4096'} = '';
+    $checked{'ESP_GROUPTYPE'}{'6144'} = '';
+    $checked{'ESP_GROUPTYPE'}{'8192'} = '';
+    $checked{'ESP_GROUPTYPE'}{'none'} = '';
+    @temp = split('\|', $cgiparams{'ESP_GROUPTYPE'});
+    foreach my $key (@temp) {$checked{'ESP_GROUPTYPE'}{$key} = "selected='selected'"; }
 
     $checked{'COMPRESSION'} = $cgiparams{'COMPRESSION'} eq 'on' ? "checked='checked'" : '' ;
+    $checked{'FORCE_MOBIKE'} = $cgiparams{'FORCE_MOBIKE'} eq 'on' ? "checked='checked'" : '' ;
     $checked{'ONLY_PROPOSED'} = $cgiparams{'ONLY_PROPOSED'} eq 'on' ? "checked='checked'" : '' ;
     $checked{'PFS'} = $cgiparams{'PFS'} eq 'on' ? "checked='checked'" : '' ;
     $checked{'VHOST'} = $cgiparams{'VHOST'} eq 'on' ? "checked='checked'" : '' ;
@@ -2351,7 +2394,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
     $selected{'DPD_ACTION'}{$cgiparams{'DPD_ACTION'}} = "selected='selected'";
 
     &Header::showhttpheaders();
-    &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+    &Header::openpage($Lang::tr{'ipsec'}, 1, '');
     &Header::openbigbox('100%', 'left', '', $errormessage);
 
     if ($errormessage) {
@@ -2397,24 +2440,42 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
                        <td class='boldbase' width="15%">$Lang::tr{'encryption'}</td>
                        <td class='boldbase'>
                                <select name='IKE_ENCRYPTION' multiple='multiple' size='6' style='width: 100%'>
-                                       <option value='aes256' $checked{'IKE_ENCRYPTION'}{'aes256'}>AES (256 bit)</option>
-                                       <option value='aes192' $checked{'IKE_ENCRYPTION'}{'aes192'}>AES (192 bit)</option>
-                                       <option value='aes128' $checked{'IKE_ENCRYPTION'}{'aes128'}>AES (128 bit)</option>
-                                       <option value='3des' $checked{'IKE_ENCRYPTION'}{'3des'}>3DES</option>
-                                       <option value='camellia256' $checked{'IKE_ENCRYPTION'}{'camellia256'}>Camellia (256 bit)</option>
-                                       <option value='camellia192' $checked{'IKE_ENCRYPTION'}{'camellia192'}>Camellia (192 bit)</option>
-                                       <option value='camellia128' $checked{'IKE_ENCRYPTION'}{'camellia128'}>Camellia (128 bit)</option>
+                                       <option value='aes256gcm128' $checked{'IKE_ENCRYPTION'}{'aes256gcm128'}>256 bit AES-GCM/128 bit ICV</option>
+                                       <option value='aes256gcm96' $checked{'IKE_ENCRYPTION'}{'aes256gcm96'}>256 bit AES-GCM/96 bit ICV</option>
+                                       <option value='aes256gcm64' $checked{'IKE_ENCRYPTION'}{'aes256gcm64'}>256 bit AES-GCM/64 bit ICV</option>
+                                       <option value='aes256' $checked{'IKE_ENCRYPTION'}{'aes256'}>256 bit AES-CBC</option>
+                                       <option value='camellia256' $checked{'IKE_ENCRYPTION'}{'camellia256'}>256 bit Camellia-CBC</option>
+                                       <option value='aes192gcm128' $checked{'IKE_ENCRYPTION'}{'aes192gcm128'}>192 bit AES-GCM/128 bit ICV</option>
+                                       <option value='aes192gcm96' $checked{'IKE_ENCRYPTION'}{'aes192gcm96'}>192 bit AES-GCM/96 bit ICV</option>
+                                       <option value='aes192gcm64' $checked{'IKE_ENCRYPTION'}{'aes192gcm64'}>192 bit AES-GCM/64 bit ICV</option>
+                                       <option value='aes192' $checked{'IKE_ENCRYPTION'}{'aes192'}>192 bit AES-CBC</option>
+                                       <option value='camellia192' $checked{'IKE_ENCRYPTION'}{'camellia192'}>192 bit Camellia-CBC</option>
+                                       <option value='aes128gcm128' $checked{'IKE_ENCRYPTION'}{'aes128gcm128'}>128 bit AES-GCM/128 bit ICV</option>
+                                       <option value='aes128gcm96' $checked{'IKE_ENCRYPTION'}{'aes128gcm96'}>128 bit AES-GCM/96 bit ICV</option>
+                                       <option value='aes128gcm64' $checked{'IKE_ENCRYPTION'}{'aes128gcm64'}>128 bit AES-GCM/64 bit ICV</option>
+                                       <option value='aes128' $checked{'IKE_ENCRYPTION'}{'aes128'}>128 bit AES-CBC</option>
+                                       <option value='camellia128' $checked{'IKE_ENCRYPTION'}{'camellia128'}>128 bit Camellia-CBC</option>
+                                       <option value='3des' $checked{'IKE_ENCRYPTION'}{'3des'}>168 bit 3DES-EDE-CBC</option>
                                </select>
                        </td>
                        <td class='boldbase'>
                                <select name='ESP_ENCRYPTION' multiple='multiple' size='6' style='width: 100%'>
-                                       <option value='aes256' $checked{'ESP_ENCRYPTION'}{'aes256'}>AES (256 bit)</option>
-                                       <option value='aes192' $checked{'ESP_ENCRYPTION'}{'aes192'}>AES (192 bit)</option>
-                                       <option value='aes128' $checked{'ESP_ENCRYPTION'}{'aes128'}>AES (128 bit)</option>
-                                       <option value='3des' $checked{'ESP_ENCRYPTION'}{'3des'}>3DES</option>
-                                       <option value='camellia256' $checked{'ESP_ENCRYPTION'}{'camellia256'}>Camellia (256 bit)</option>
-                                       <option value='camellia192' $checked{'ESP_ENCRYPTION'}{'camellia192'}>Camellia (192 bit)</option>
-                                       <option value='camellia128' $checked{'ESP_ENCRYPTION'}{'camellia128'}>Camellia (128 bit)</option>
+                                       <option value='aes256gcm128' $checked{'ESP_ENCRYPTION'}{'aes256gcm128'}>256 bit AES-GCM/128 bit ICV</option>
+                                       <option value='aes256gcm96' $checked{'ESP_ENCRYPTION'}{'aes256gcm96'}>256 bit AES-GCM/96 bit ICV</option>
+                                       <option value='aes256gcm64' $checked{'ESP_ENCRYPTION'}{'aes256gcm64'}>256 bit AES-GCM/64 bit ICV</option>
+                                       <option value='aes256' $checked{'ESP_ENCRYPTION'}{'aes256'}>256 bit AES-CBC</option>
+                                       <option value='camellia256' $checked{'ESP_ENCRYPTION'}{'camellia256'}>256 bit Camellia-CBC</option>
+                                       <option value='aes192gcm128' $checked{'ESP_ENCRYPTION'}{'aes192gcm128'}>192 bit AES-GCM/128 bit ICV</option>
+                                       <option value='aes192gcm96' $checked{'ESP_ENCRYPTION'}{'aes192gcm96'}>192 bit AES-GCM/96 bit ICV</option>
+                                       <option value='aes192gcm64' $checked{'ESP_ENCRYPTION'}{'aes192gcm64'}>192 bit AES-GCM/64 bit ICV</option>
+                                       <option value='aes192' $checked{'ESP_ENCRYPTION'}{'aes192'}>192 bit AES-CBC</option>
+                                       <option value='camellia192' $checked{'ESP_ENCRYPTION'}{'camellia192'}>192 bit Camellia-CBC</option>
+                                       <option value='aes128gcm128' $checked{'ESP_ENCRYPTION'}{'aes128gcm128'}>128 bit AES-GCM/128 bit ICV</option>
+                                       <option value='aes128gcm96' $checked{'ESP_ENCRYPTION'}{'aes128gcm96'}>128 bit AES-GCM/96 bit ICV</option>
+                                       <option value='aes128gcm64' $checked{'ESP_ENCRYPTION'}{'aes128gcm64'}>128 bit AES-GCM/64 bit ICV</option>
+                                       <option value='aes128' $checked{'ESP_ENCRYPTION'}{'aes128'}>128 bit AES-CBC</option>
+                                       <option value='camellia128' $checked{'ESP_ENCRYPTION'}{'camellia128'}>128 bit Camellia-CBC</option>
+                                       <option value='3des' $checked{'ESP_ENCRYPTION'}{'3des'}>168 bit 3DES-EDE-CBC</option>
                                </select>
                        </td>
                </tr>
@@ -2426,9 +2487,9 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
                                        <option value='sha2_512' $checked{'IKE_INTEGRITY'}{'sha2_512'}>SHA2 512 bit</option>
                                        <option value='sha2_384' $checked{'IKE_INTEGRITY'}{'sha2_384'}>SHA2 384 bit</option>
                                        <option value='sha2_256' $checked{'IKE_INTEGRITY'}{'sha2_256'}>SHA2 256 bit</option>
+                                       <option value='aesxcbc' $checked{'IKE_INTEGRITY'}{'aesxcbc'}>AES XCBC</option>
                                        <option value='sha' $checked{'IKE_INTEGRITY'}{'sha'}>SHA1</option>
                                        <option value='md5' $checked{'IKE_INTEGRITY'}{'md5'}>MD5</option>
-                                       <option value='aesxcbc' $checked{'IKE_INTEGRITY'}{'aesxcbc'}>AES XCBC</option>
                                </select>
                        </td>
                        <td class='boldbase'>
@@ -2436,9 +2497,9 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
                                        <option value='sha2_512' $checked{'ESP_INTEGRITY'}{'sha2_512'}>SHA2 512 bit</option>
                                        <option value='sha2_384' $checked{'ESP_INTEGRITY'}{'sha2_384'}>SHA2 384 bit</option>
                                        <option value='sha2_256' $checked{'ESP_INTEGRITY'}{'sha2_256'}>SHA2 256 bit</option>
+                                       <option value='aesxcbc' $checked{'ESP_INTEGRITY'}{'aesxcbc'}>AES XCBC</option>
                                        <option value='sha1' $checked{'ESP_INTEGRITY'}{'sha1'}>SHA1</option>
                                        <option value='md5' $checked{'ESP_INTEGRITY'}{'md5'}>MD5</option>
-                                       <option value='aesxcbc' $checked{'ESP_INTEGRITY'}{'aesxcbc'}>AES XCBC</option>
                                </select>
                        </td>
                </tr>
@@ -2456,14 +2517,14 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
                        <td class='boldbase'>
                                <select name='IKE_GROUPTYPE' multiple='multiple' size='6' style='width: 100%'>
                                        <option value='e521' $checked{'IKE_GROUPTYPE'}{'e521'}>ECP-521 (NIST)</option>
-                                       <option value='e384' $checked{'IKE_GROUPTYPE'}{'e384'}>ECP-384 (NIST)</option>
-                                       <option value='e256' $checked{'IKE_GROUPTYPE'}{'e256'}>ECP-256 (NIST)</option>
-                                       <option value='e224' $checked{'IKE_GROUPTYPE'}{'e224'}>ECP-224 (NIST)</option>
-                                       <option value='e192' $checked{'IKE_GROUPTYPE'}{'e192'}>ECP-192 (NIST)</option>
                                        <option value='e512bp' $checked{'IKE_GROUPTYPE'}{'e512bp'}>ECP-512 (Brainpool)</option>
+                                       <option value='e384' $checked{'IKE_GROUPTYPE'}{'e384'}>ECP-384 (NIST)</option>
                                        <option value='e384bp' $checked{'IKE_GROUPTYPE'}{'e384bp'}>ECP-384 (Brainpool)</option>
+                                       <option value='e256' $checked{'IKE_GROUPTYPE'}{'e256'}>ECP-256 (NIST)</option>
                                        <option value='e256bp' $checked{'IKE_GROUPTYPE'}{'e256bp'}>ECP-256 (Brainpool)</option>
+                                       <option value='e224' $checked{'IKE_GROUPTYPE'}{'e224'}>ECP-224 (NIST)</option>
                                        <option value='e224bp' $checked{'IKE_GROUPTYPE'}{'e224bp'}>ECP-224 (Brainpool)</option>
+                                       <option value='e192' $checked{'IKE_GROUPTYPE'}{'e192'}>ECP-192 (NIST)</option>
                                        <option value='8192' $checked{'IKE_GROUPTYPE'}{'8192'}>MODP-8192</option>
                                        <option value='6144' $checked{'IKE_GROUPTYPE'}{'6144'}>MODP-6144</option>
                                        <option value='4096' $checked{'IKE_GROUPTYPE'}{'4096'}>MODP-4096</option>
@@ -2476,7 +2537,30 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
                                        <option value='1024' $checked{'IKE_GROUPTYPE'}{'1024'}>MODP-1024</option>
                                </select>
                        </td>
-                       <td></td>
+                       <td class='boldbase'>
+                               <select name='ESP_GROUPTYPE' multiple='multiple' size='6' style='width: 100%'>
+                                       <option value='e521' $checked{'ESP_GROUPTYPE'}{'e521'}>ECP-521 (NIST)</option>
+                                       <option value='e512bp' $checked{'ESP_GROUPTYPE'}{'e512bp'}>ECP-512 (Brainpool)</option>
+                                       <option value='e384' $checked{'ESP_GROUPTYPE'}{'e384'}>ECP-384 (NIST)</option>
+                                       <option value='e384bp' $checked{'ESP_GROUPTYPE'}{'e384bp'}>ECP-384 (Brainpool)</option>
+                                       <option value='e256' $checked{'ESP_GROUPTYPE'}{'e256'}>ECP-256 (NIST)</option>
+                                       <option value='e256bp' $checked{'ESP_GROUPTYPE'}{'e256bp'}>ECP-256 (Brainpool)</option>
+                                       <option value='e224' $checked{'ESP_GROUPTYPE'}{'e224'}>ECP-224 (NIST)</option>
+                                       <option value='e224bp' $checked{'ESP_GROUPTYPE'}{'e224bp'}>ECP-224 (Brainpool)</option>
+                                       <option value='e192' $checked{'ESP_GROUPTYPE'}{'e192'}>ECP-192 (NIST)</option>
+                                       <option value='8192' $checked{'ESP_GROUPTYPE'}{'8192'}>MODP-8192</option>
+                                       <option value='6144' $checked{'ESP_GROUPTYPE'}{'6144'}>MODP-6144</option>
+                                       <option value='4096' $checked{'ESP_GROUPTYPE'}{'4096'}>MODP-4096</option>
+                                       <option value='3072' $checked{'ESP_GROUPTYPE'}{'3072'}>MODP-3072</option>
+                                       <option value='2048s256' $checked{'ESP_GROUPTYPE'}{'2048s256'}>MODP-2048/256</option>
+                                       <option value='2048s224' $checked{'ESP_GROUPTYPE'}{'2048s224'}>MODP-2048/224</option>
+                                       <option value='2048s160' $checked{'ESP_GROUPTYPE'}{'2048s160'}>MODP-2048/160</option>
+                                       <option value='2048' $checked{'ESP_GROUPTYPE'}{'2048'}>MODP-2048</option>
+                                       <option value='1536' $checked{'ESP_GROUPTYPE'}{'1536'}>MODP-1536</option>
+                                       <option value='1024' $checked{'ESP_GROUPTYPE'}{'1024'}>MODP-1024</option>
+                                       <option value='none' $checked{'ESP_GROUPTYPE'}{'none'}>- $Lang::tr{'none'} -</option>
+                               </select>
+                       </td>
                </tr>
        </tbody>
     </table>
@@ -2518,7 +2602,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
                <td>
                        <label>
                                <input type='checkbox' name='ONLY_PROPOSED' $checked{'ONLY_PROPOSED'} />
-                               IKE+ESP: $Lang::tr{'use only proposed settings'}</td>
+                               IKE+ESP: $Lang::tr{'use only proposed settings'}
                        </label>
                </td>
        </tr>
@@ -2538,6 +2622,14 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) ||
                        </label>
                </td>
        </tr>
+       <tr>
+               <td>
+                       <label>
+                               <input type='checkbox' name='FORCE_MOBIKE' $checked{'FORCE_MOBIKE'} />
+                               $Lang::tr{'vpn force mobike'}
+                       </label>
+               </td>
+       </tr>
 EOF
     ;
     if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') {
@@ -2600,7 +2692,7 @@ EOF
     $checked{'ENABLED'} = $cgiparams{'ENABLED'} eq 'on' ? "checked='checked'" : '';
 
     &Header::showhttpheaders();
-    &Header::openpage($Lang::tr{'vpn configuration main'}, 1, '');
+    &Header::openpage($Lang::tr{'ipsec'}, 1, '');
     &Header::openbigbox('100%', 'left', '', $errormessage);
 
     if ($errormessage) {
@@ -2610,6 +2702,16 @@ EOF
        &Header::closebox();
     }
 
+       if ($warnmessage) {
+               &Header::openbox('100%', 'left', $Lang::tr{'warning messages'});
+               print "$warnmessage<br>";
+               print "$Lang::tr{'fwdfw warn1'}<br>";
+               &Header::closebox();
+               print"<center><form method='post'><input type='submit' name='ACTION' value='$Lang::tr{'ok'}' style='width: 5em;'></form>";
+               &Header::closepage();
+               exit 0;
+       }
+
     &Header::openbox('100%', 'left', $Lang::tr{'global settings'});
     print <<END
     <form method='post' action='$ENV{'SCRIPT_NAME'}'>
@@ -2630,17 +2732,18 @@ print <<END
        <td  class='base' nowrap='nowrap'>$Lang::tr{'host to net vpn'}:&nbsp;<img src='/blob.gif' alt='*' /></td>
        <td ><input type='text' name='RW_NET' value='$cgiparams{'RW_NET'}' /></td>
     </tr>
- </table>
+</table>
+<br>
 <hr />
 <table width='100%'>
 <tr>
     <td class='base' valign='top'><img src='/blob.gif' alt='*' /></td>
-    <td width='70%' class='base' valign='top'>$Lang::tr{'this field may be blank'}</td>
+    <td width='70%' class='base' valign='top'>$Lang::tr{'this field may be blank'}</td><td width='30%' align='right' class='base'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td>
 </tr>
 <tr>
     <td class='base' valign='top' nowrap='nowrap'><img src='/blob.gif' alt='*' /><img src='/blob.gif' alt='*' />&nbsp;</td>
     <td class='base'>  <font class='base'>$Lang::tr{'vpn delayed start help'}</font></td>
-    <td width='30%' align='center' class='base'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td>
+    <td></td>
 </tr>
 </table>
 END
@@ -2650,14 +2753,14 @@ END
 
     &Header::openbox('100%', 'left', $Lang::tr{'connection status and controlc'});
     print <<END
-    <table width='100%' border='0' cellspacing='1' cellpadding='0'>
+    <table width='100%' cellspacing='1' cellpadding='0' class='tbl'>
     <tr>
-       <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
-       <td width='22%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></td>
-       <td width='23%' class='boldbase' align='center'><b>$Lang::tr{'common name'}</b></td>
-       <td width='30%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></td>
-       <td width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></td>
-       <td class='boldbase' align='center' colspan='6'><b>$Lang::tr{'action'}</b></td>
+       <th width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></th>
+       <th width='22%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></th>
+       <th width='23%' class='boldbase' align='center'><b>$Lang::tr{'common name'}</b></th>
+       <th width='30%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></th>
+       <th width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></th>
+       <th class='boldbase' align='center' colspan='6'><b>$Lang::tr{'action'}</b></th>
     </tr>
 END
     ;
@@ -2667,36 +2770,41 @@ END
        if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
 
        if ($id % 2) {
-           print "<tr bgcolor='$color{'color20'}'>\n";
+               print "<tr>";
+               $col="bgcolor='$color{'color20'}'";
        } else {
-           print "<tr bgcolor='$color{'color22'}'>\n";
+               print "<tr>";
+               $col="bgcolor='$color{'color22'}'";
        }
-       print "<td align='center' nowrap='nowrap'>$confighash{$key}[1]</td>";
-       print "<td align='center' nowrap='nowrap'>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ") $confighash{$key}[29]</td>";
+       print "<td align='center' nowrap='nowrap' $col>$confighash{$key}[1]</td>";
+       print "<td align='center' nowrap='nowrap' $col>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ") $confighash{$key}[29]</td>";
        if ($confighash{$key}[2] eq '%auth-dn') {
-           print "<td align='left' nowrap='nowrap'>$confighash{$key}[9]</td>";
+           print "<td align='left' nowrap='nowrap' $col>$confighash{$key}[9]</td>";
        } elsif ($confighash{$key}[4] eq 'cert') {
-           print "<td align='left' nowrap='nowrap'>$confighash{$key}[2]</td>";
+           print "<td align='left' nowrap='nowrap' $col>$confighash{$key}[2]</td>";
        } else {
-           print "<td align='left'>&nbsp;</td>";
+           print "<td align='left' $col>&nbsp;</td>";
        }
-       print "<td align='center'>$confighash{$key}[25]</td>";
+       print "<td align='center' $col>$confighash{$key}[25]</td>";
+       my $col1="bgcolor='${Header::colourred}'";
        # get real state
-       my $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourred}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>";
+       my $active = "<b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b>";
        foreach my $line (@status) {
            if (($line =~ /\"$confighash{$key}[1]\".*IPsec SA established/) ||
               ($line =~ /$confighash{$key}[1]\{.*INSTALLED/))
            {
-               $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourgreen}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsopen'}</font></b></td></tr></table>";
+               $col1="bgcolor='${Header::colourgreen}'";
+               $active = "<b><font color='#FFFFFF'>$Lang::tr{'capsopen'}</font></b>";
            }
        }
        # move to blueif really down
-       if ($confighash{$key}[0] eq 'off' && $active =~ /${Header::colourred}/ ) {
-           $active = "<table cellpadding='2' cellspacing='0' bgcolor='${Header::colourblue}' width='100%'><tr><td align='center'><b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b></td></tr></table>";
+       if ($confighash{$key}[0] eq 'off' && $col1 =~ /${Header::colourred}/ ) {
+               $col1="bgcolor='${Header::colourblue}'";
+           $active = "<b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b>";
        }
        print <<END
-       <td align='center'>$active</td>
-       <td align='center'>
+       <td align='center' $col1>$active</td>
+       <td align='center' $col>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
            <input type='image'  name='$Lang::tr{'restart'}' src='/images/reload.gif' alt='$Lang::tr{'restart'}' title='$Lang::tr{'restart'}' />
            <input type='hidden' name='ACTION' value='$Lang::tr{'restart'}' />
@@ -2707,7 +2815,7 @@ END
        ;
        if (($confighash{$key}[4] eq 'cert') && ($confighash{$key}[2] ne '%auth-dn')) {
            print <<END
-           <td align='center'>
+           <td align='center' $col>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
                <input type='image' name='$Lang::tr{'show certificate'}' src='/images/info.gif' alt='$Lang::tr{'show certificate'}' title='$Lang::tr{'show certificate'}' />
                <input type='hidden' name='ACTION' value='$Lang::tr{'show certificate'}' />
@@ -2716,11 +2824,11 @@ END
            </td>
 END
        ; } else {
-           print "<td width='2%'>&nbsp;</td>";
+           print "<td width='2%' $col>&nbsp;</td>";
        }
        if ($confighash{$key}[4] eq 'cert' && -f "${General::swroot}/certs/$confighash{$key}[1].p12") { 
            print <<END
-           <td align='center'>
+           <td align='center' $col>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
                <input type='image' name='$Lang::tr{'download pkcs12 file'}' src='/images/floppy.gif' alt='$Lang::tr{'download pkcs12 file'}' title='$Lang::tr{'download pkcs12 file'}' />
                <input type='hidden' name='ACTION' value='$Lang::tr{'download pkcs12 file'}' />
@@ -2730,7 +2838,7 @@ END
 END
        ; } elsif (($confighash{$key}[4] eq 'cert') && ($confighash{$key}[2] ne '%auth-dn')) {
            print <<END
-           <td align='center'>
+           <td align='center' $col>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
                <input type='image' name='$Lang::tr{'download certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download certificate'}' title='$Lang::tr{'download certificate'}' />
                <input type='hidden' name='ACTION' value='$Lang::tr{'download certificate'}' />
@@ -2739,10 +2847,10 @@ END
        </td>
 END
        ; } else {
-           print "<td width='2%'>&nbsp;</td>";
+           print "<td width='2%' $col>&nbsp;</td>";
        }
        print <<END
-       <td align='center'>
+       <td align='center' $col>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
            <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$Lang::tr{'toggle enable disable'}' title='$Lang::tr{'toggle enable disable'}' />
            <input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />
@@ -2750,14 +2858,14 @@ END
            </form>
        </td>
 
-       <td align='center'>
+       <td align='center' $col>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
            <input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />
            <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
            <input type='hidden' name='KEY' value='$key' />
            </form>
        </td>
-       <td align='center' >
+       <td align='center' $col>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
            <input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />
            <input type='image'  name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' />
@@ -2802,7 +2910,7 @@ END
 
     print <<END
     <table width='100%'>
-    <tr><td align='center' colspan='9'>
+    <tr><td align='right' colspan='9'>
        <form method='post' action='$ENV{'SCRIPT_NAME'}'>
        <input type='submit' name='ACTION' value='$Lang::tr{'add'}' />
        </form>
@@ -2812,45 +2920,46 @@ END
     ;
     &Header::closebox();
 
-    &Header::openbox('100%', 'left', "$Lang::tr{'certificate authorities'}:");
+    &Header::openbox('100%', 'left', "$Lang::tr{'certificate authorities'}");
     print <<EOF
-    <table width='100%' border='0' cellspacing='1' cellpadding='0'>
+    <table width='100%' cellspacing='1' cellpadding='0' class='tbl'>
     <tr>
-       <td width='25%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></td>
-       <td width='65%' class='boldbase' align='center'><b>$Lang::tr{'subject'}</b></td>
-       <td width='10%' class='boldbase' colspan='3' align='center'><b>$Lang::tr{'action'}</b></td>
+       <th width='25%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></th>
+       <th width='65%' class='boldbase' align='center'><b>$Lang::tr{'subject'}</b></th>
+       <th width='10%' class='boldbase' colspan='3' align='center'><b>$Lang::tr{'action'}</b></th>
     </tr>
 EOF
     ;
+    my $col1="bgcolor='$color{'color22'}'";
+       my $col2="bgcolor='$color{'color20'}'";
     if (-f "${General::swroot}/ca/cacert.pem") {
        my $casubject = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/ca/cacert.pem"));
-
        print <<END
-       <tr bgcolor='$color{'color22'}'>
-       <td class='base'>$Lang::tr{'root certificate'}</td>
-       <td class='base'>$casubject</td>
-       <td width='3%' align='center'>
+       <tr>
+       <td class='base' $col1>$Lang::tr{'root certificate'}</td>
+       <td class='base' $col1>$casubject</td>
+       <td width='3%' align='center' $col1>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
            <input type='hidden' name='ACTION' value='$Lang::tr{'show root certificate'}' />
            <input type='image' name='$Lang::tr{'edit'}' src='/images/info.gif' alt='$Lang::tr{'show root certificate'}' title='$Lang::tr{'show root certificate'}' />
            </form>
        </td>
-       <td width='3%' align='center'>
+       <td width='3%' align='center' $col1>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
            <input type='image' name='$Lang::tr{'download root certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download root certificate'}' title='$Lang::tr{'download root certificate'}' />
            <input type='hidden' name='ACTION' value='$Lang::tr{'download root certificate'}' />
            </form>
        </td>
-       <td width='4%'>&nbsp;</td></tr>
+       <td width='4%' $col1>&nbsp;</td></tr>
 END
        ;
     } else {
        # display rootcert generation buttons
        print <<END
-       <tr bgcolor='$color{'color22'}'>
-       <td class='base'>$Lang::tr{'root certificate'}:</td>
-       <td class='base'>$Lang::tr{'not present'}</td>
-       <td colspan='3'>&nbsp;</td></tr>
+       <tr>
+       <td class='base' $col1>$Lang::tr{'root certificate'}:</td>
+       <td class='base' $col1>$Lang::tr{'not present'}</td>
+       <td colspan='3' $col1>&nbsp;</td></tr>
 END
        ;
     }
@@ -2859,61 +2968,63 @@ END
        my $hostsubject = &Header::cleanhtml(getsubjectfromcert ("${General::swroot}/certs/hostcert.pem"));
 
        print <<END
-       <tr bgcolor='$color{'color20'}'>
-       <td class='base'>$Lang::tr{'host certificate'}</td>
-       <td class='base'>$hostsubject</td>
-       <td width='3%' align='center'>
+       <tr>
+       <td class='base' $col2>$Lang::tr{'host certificate'}</td>
+       <td class='base' $col2>$hostsubject</td>
+       <td width='3%' align='center' $col2>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
            <input type='hidden' name='ACTION' value='$Lang::tr{'show host certificate'}' />
            <input type='image' name='$Lang::tr{'show host certificate'}' src='/images/info.gif' alt='$Lang::tr{'show host certificate'}' title='$Lang::tr{'show host certificate'}' />
            </form>
        </td>
-       <td width='3%' align='center'>
+       <td width='3%' align='center' $col2>
            <form method='post' action='$ENV{'SCRIPT_NAME'}'>
-           <input type='image' name='$Lang::tr{'download host certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download host certificate'}' title='$Lang::tr{'download host certificate'}' />
-           <input type='hidden' name='ACTION' value='$Lang::tr{'download host certificate'}' />
+           <input type='image' name="$Lang::tr{'download host certificate'}" src='/images/floppy.gif' alt="$Lang::tr{'download host certificate'}" title="$Lang::tr{'download host certificate'}" />
+           <input type='hidden' name='ACTION' value="$Lang::tr{'download host certificate'}" />
            </form>
        </td>
-       <td width='4%'>&nbsp;</td></tr>
+       <td width='4%' $col2>&nbsp;</td></tr>
 END
        ;
     } else {
        # Nothing
        print <<END
-       <tr bgcolor='$color{'color20'}'>
-       <td width='25%' class='base'>$Lang::tr{'host certificate'}:</td>
-       <td class='base'>$Lang::tr{'not present'}</td>
-       <td colspan='3'>&nbsp;</td></tr>
+       <tr>
+       <td width='25%' class='base' $col2>$Lang::tr{'host certificate'}:</td>
+       <td class='base' $col2>$Lang::tr{'not present'}</td>
+       <td colspan='3' $col2>&nbsp;</td></tr>
 END
        ;
     }
  
-    my $rowcolor = 0;
-    if (keys %cahash > 0) {
-   foreach my $key (keys %cahash) {
-       if ($rowcolor++ % 2) {
-      print "<tr bgcolor='$color{'color20'}'>\n";
-       } else {
-      print "<tr bgcolor='$color{'color22'}'>\n";
-       }
-           print "<td class='base'>$cahash{$key}[0]</td>\n";
-           print "<td class='base'>$cahash{$key}[1]</td>\n";
+       my $rowcolor = 0;
+       if (keys %cahash > 0) {
+               foreach my $key (keys %cahash) {
+                       if ($rowcolor++ % 2) {
+                               print "<tr>";
+                               $col="bgcolor='$color{'color20'}'";
+                       } else {
+                               print "<tr>";
+                               $col="bgcolor='$color{'color22'}'";
+                       }
+           print "<td class='base' $col>$cahash{$key}[0]</td>\n";
+           print "<td class='base' $col>$cahash{$key}[1]</td>\n";
            print <<END
-           <td align='center'>
+           <td align='center' $col>
                <form method='post' name='cafrm${key}a' action='$ENV{'SCRIPT_NAME'}'>
                <input type='image' name='$Lang::tr{'show ca certificate'}' src='/images/info.gif' alt='$Lang::tr{'show ca certificate'}' title='$Lang::tr{'show ca certificate'}' />
                <input type='hidden' name='ACTION' value='$Lang::tr{'show ca certificate'}' />
                <input type='hidden' name='KEY' value='$key' />
                </form>
            </td>
-           <td align='center'>
+           <td align='center' $col>
                <form method='post' name='cafrm${key}b' action='$ENV{'SCRIPT_NAME'}'>
                <input type='image' name='$Lang::tr{'download ca certificate'}' src='/images/floppy.gif' alt='$Lang::tr{'download ca certificate'}' title='$Lang::tr{'download ca certificate'}' />
                <input type='hidden' name='ACTION' value='$Lang::tr{'download ca certificate'}' />
                <input type='hidden' name='KEY' value='$key' />
                </form>
            </td>
-           <td align='center'>
+           <td align='center' $col>
                <form method='post' name='cafrm${key}c' action='$ENV{'SCRIPT_NAME'}'>
                <input type='hidden' name='ACTION' value='$Lang::tr{'remove ca certificate'}' />
                <input type='image'  name='$Lang::tr{'remove ca certificate'}' src='/images/delete.gif' alt='$Lang::tr{'remove ca certificate'}' title='$Lang::tr{'remove ca certificate'}' />
@@ -2942,6 +3053,7 @@ END
     }
     my $createCA = -f "${General::swroot}/ca/cacert.pem" ? '' : "<tr><td colspan='3'></td><td><input type='submit' name='ACTION' value='$Lang::tr{'generate root/host certificates'}' /></td></tr>";
     print <<END
+    <br>
     <hr />
     <form method='post' enctype='multipart/form-data' action='$ENV{'SCRIPT_NAME'}'>
     <table width='100%' border='0' cellspacing='1' cellpadding='0'>
@@ -2954,7 +3066,7 @@ END
     </tr>
     <tr>
        <td colspan='3'>$Lang::tr{'resetting the vpn configuration will remove the root ca, the host certificate and all certificate based connections'}:</td>
-       <td><input type='submit' name='ACTION' value='$Lang::tr{'remove x509'}' /></td>
+       <td align='right'><input type='submit' name='ACTION' value='$Lang::tr{'remove x509'}' /></td>
     </tr>
     </table>
     </form>
@@ -2963,3 +3075,58 @@ END
     &Header::closebox();
     &Header::closebigbox();
     &Header::closepage();
+
+sub array_unique($) {
+       my $array = shift;
+       my @unique = ();
+
+       my %seen = ();
+       foreach my $e (@$array) {
+               next if $seen{$e}++;
+               push(@unique, $e);
+       }
+
+       return @unique;
+}
+
+sub make_algos($$$$$) {
+       my ($mode, $encs, $ints, $grps, $pfs) = @_;
+       my @algos = ();
+
+       foreach my $enc (@$encs) {
+               foreach my $int (@$ints) {
+                       foreach my $grp (@$grps) {
+                               my @algo = ($enc);
+
+                               if ($mode eq "ike") {
+                                       push(@algo, $int);
+
+                                       if ($grp =~ m/^e(.*)$/) {
+                                               push(@algo, "ecp$1");
+                                       } else {
+                                               push(@algo, "modp$grp");
+                                       }
+
+                               } elsif ($mode eq "esp" && $pfs) {
+                                       my $is_aead = ($enc =~ m/[cg]cm/);
+
+                                       if (!$is_aead) {
+                                               push(@algo, $int);
+                                       }
+
+                                       if ($grp eq "none") {
+                                               # noop
+                                       } elsif ($grp =~ m/^e(.*)$/) {
+                                               push(@algo, "ecp$1");
+                                       } else {
+                                               push(@algo, "modp$grp");
+                                       }
+                               }
+
+                               push(@algos, join("-", @algo));
+                       }
+               }
+       }
+
+       return &array_unique(\@algos);
+}