]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - html/cgi-bin/ovpnmain.cgi
Merge remote-tracking branch 'ummeegge/OpenVPN_validating_N2N' into next
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / ovpnmain.cgi
index 907e8c042c1d023a5f6e21c4a34df8457ac698e4..7727333b90c338308ae5be0786af7a88b3c99b94 100644 (file)
@@ -172,105 +172,6 @@ sub deletebackupcert
                unlink ("${General::swroot}/ovpn/certs/$hexvalue.pem");
        }
 }
-sub checkportfw {
-       my $DPORT = shift;
-       my $DPROT = shift;
-       my %natconfig =();
-       my $confignat = "${General::swroot}/firewall/config";
-       $DPROT= uc ($DPROT);
-       &General::readhasharray($confignat, \%natconfig);
-       foreach my $key (sort keys %natconfig){
-               my @portarray = split (/\|/,$natconfig{$key}[30]);
-               foreach my $value (@portarray){
-                       if ($value =~ /:/i){
-                               my ($a,$b) = split (":",$value);
-                               if ($DPROT eq $natconfig{$key}[12] && $DPORT gt $a && $DPORT lt $b){
-                                       $errormessage= "$Lang::tr{'source port in use'} $DPORT";
-                               }
-                       }else{
-                               if ($DPROT eq $natconfig{$key}[12] && $DPORT eq $value){
-                                       $errormessage= "$Lang::tr{'source port in use'} $DPORT";
-                               }
-                       }
-               }
-       }
-       return;
-}
-
-sub checkportoverlap
-{
-       my $portrange1 = $_[0]; # New port range
-       my $portrange2 = $_[1]; # existing port range
-       my @tempr1 = split(/\:/,$portrange1);
-       my @tempr2 = split(/\:/,$portrange2);
-
-       unless (&checkportinc($tempr1[0], $portrange2)){ return 0;}
-       unless (&checkportinc($tempr1[1], $portrange2)){ return 0;}
-       
-       unless (&checkportinc($tempr2[0], $portrange1)){ return 0;}
-       unless (&checkportinc($tempr2[1], $portrange1)){ return 0;}
-
-       return 1; # Everything checks out!
-}
-
-# Darren Critchley - we want to make sure that a port entry is not within an already existing range
-sub checkportinc
-{
-       my $port1 = $_[0]; # Port
-       my $portrange2 = $_[1]; # Port range
-       my @tempr1 = split(/\:/,$portrange2);
-
-       if ($port1 < $tempr1[0] || $port1 > $tempr1[1]) {
-               return 1; 
-       } else {
-               return 0; 
-       }
-}
-
-# Darren Critchley - certain ports are reserved for IPFire
-# TCP 67,68,81,222,444
-# UDP 67,68
-# Params passed in -> port, rangeyn, protocol
-sub disallowreserved
-{
-       # port 67 and 68 same for tcp and udp, don't bother putting in an array
-       my $msg = "";
-       my @tcp_reserved = (81,222,444);
-       my $prt = $_[0]; # the port or range
-       my $ryn = $_[1]; # tells us whether or not it is a port range
-       my $prot = $_[2]; # protocol
-       my $srcdst = $_[3]; # source or destination
-       if ($ryn) { # disect port range
-               if ($srcdst eq "src") {
-                       $msg = "$Lang::tr{'rsvd src port overlap'}";
-               } else {
-                       $msg = "$Lang::tr{'rsvd dst port overlap'}";
-               }
-               my @tmprng = split(/\:/,$prt);
-               unless (67 < $tmprng[0] || 67 > $tmprng[1]) { $errormessage="$msg 67"; return; }
-               unless (68 < $tmprng[0] || 68 > $tmprng[1]) { $errormessage="$msg 68"; return; }
-               if ($prot eq "tcp") {
-                       foreach my $prange (@tcp_reserved) {
-                               unless ($prange < $tmprng[0] || $prange > $tmprng[1]) { $errormessage="$msg $prange"; return; }
-                       }
-               }
-       } else {
-               if ($srcdst eq "src") {
-                       $msg = "$Lang::tr{'reserved src port'}";
-               } else {
-                       $msg = "$Lang::tr{'reserved dst port'}";
-               }
-               if ($prt == 67) { $errormessage="$msg 67"; return; }
-               if ($prt == 68) { $errormessage="$msg 68"; return; }
-               if ($prot eq "tcp") {
-                       foreach my $prange (@tcp_reserved) {
-                               if ($prange == $prt) { $errormessage="$msg $prange"; return; }
-                       }
-               }
-       }
-       return;
-}
-
 
 sub writeserverconf {
     my %sovpnsettings = ();  
@@ -369,7 +270,7 @@ sub writeserverconf {
        print CONF "auth $sovpnsettings{'DAUTH'}\n";
     }
     if ($sovpnsettings{'TLSAUTH'} eq 'on') {
-       print CONF "tls-auth ${General::swroot}/ovpn/ca/ta.key 0\n";
+       print CONF "tls-auth ${General::swroot}/ovpn/certs/ta.key\n";
     }
     if ($sovpnsettings{DCOMPLZO} eq 'on') {
         print CONF "comp-lzo\n";
@@ -810,13 +711,6 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
        $vpnsettings{'MSSFIX'} = $cgiparams{'MSSFIX'};
     }
 
-   # Create ta.key for tls-auth if not presant
-   if ($cgiparams{'TLSAUTH'} eq 'on') {
-       if ( ! -e "${General::swroot}/ovpn/ca/ta.key") {
-               system('/usr/sbin/openvpn', '--genkey', '--secret', "${General::swroot}/ovpn/ca/ta.key")
-       }
-    }
-
     if (($cgiparams{'PMTU_DISCOVERY'} eq 'yes') ||
         ($cgiparams{'PMTU_DISCOVERY'} eq 'maybe') ||
         ($cgiparams{'PMTU_DISCOVERY'} eq 'no' )) {
@@ -915,6 +809,16 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
         $errormessage = $Lang::tr{'invalid input for keepalive 1:2'};
         goto ADV_ERROR;        
     }
+    # Create ta.key for tls-auth if not presant
+    if ($cgiparams{'TLSAUTH'} eq 'on') {
+       if ( ! -e "${General::swroot}/ovpn/certs/ta.key") {
+               system('/usr/sbin/openvpn', '--genkey', '--secret', "${General::swroot}/ovpn/certs/ta.key");
+               if ($?) {
+               $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
+        goto ADV_ERROR;
+               }
+       }
+    }
     
     &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
     &writeserverconf();#hier ok
@@ -1004,7 +908,7 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   }
   if ($cgiparams{'COMPLZO'} eq 'on') {
    print SERVERCONF "# Enable Compression\n";
-   print SERVERCONF "comp-lzo\r\n";
+   print SERVERCONF "comp-lzo\n";
      }
   print SERVERCONF "# Debug Level\n"; 
   print SERVERCONF "verb 3\n"; 
@@ -1099,7 +1003,7 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   }
   if ($cgiparams{'COMPLZO'} eq 'on') {
    print CLIENTCONF "# Enable Compression\n";
-   print CLIENTCONF "comp-lzo\r\n";
+   print CLIENTCONF "comp-lzo\n";
   }
   print CLIENTCONF "# Debug Level\n"; 
   print CLIENTCONF "verb 3\n"; 
@@ -1119,7 +1023,6 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
 ### Save main settings
 ###
 
-
 if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cgiparams{'KEY'} eq '') {
     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
     #DAN do we really need (to to check) this value? Besides if we listen on blue and orange too,
@@ -1130,13 +1033,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg
        goto SETTINGS_ERROR;
        }
     }
-    if ($errormessage) { goto SETTINGS_ERROR; }
 
-    if ($cgiparams{'ENABLED'} eq 'on'){
-       &checkportfw($cgiparams{'DDEST_PORT'},$cgiparams{'DPROTOCOL'});
-    }
-    if ($errormessage) { goto SETTINGS_ERROR; }
-    
     if (! &General::validipandmask($cgiparams{'DOVPN_SUBNET'})) {
             $errormessage = $Lang::tr{'ovpn subnet is invalid'};
                        goto SETTINGS_ERROR;
@@ -1306,8 +1203,7 @@ END
         unlink "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}";
        }
        # Create Diffie Hellmann Parameter
-       system('/usr/bin/openssl', 'dhparam', '-rand', '/proc/interrupts:/proc/net/rt_cache',
-       '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}");
+       system('/usr/bin/openssl', 'dhparam', '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}");
        if ($?) {
                $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
                unlink ("${General::swroot}/ovpn/ca/dh1024.pem");
@@ -1621,6 +1517,18 @@ END
        print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/certs/servercert.pem`;
        exit(0);
     }
+
+###
+### Download tls-auth key
+###
+}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download tls-auth key'}) {
+    if ( -f "${General::swroot}/ovpn/certs/ta.key" ) {
+       print "Content-Type: application/octet-stream\r\n";
+       print "Content-Disposition: filename=ta.key\r\n\r\n";
+       print `/bin/cat ${General::swroot}/ovpn/certs/ta.key`;
+       exit(0);
+    }
+
 ###
 ### Form for generating a root certificate
 ###
@@ -1848,7 +1756,7 @@ END
                goto ROOTCERT_ERROR;
            }
        } else {        # child
-           unless (exec ('/usr/bin/openssl', 'req', '-x509', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
+           unless (exec ('/usr/bin/openssl', 'req', '-x509', '-nodes',
                        '-days', '999999', '-newkey', 'rsa:4096', '-sha512',
                        '-keyout', "${General::swroot}/ovpn/ca/cakey.pem",
                        '-out', "${General::swroot}/ovpn/ca/cacert.pem",
@@ -1879,7 +1787,7 @@ END
                goto ROOTCERT_ERROR;
            }
        } else {        # child
-           unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
+           unless (exec ('/usr/bin/openssl', 'req', '-nodes',
                        '-newkey', 'rsa:2048',
                        '-keyout', "${General::swroot}/ovpn/certs/serverkey.pem",
                        '-out', "${General::swroot}/ovpn/certs/serverreq.pem",
@@ -1931,8 +1839,7 @@ END
 #          &cleanssldatabase();
        }
        # Create Diffie Hellmann Parameter
-       system('/usr/bin/openssl', 'dhparam', '-rand', '/proc/interrupts:/proc/net/rt_cache',
-              '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}");
+       system('/usr/bin/openssl', 'dhparam', '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}");
        if ($?) {
            $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
            unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
@@ -1944,7 +1851,14 @@ END
            goto ROOTCERT_ERROR;
 #      } else {
 #          &cleanssldatabase();
-       }       
+       }
+       # Create ta.key for tls-auth
+       system('/usr/sbin/openvpn', '--genkey', '--secret', "${General::swroot}/ovpn/certs/ta.key");
+       if ($?) {
+           $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
+           &cleanssldatabase();
+           goto ROOTCERT_ERROR;
+       }
        goto ROOTCERT_SUCCESS;
     }
     ROOTCERT_ERROR:
@@ -2187,7 +2101,7 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
    }
    if ($confighash{$cgiparams{'KEY'}}[30] eq 'on') {
    print CLIENTCONF "# Enable Compression\n";
-   print CLIENTCONF "comp-lzo\r\n";
+   print CLIENTCONF "comp-lzo\n";
      }
    print CLIENTCONF "# Debug Level\n"; 
    print CLIENTCONF "verb 3\n"; 
@@ -2286,8 +2200,8 @@ else
        print CLIENTCONF "auth $vpnsettings{'DAUTH'}\r\n";
     }
     if ($vpnsettings{'TLSAUTH'} eq 'on') {
-       print CLIENTCONF "tls-auth ta.key 1\r\n";
-       $zip->addFile( "${General::swroot}/ovpn/ca/ta.key", "ta.key")  or die "Can't add file ta.key\n";
+       print CLIENTCONF "tls-auth ta.key\r\n";
+       $zip->addFile( "${General::swroot}/ovpn/certs/ta.key", "ta.key")  or die "Can't add file ta.key\n";
     }
     if ($vpnsettings{DCOMPLZO} eq 'on') {
         print CLIENTCONF "comp-lzo\r\n";
@@ -2453,6 +2367,28 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') {
                exit(0);
     }
 
+###
+### Display tls-auth key
+###
+} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show tls-auth key'}) {
+
+    if (! -e "${General::swroot}/ovpn/certs/ta.key") {
+       $errormessage = $Lang::tr{'not present'};
+       } else {
+               &Header::showhttpheaders();
+               &Header::openpage($Lang::tr{'ovpn'}, 1, '');
+               &Header::openbigbox('100%', 'LEFT', '', '');
+               &Header::openbox('100%', 'LEFT', "$Lang::tr{'ta key'}:");
+               my $output = `/bin/cat ${General::swroot}/ovpn/certs/ta.key`;
+               $output = &Header::cleanhtml($output,"y");
+               print "<pre>$output</pre>\n";
+               &Header::closebox();
+               print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
+               &Header::closebigbox();
+               &Header::closepage();
+               exit(0);
+    }
+
 ###
 ### Display Certificate Revoke List
 ###
@@ -2511,20 +2447,8 @@ ADV_ERROR:
     if ($cgiparams{'DAUTH'} eq '') {
                $cgiparams{'DAUTH'} = 'SHA1';
     }
-    if ($cgiparams{'DAUTH'} eq '') {
-       $cgiparams{'DAUTH'} = 'SHA1';
-    }
-    if ($cgiparams{'ENGINES'} eq '') {
-       $cgiparams{'ENGINES'} = 'disabled';
-    }
-    if ($cgiparams{'TLSAUTH'} eq '') {
-       $cgiparams{'TLSAUTH'} = 'off';
-    }
-    if ($cgiparams{'DAUTH'} eq '') {
-       $cgiparams{'DAUTH'} = 'SHA1';
-    }
     if ($cgiparams{'TLSAUTH'} eq '') {
-       $cgiparams{'TLSAUTH'} = 'off';
+               $cgiparams{'TLSAUTH'} = 'off';
     }
     $checked{'CLIENT2CLIENT'}{'off'} = '';
     $checked{'CLIENT2CLIENT'}{'on'} = '';
@@ -3251,7 +3175,6 @@ my $complzoactive;
 my $mssfixactive;
 my $authactive;
 my $n2nfragment;
-my $authactive;
 my @n2nmtudisc = split(/ /, (grep { /^mtu-disc/ } @firen2nconf)[0]);
 my @n2nproto2 = split(/ /, (grep { /^proto/ } @firen2nconf)[0]);
 my @n2nproto = split(/-/, $n2nproto2[1]);
@@ -4043,10 +3966,8 @@ if ($cgiparams{'TYPE'} eq 'net') {
                $errormessage = $Lang::tr{'name too long'};
                goto VPNCONF_ERROR;
            }
-           if ($cgiparams{'CERT_NAME'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) {
+           if ($cgiparams{'CERT_NAME'} eq '' || $cgiparams{'CERT_NAME'} !~ /^[a-zA-Z0-9 ,\.\-_]+$/) {
                $errormessage = $Lang::tr{'invalid input for name'};
-               unlink ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}/$cgiparams{'NAME'}.conf") or die "Removing Configfile fail: $!";
-               rmdir ("${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}") || die "Removing Directory fail: $!";
                goto VPNCONF_ERROR;
            }
            if ($cgiparams{'CERT_EMAIL'} ne '' && (! &General::validemail($cgiparams{'CERT_EMAIL'}))) {
@@ -4091,6 +4012,10 @@ if ($cgiparams{'TYPE'} eq 'net') {
                $errormessage = $Lang::tr{'passwords do not match'};
                goto VPNCONF_ERROR;
            }
+           if ($cgiparams{'DAYS_VALID'} ne '' && $cgiparams{'DAYS_VALID'} !~ /^[0-9]+$/) {
+               $errormessage = $Lang::tr{'invalid input for valid till days'};
+               goto VPNCONF_ERROR;
+           }
 
            # Replace empty strings with a .
            (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./;
@@ -4118,7 +4043,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
                    goto VPNCONF_ERROR;
                }
            } else {    # child
-               unless (exec ('/usr/bin/openssl', 'req', '-nodes', '-rand', '/proc/interrupts:/proc/net/rt_cache',
+               unless (exec ('/usr/bin/openssl', 'req', '-nodes',
                        '-newkey', 'rsa:2048',
                        '-keyout', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem",
                        '-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem",
@@ -4361,6 +4286,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
        $cgiparams{'CERT_CITY'}         = $vpnsettings{'ROOTCERT_CITY'};
        $cgiparams{'CERT_STATE'}        = $vpnsettings{'ROOTCERT_STATE'};
        $cgiparams{'CERT_COUNTRY'}      = $vpnsettings{'ROOTCERT_COUNTRY'};
+       $cgiparams{'DAYS_VALID'}        = $vpnsettings{'DAYS_VALID'};
     }
 
     VPNCONF_ERROR:
@@ -4576,7 +4502,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
                                <option value='CAMELLIA-256-CBC'        $selected{'DCIPHER'}{'CAMELLIA-256-CBC'}>CAMELLIA-CBC (256 $Lang::tr{'bit'})</option>
                                <option value='CAMELLIA-192-CBC'        $selected{'DCIPHER'}{'CAMELLIA-192-CBC'}>CAMELLIA-CBC (192 $Lang::tr{'bit'})</option>
                                <option value='CAMELLIA-128-CBC'        $selected{'DCIPHER'}{'CAMELLIA-128-CBC'}>CAMELLIA-CBC (128 $Lang::tr{'bit'})</option>
-                               <option value='AES-256-CBC'             $selected{'DCIPHER'}{'AES-256-CBC'}>AES-CBC (256 $Lang::tr{'bit'})</option>
+                               <option value='AES-256-CBC'             $selected{'DCIPHER'}{'AES-256-CBC'}>AES-CBC (256 $Lang::tr{'bit'}, $Lang::tr{'default'})</option>
                                <option value='AES-192-CBC'             $selected{'DCIPHER'}{'AES-192-CBC'}>AES-CBC (192 $Lang::tr{'bit'})</option>
                                <option value='AES-128-CBC'             $selected{'DCIPHER'}{'AES-128-CBC'}>AES-CBC (128 $Lang::tr{'bit'})</option>
                                <option value='DES-EDE3-CBC'            $selected{'DCIPHER'}{'DES-EDE3-CBC'}>DES-EDE3-CBC (192 $Lang::tr{'bit'})</option>
@@ -4722,27 +4648,28 @@ END
 
 if ($cgiparams{'TYPE'} eq 'host') {
        print <<END;
-           </select></td></tr>
-
-       <td>&nbsp;</td><td class='base'>$Lang::tr{'valid till'} (days):</td>
-       <td class='base' nowrap='nowrap'><input type='text' name='DAYS_VALID' value='$cgiparams{'DAYS_VALID'}' size='32' $cakeydisabled /></td></tr>
-   <tr><td>&nbsp;</td>
+       </select></td></tr>
+               <td>&nbsp;</td><td class='base'>$Lang::tr{'valid till'} (days):</td>
+               <td class='base' nowrap='nowrap'><input type='text' name='DAYS_VALID' value='$cgiparams{'DAYS_VALID'}' size='32' $cakeydisabled /></td></tr>
+               <tr><td>&nbsp;</td>
                <td class='base'>$Lang::tr{'pkcs12 file password'}:</td>
                <td class='base' nowrap='nowrap'><input type='password' name='CERT_PASS1' value='$cgiparams{'CERT_PASS1'}' size='32' $cakeydisabled /></td></tr>
-           <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'pkcs12 file password'}:<br>($Lang::tr{'confirmation'})</td>
+               <tr><td>&nbsp;</td><td class='base'>$Lang::tr{'pkcs12 file password'}:<br>($Lang::tr{'confirmation'})</td>
                <td class='base' nowrap='nowrap'><input type='password' name='CERT_PASS2' value='$cgiparams{'CERT_PASS2'}' size='32' $cakeydisabled /></td></tr>
-     <tr><td colspan='3'>&nbsp;</td></tr>
-     <tr><td colspan='3'><hr /></td></tr>
-     <tr><td class='base' colspan='3' align='left'><img src='/blob.gif' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
-     </table>
+               <tr><td colspan='3'>&nbsp;</td></tr>
+               <tr><td colspan='3'><hr /></td></tr>
+               <tr><td class='base' colspan='3' align='left'><img src='/blob.gif' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
+       </table>
 END
 }else{
        print <<END;
-           </select></td></tr>
-   <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
-        <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
-        <tr><td colspan='3'><hr /></td></tr>
-        <tr><td class='base' colspan='3' align='left'><img src='/blob.gif' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
+       </select></td></tr>
+               <td>&nbsp;</td><td class='base'>$Lang::tr{'valid till'} (days):</td>
+               <td class='base' nowrap='nowrap'><input type='text' name='DAYS_VALID' value='$cgiparams{'DAYS_VALID'}' size='32' $cakeydisabled /></td></tr>
+               <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+               <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+               <tr><td colspan='3'><hr /></td></tr>
+               <tr><td class='base' colspan='3' align='left'><img src='/blob.gif' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td></tr>
        </table>
  
 END
@@ -4927,9 +4854,6 @@ END
        if ($cgiparams{'DAUTH'} eq '') {
                $cgiparams{'DAUTH'} = 'SHA1';
     }
-    if ($cgiparams{'ENGINES'} eq '') {
-       $cgiparams{'ENGINES'} = 'disabled';
-    }
     if ($cgiparams{'DOVPN_SUBNET'} eq '') {
                $cgiparams{'DOVPN_SUBNET'} = '10.' . int(rand(256)) . '.' . int(rand(256)) . '.0/255.255.255.0';
     }
@@ -5102,24 +5026,41 @@ END
 ###
 
     &Header::openbox('100%', 'LEFT', $Lang::tr{'connection status and controlc' });
-    print <<END;
-
-
-    <table width='100%' cellspacing='1' cellpadding='0' class='tbl'>
-<tr>
-    <th width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></th>
-    <th width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></th>
-    <th width='22%' class='boldbase' align='center'><b>$Lang::tr{'network'}</b></th>
-    <th width='20%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></th>
-    <th width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></th>
-    <th width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></th>
-</tr>
-END
        ;
        my $id = 0;
        my $gif;
        my $col1="";
-       foreach my $key (sort { ncmp ($confighash{$a}[1],$confighash{$b}[1]) } keys %confighash) {
+       my $lastnet;
+       foreach my $key (sort { ncmp ($confighash{$a}[32],$confighash{$b}[32]) } sort { ncmp ($confighash{$a}[1],$confighash{$b}[1]) } keys %confighash) {
+               if ($confighash{$key}[32] eq "" && $confighash{$key}[3] eq 'net' ){$confighash{$key}[32]=$Lang::tr{'fwhost OpenVPN N-2-N'};}
+               if ($confighash{$key}[32] eq "dynamic"){$confighash{$key}[32]=$Lang::tr{'ccd dynrange'};}
+               if($id == 0){
+                       print"<b>$confighash{$key}[32]</b>";
+                       print <<END;
+       <table width='100%' cellspacing='1' cellpadding='0' class='tbl'>
+<tr>
+       <th width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></th>
+       <th width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></th>
+       <th width='20%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></th>
+       <th width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></th>
+       <th width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></th>
+</tr>
+END
+               }
+               if ($id > 0 && $lastnet ne $confighash{$key}[32]){
+                       print "</table><br>";
+                       print"<b>$confighash{$key}[32]</b>";
+                       print <<END;
+       <table width='100%' cellspacing='1' cellpadding='0' class='tbl'>
+<tr>
+       <th width='10%' class='boldbase' align='center'><b>$Lang::tr{'name'}</b></th>
+       <th width='15%' class='boldbase' align='center'><b>$Lang::tr{'type'}</b></th>
+       <th width='20%' class='boldbase' align='center'><b>$Lang::tr{'remark'}</b></th>
+       <th width='10%' class='boldbase' align='center'><b>$Lang::tr{'status'}</b></th>
+       <th width='5%' class='boldbase' colspan='6' align='center'><b>$Lang::tr{'action'}</b></th>
+</tr>
+END
+               }
        if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
        if ($id % 2) {
                print "<tr>";
@@ -5138,9 +5079,6 @@ END
        my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
        $cavalid    =~ /Not After : (.*)[\n]/;
        $cavalid    = $1;
-       if ($confighash{$key}[32] eq "" && $confighash{$key}[3] eq 'net' ){$confighash{$key}[32]="net-2-net";}
-       if ($confighash{$key}[32] eq "" && $confighash{$key}[3] eq 'host' ){$confighash{$key}[32]="dynamic";}
-       print "<td align='center' $col>$confighash{$key}[32]</td>";
        print "<td align='center' $col>$confighash{$key}[25]</td>";
        $col1="bgcolor='${Header::colourred}'";
        my $active = "<b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b>";
@@ -5269,7 +5207,9 @@ END
 END
        ;
        $id++;
+       $lastnet = $confighash{$key}[32];
     }
+    print"</table>";
     ;
 
     # If the config file contains entries, print Key to action icons
@@ -5314,6 +5254,8 @@ END
     ;
        &Header::closebox();
        }
+
+    # CA/key listing
     &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate authorities'}");
     print <<END;
     <table width='100%' cellspacing='1' cellpadding='0' class='tbl'>
@@ -5325,7 +5267,12 @@ END
 END
     ;
     my $col1="bgcolor='$color{'color22'}'";
-       my $col2="bgcolor='$color{'color20'}'";
+    my $col2="bgcolor='$color{'color20'}'";
+    # DH parameter line
+    my $col3="bgcolor='$color{'color22'}'";
+    # ta.key line
+    my $col4="bgcolor='$color{'color20'}'";
+
     if (-f "${General::swroot}/ovpn/ca/cacert.pem") {
                my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
                $casubject    =~ /Subject: (.*)[\n]/;
@@ -5336,15 +5283,16 @@ END
                <tr>
                        <td class='base' $col1>$Lang::tr{'root certificate'}</td>
                        <td class='base' $col1>$casubject</td>
-               <form method='post' name='frmrootcrta'><td width='3%' align='center' $col1>
+                       <form method='post' name='frmrootcrta'><td width='3%' align='center' $col1>
                        <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'}' width='20' height='20' border='0' />
-               </td></form>
-               <form method='post' name='frmrootcrtb'><td width='3%' align='center' $col1>
+                       </form>
+                       <form method='post' name='frmrootcrtb'><td width='3%' align='center' $col1>
                        <input type='image' name='$Lang::tr{'download root certificate'}' src='/images/media-floppy.png' alt='$Lang::tr{'download root certificate'}' title='$Lang::tr{'download root certificate'}' border='0' />
                        <input type='hidden' name='ACTION' value='$Lang::tr{'download root certificate'}' />
-               </td></form>
-               <td width='4%' $col1>&nbsp;</td></tr>
+                       </form>
+                       <td width='4%' $col1>&nbsp;</td>
+               </tr>
 END
                ;
     } else {
@@ -5353,7 +5301,8 @@ END
                <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>
+                       <td colspan='3' $col1>&nbsp;</td>
+               </tr>
 END
                ;
     }
@@ -5369,15 +5318,16 @@ END
                <tr>
                        <td class='base' $col2>$Lang::tr{'host certificate'}</td>
                        <td class='base' $col2>$hostsubject</td>
-               <form method='post' name='frmhostcrta'><td width='3%' align='center' $col2>
+                       <form method='post' name='frmhostcrta'><td width='3%' align='center' $col2>
                        <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'}' width='20' height='20' border='0' />
-               </td></form>
-               <form method='post' name='frmhostcrtb'><td width='3%' align='center' $col2>
+                       </form>
+                       <form method='post' name='frmhostcrtb'><td width='3%' align='center' $col2>
                        <input type='image' name="$Lang::tr{'download host certificate'}" src='/images/media-floppy.png' alt="$Lang::tr{'download host certificate'}" title="$Lang::tr{'download host certificate'}" border='0' />
                        <input type='hidden' name='ACTION' value="$Lang::tr{'download host certificate'}" />
-               </td></form>
-               <td width='4%' $col2>&nbsp;</td></tr>
+                       </td></form>
+                       <td width='4%' $col2>&nbsp;</td>
+               </tr>
 END
                ;
     } else {
@@ -5386,7 +5336,75 @@ END
                <tr>
                        <td width='25%' class='base' $col2>$Lang::tr{'host certificate'}:</td>
                        <td class='base' $col2>$Lang::tr{'not present'}</td>
-               </td><td colspan='3' $col2>&nbsp;</td></tr>
+                       </td><td colspan='3' $col2>&nbsp;</td>
+               </tr>
+END
+               ;
+    }
+
+    # Adding DH parameter to chart
+    if (-f "${General::swroot}/ovpn/ca/dh1024.pem") {
+               my $dhsubject = `/usr/bin/openssl dhparam -text -in ${General::swroot}/ovpn/ca/dh1024.pem`;
+               $dhsubject    =~ /    (.*)[\n]/;
+               $dhsubject    = $1;
+
+
+       print <<END;
+               <tr>
+                       <td class='base' $col3>$Lang::tr{'dh parameter'}</td>
+                       <td class='base' $col3>$dhsubject</td>
+                       <form method='post' name='frmdhparam'><td width='3%' align='center' $col3>
+                       <input type='hidden' name='ACTION' value='$Lang::tr{'show dh'}' />
+                       <input type='image' name='$Lang::tr{'show dh'}' src='/images/info.gif' alt='$Lang::tr{'show dh'}' title='$Lang::tr{'show dh'}' width='20' height='20' border='0' />
+                       </form>
+                       <form method='post' name='frmdhparam'><td width='3%' align='center' $col3>
+                       </form>
+                       <td width='4%' $col3>&nbsp;</td>
+               </tr>
+END
+               ;
+    } else {
+               # Nothing
+               print <<END;
+               <tr>
+                       <td width='25%' class='base' $col3>$Lang::tr{'dh parameter'}:</td>
+                       <td class='base' $col3>$Lang::tr{'not present'}</td>
+                       </td><td colspan='3' $col3>&nbsp;</td>
+               </tr>
+END
+               ;
+    }
+
+    # Adding ta.key to chart
+    if (-f "${General::swroot}/ovpn/certs/ta.key") {
+               my $tasubject = `/bin/cat ${General::swroot}/ovpn/certs/ta.key`;
+               $tasubject    =~ /# (.*)[\n]/;
+               $tasubject    = $1;
+               print <<END;
+
+               <tr>
+                       <td class='base' $col4>$Lang::tr{'ta key'}</td>
+                       <td class='base' $col4>$tasubject</td>
+                       <form method='post' name='frmtakey'><td width='3%' align='center' $col4>
+                       <input type='hidden' name='ACTION' value='$Lang::tr{'show tls-auth key'}' />
+                       <input type='image' name='$Lang::tr{'edit'}' src='/images/info.gif' alt='$Lang::tr{'show tls-auth key'}' title='$Lang::tr{'show tls-auth key'}' width='20' height='20' border='0' />
+                       </form>
+                       <form method='post' name='frmtakey'><td width='3%' align='center' $col4>
+                       <input type='image' name='$Lang::tr{'download tls-auth key'}' src='/images/media-floppy.png' alt='$Lang::tr{'download tls-auth key'}' title='$Lang::tr{'download tls-auth key'}' border='0' />
+                       <input type='hidden' name='ACTION' value='$Lang::tr{'download tls-auth key'}' />
+                       </form>
+                       <td width='4%' $col4>&nbsp;</td>
+               </tr>
+END
+               ;
+    } else {
+               # Nothing
+               print <<END;
+               <tr>
+                       <td width='25%' class='base' $col4>$Lang::tr{'ta key'}:</td>
+                       <td class='base' $col4>$Lang::tr{'not present'}</td>
+                       <td colspan='3' $col4>&nbsp;</td>
+               </tr>
 END
                ;
     }
@@ -5449,6 +5467,9 @@ END
        <hr size='1'>
        <form method='post' enctype='multipart/form-data'>
        <table width='100%' border='0'cellspacing='1' cellpadding='0'>
+       <tr>
+               <td class'base'><b>$Lang::tr{'upload ca certificate'}</b></td>
+       </tr>
        <tr>
                <td class='base' nowrap='nowrap'>$Lang::tr{'ca name'}:</td>
                <td nowrap='nowrap'><input type='text' name='CA_NAME' value='$cgiparams{'CA_NAME'}' size='15' align='left'/></td>
@@ -5462,7 +5483,7 @@ END
 
        <tr><td colspan=4><hr /></td></tr><tr>
        <tr>
-               <td class'base'><b>$Lang::tr{'ovpn dh parameters'}:</b></td>
+               <td class'base'><b>$Lang::tr{'ovpn dh parameters'}</b></td>
        </tr>
 
        <tr>
@@ -5476,9 +5497,6 @@ END
                <td nowrap='nowrap'><size='15' align='left'/></td>
                <td nowrap='nowrap'><input type='submit' name='ACTION' value='$Lang::tr{'generate dh key'}' /></td>
        </tr>
-       <tr>
-               <td colspan='4' align='right'><input type='submit' name='ACTION' value='$Lang::tr{'show dh'}' /></td>
-       </tr>
        </table>
        
        <tr><td colspan=4><hr /></td></tr><tr>