]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - html/cgi-bin/ovpnmain.cgi
Merge remote-tracking branch 'amarx/vpn-statistic1' into next
[ipfire-2.x.git] / html / cgi-bin / ovpnmain.cgi
index 921009fc70ba194ffbcd22f9d1de34cca7756a88..1e074928f29507143d98d40ba0ab5deeec4b0c21 100644 (file)
@@ -70,6 +70,9 @@ my $configgrp="${General::swroot}/fwhosts/customgroups";
 my $customnet="${General::swroot}/fwhosts/customnetworks";
 my $name;
 my $col="";
+my $local_serverconf = "${General::swroot}/ovpn/scripts/server.conf.local";
+my $local_clientconf = "${General::swroot}/ovpn/scripts/client.conf.local";
+
 &General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
 $cgiparams{'ENABLED'} = 'off';
 $cgiparams{'ENABLED_BLUE'} = 'off';
@@ -94,10 +97,33 @@ $cgiparams{'DCIPHER'} = '';
 $cgiparams{'DAUTH'} = '';
 $cgiparams{'TLSAUTH'} = '';
 $routes_push_file = "${General::swroot}/ovpn/routes_push";
-unless (-e $routes_push_file)    { system("touch $routes_push_file"); }
-unless (-e "${General::swroot}/ovpn/ccd.conf")    { system("touch ${General::swroot}/ovpn/ccd.conf"); }
-unless (-e "${General::swroot}/ovpn/ccdroute")    { system("touch ${General::swroot}/ovpn/ccdroute"); }
-unless (-e "${General::swroot}/ovpn/ccdroute2")    { system("touch ${General::swroot}/ovpn/ccdroute2"); }
+
+# Add CCD files if not already presant
+unless (-e $routes_push_file) {
+       open(RPF, ">$routes_push_file");
+       close(RPF);
+}
+unless (-e "${General::swroot}/ovpn/ccd.conf") {
+       open(CCDC, ">${General::swroot}/ovpn/ccd.conf");
+       close (CCDC);
+}
+unless (-e "${General::swroot}/ovpn/ccdroute") {
+       open(CCDR, ">${General::swroot}/ovpn/ccdroute");
+       close (CCDR);
+}
+unless (-e "${General::swroot}/ovpn/ccdroute2") {
+       open(CCDRT, ">${General::swroot}/ovpn/ccdroute2");
+       close (CCDRT);
+}
+# Add additional configs if not already presant
+unless (-e "$local_serverconf") {
+       open(LSC, ">$local_serverconf");
+       close (LSC);
+}
+unless (-e "$local_clientconf") {
+       open(LCC, ">$local_clientconf");
+       close (LCC);
+}
 
 &Header::getcgihash(\%cgiparams, {'wantfile' => 1, 'filevar' => 'FH'});
 
@@ -262,7 +288,7 @@ sub writeserverconf {
        print CONF "keepalive $sovpnsettings{'KEEPALIVE_1'} $sovpnsettings{'KEEPALIVE_2'}\n";
     }  
     print CONF "status-version 1\n";
-    print CONF "status /var/log/ovpnserver.log 30\n";
+    print CONF "status /var/run/ovpnserver.log 30\n";
     print CONF "cipher $sovpnsettings{DCIPHER}\n";
     if ($sovpnsettings{'DAUTH'} eq '') {
         print CONF "";
@@ -306,14 +332,29 @@ sub writeserverconf {
                print CONF "verb $sovpnsettings{LOG_VERB}\n";
        } else {
                print CONF "verb 3\n";
-       }       
+       }
+    # Print server.conf.local if entries exist to server.conf
+    if ( !-z $local_serverconf  && $sovpnsettings{'ADDITIONAL_CONFIGS'} eq 'on') {
+       open (LSC, "$local_serverconf");
+               print CONF "\n#---------------------------\n";
+               print CONF "# Start of custom directives\n";
+               print CONF "# from server.conf.local\n";
+               print CONF "#---------------------------\n\n";
+       while (<LSC>) {
+               print CONF $_;
+       }
+               print CONF "\n#-----------------------------\n";
+               print CONF "# End of custom directives\n";
+               print CONF "#-----------------------------\n";
+       close (LSC);
+    }
     print CONF "\n";
     
     close(CONF);
 }    
 
 sub emptyserverlog{
-    if (open(FILE, ">/var/log/ovpnserver.log")) {
+    if (open(FILE, ">/var/run/ovpnserver.log")) {
        flock FILE, 2;
        print FILE "";
        close FILE;
@@ -685,6 +726,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
     $vpnsettings{'MAX_CLIENTS'} = $cgiparams{'MAX_CLIENTS'};
     $vpnsettings{'REDIRECT_GW_DEF1'} = $cgiparams{'REDIRECT_GW_DEF1'};
     $vpnsettings{'CLIENT2CLIENT'} = $cgiparams{'CLIENT2CLIENT'};
+    $vpnsettings{'ADDITIONAL_CONFIGS'} = $cgiparams{'ADDITIONAL_CONFIGS'};
     $vpnsettings{'DHCP_DOMAIN'} = $cgiparams{'DHCP_DOMAIN'};
     $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'};
     $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'};
@@ -863,9 +905,12 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   print SERVERCONF "route $remsubnet[0] $remsubnet[1]\n";
   print SERVERCONF "# tun Device\n"; 
   print SERVERCONF "dev tun\n"; 
+  print SERVERCONF "#Logfile for statistics\n";
+  print SERVERCONF "status-version 1\n";
+  print SERVERCONF "status /var/run/openvpn/$cgiparams{'NAME'}-n2n 10\n";
   print SERVERCONF "# Port and Protokol\n"; 
   print SERVERCONF "port $cgiparams{'DEST_PORT'}\n"; 
-  
+
   if ($cgiparams{'PROTOCOL'} eq 'tcp') {
   print SERVERCONF "proto tcp-server\n";
   print SERVERCONF "# Packet size\n";
@@ -908,7 +953,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"; 
@@ -1003,7 +1048,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"; 
@@ -1151,6 +1196,14 @@ SETTINGS_ERROR:
     while ($file = glob("${General::swroot}/ovpn/ccd/*")) {
        unlink $file
     }
+# Delete all RRD files for Roadwarrior connections
+    chdir('/var/ipfire/ovpn/ccd');
+       while ($file = glob("*")) {
+       system ("/usr/local/bin/openvpnctrl -drrd $file");
+       }
+    while ($file = glob("${General::swroot}/ovpn/ccd/*")) {
+       unlink $file
+    }
     if (open(FILE, ">${General::swroot}/ovpn/ovpn-leases.db")) {
        print FILE "";
        close FILE;
@@ -1203,8 +1256,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");
@@ -1520,13 +1572,13 @@ END
     }
 
 ###
-### Download Diffie-Hellman parameter
+### Download tls-auth key
 ###
-}elsif ($cgiparams{'ACTION'} eq $Lang::tr{'download dh parameter'}) {
-    if ( -f "${General::swroot}/ovpn/ca/dh1024.pem" ) {
+}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=dh1024.pem\r\n\r\n";
-       print `/usr/bin/openssl dhparam -in ${General::swroot}/ovpn/ca/dh1024.pem`;
+       print "Content-Disposition: filename=ta.key\r\n\r\n";
+       print `/bin/cat ${General::swroot}/ovpn/certs/ta.key`;
        exit(0);
     }
 
@@ -1757,7 +1809,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",
@@ -1788,7 +1840,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",
@@ -1840,8 +1892,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");
@@ -2103,7 +2154,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"; 
@@ -2226,6 +2277,21 @@ else
                print CLIENTCONF "mtu-disc $vpnsettings{'PMTU_DISCOVERY'}\r\n";
        }
     }
+    # Print client.conf.local if entries exist to client.ovpn
+    if (!-z $local_clientconf && $vpnsettings{'ADDITIONAL_CONFIGS'} eq 'on') {
+       open (LCC, "$local_clientconf");
+               print CLIENTCONF "\n#---------------------------\n";
+               print CLIENTCONF "# Start of custom directives\n";
+               print CLIENTCONF "# from client.conf.local\n";
+               print CLIENTCONF "#---------------------------\n\n";
+       while (<LCC>) {
+               print CLIENTCONF $_;
+       }
+               print CLIENTCONF "\n#---------------------------\n";
+               print CLIENTCONF "# End of custom directives\n";
+               print CLIENTCONF "#---------------------------\n\n";
+       close (LCC);
+    }
     close(CLIENTCONF);
         
     $zip->addFile( "$tempdir/$clientovpn", $clientovpn) or die "Can't add file $clientovpn\n";
@@ -2304,7 +2370,10 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') {
        
 # CCD end 
 
-       
+###
+###  Delete all RRD's for client
+###
+       system ("/usr/local/bin/openvpnctrl -drrd $confighash{$cgiparams{'KEY'}}[1]");
        delete $confighash{$cgiparams{'KEY'}};
        my $temp2 = `/usr/bin/openssl ca -gencrl -out ${General::swroot}/ovpn/crls/cacrl.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
        &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
@@ -2369,6 +2438,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
 ###
@@ -2436,6 +2527,9 @@ ADV_ERROR:
     $checked{'REDIRECT_GW_DEF1'}{'off'} = '';
     $checked{'REDIRECT_GW_DEF1'}{'on'} = '';
     $checked{'REDIRECT_GW_DEF1'}{$cgiparams{'REDIRECT_GW_DEF1'}} = 'CHECKED';
+    $checked{'ADDITIONAL_CONFIGS'}{'off'} = '';
+    $checked{'ADDITIONAL_CONFIGS'}{'on'} = '';
+    $checked{'ADDITIONAL_CONFIGS'}{$cgiparams{'ADDITIONAL_CONFIGS'}} = 'CHECKED';
     $checked{'MSSFIX'}{'off'} = '';
     $checked{'MSSFIX'}{'on'} = '';
     $checked{'MSSFIX'}{$cgiparams{'MSSFIX'}} = 'CHECKED';
@@ -2516,39 +2610,52 @@ print <<END;
 </table>
 <hr size='1'>
 <table width='100%'>
-    <tr>
+       <tr>
                <td class'base'><b>$Lang::tr{'misc-options'}</b></td>
-    </tr>
-    <tr>
+       </tr>
+
+       <tr>
                <td width='20%'></td> <td width='15%'> </td><td width='15%'> </td><td width='15%'></td><td width='35%'></td>
-    </tr>
-    <tr>
+       </tr>
+
+       <tr>
                <td class='base'>Client-To-Client</td>
                <td><input type='checkbox' name='CLIENT2CLIENT' $checked{'CLIENT2CLIENT'}{'on'} /></td>
-    </tr>
-    <tr>       
+       </tr>
+
+       <tr>
                <td class='base'>Redirect-Gateway def1</td>
                <td><input type='checkbox' name='REDIRECT_GW_DEF1' $checked{'REDIRECT_GW_DEF1'}{'on'} /></td>
-    </tr>
-    <tr>       
-        <td class='base'>Max-Clients</td>
-        <td><input type='text' name='MAX_CLIENTS' value='$cgiparams{'MAX_CLIENTS'}' size='10' /></td>
-    </tr>      
+       </tr>
+
        <tr>
-         <td class='base'>Keepalive <br />
-           (ping/ping-restart)</td>
-         <td><input type='TEXT' name='KEEPALIVE_1' value='$cgiparams{'KEEPALIVE_1'}' size='10' /></td>
-         <td><input type='TEXT' name='KEEPALIVE_2' value='$cgiparams{'KEEPALIVE_2'}' size='10' /></td>
-    </tr>
+               <td class='base'>$Lang::tr{'ovpn add conf'}</td>
+               <td><input type='checkbox' name='ADDITIONAL_CONFIGS' $checked{'ADDITIONAL_CONFIGS'}{'on'} /></td>
+               <td>$Lang::tr{'openvpn default'}: off</td>
+       </tr>
+
+       <tr>
+               <td class='base'>mssfix</td>
+               <td><input type='checkbox' name='MSSFIX' $checked{'MSSFIX'}{'on'} /></td>
+               <td>$Lang::tr{'openvpn default'}: off</td>
+       </tr>
+
+       <tr>
+               <td class='base'>fragment <br></td>
+               <td><input type='TEXT' name='FRAGMENT' value='$cgiparams{'FRAGMENT'}' size='10' /></td>
+       </tr>
+
+
+       <tr>
+               <td class='base'>Max-Clients</td>
+               <td><input type='text' name='MAX_CLIENTS' value='$cgiparams{'MAX_CLIENTS'}' size='10' /></td>
+       </tr>
        <tr>
-         <td class='base'>fragment <br></td>
-         <td><input type='TEXT' name='FRAGMENT' value='$cgiparams{'FRAGMENT'}' size='10' /></td>
-      </tr>
-       <tr>
-         <td class='base'>mssfix</td>
-         <td><input type='checkbox' name='MSSFIX' $checked{'MSSFIX'}{'on'} /></td>
-         <td>$Lang::tr{'openvpn default'}: off</td>
-         </tr>
+               <td class='base'>Keepalive <br />
+               (ping/ping-restart)</td>
+               <td><input type='TEXT' name='KEEPALIVE_1' value='$cgiparams{'KEEPALIVE_1'}' size='10' /></td>
+               <td><input type='TEXT' name='KEEPALIVE_2' value='$cgiparams{'KEEPALIVE_2'}' size='10' /></td>
+       </tr>
 
        <tr>
                <td class='base'>$Lang::tr{'ovpn mtu-disc'}</td>
@@ -2804,7 +2911,7 @@ END
     </tr>
 END
 ;
-       my $filename = "/var/log/ovpnserver.log";
+       my $filename = "/var/run/ovpnserver.log";
        open(FILE, $filename) or die 'Unable to open config file.';
        my @current = <FILE>;
        close(FILE);
@@ -3155,7 +3262,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]);
@@ -3947,10 +4053,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'}))) {
@@ -3995,6 +4099,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*$/\./;
@@ -4022,7 +4130,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",
@@ -4265,6 +4373,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:
@@ -4626,27 +4735,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
@@ -4801,7 +4911,7 @@ END
     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
-    my @status = `/bin/cat /var/log/ovpnserver.log`;
+    my @status = `/bin/cat /var/run/ovpnserver.log`;
 
     if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") {
                if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
@@ -5003,24 +5113,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>";
@@ -5039,9 +5166,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>";
@@ -5170,7 +5294,9 @@ END
 END
        ;
        $id++;
+       $lastnet = $confighash{$key}[32];
     }
+    print"</table>";
     ;
 
     # If the config file contains entries, print Key to action icons
@@ -5215,6 +5341,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'>
@@ -5227,7 +5355,10 @@ END
     ;
     my $col1="bgcolor='$color{'color22'}'";
     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`;
@@ -5239,15 +5370,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 {
@@ -5256,7 +5388,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
                ;
     }
@@ -5272,15 +5405,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 {
@@ -5289,7 +5423,8 @@ 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
                ;
     }
@@ -5297,7 +5432,7 @@ 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    =~ /PKCS#3 (.*)[\n]/;
+               $dhsubject    =~ /    (.*)[\n]/;
                $dhsubject    = $1;
 
 
@@ -5305,15 +5440,14 @@ 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>
+                       <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' />
-               </td></form>
-               <form method='post' name='frmdhparam'><td width='3%' align='center' $col3>
-                       <input type='image' name="$Lang::tr{'download dh parameter'}" src='/images/media-floppy.png' alt="$Lang::tr{'download dh parameter'}" title="$Lang::tr{'download dh parameter'}" border='0' />
-                       <input type='hidden' name='ACTION' value="$Lang::tr{'download dh parameter'}" />
-               </td></form>
-               <td width='4%' $col3>&nbsp;</td></tr>
+                       </form>
+                       <form method='post' name='frmdhparam'><td width='3%' align='center' $col3>
+                       </form>
+                       <td width='4%' $col3>&nbsp;</td>
+               </tr>
 END
                ;
     } else {
@@ -5322,7 +5456,42 @@ 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>
+                       </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
                ;
     }
@@ -5385,6 +5554,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>