]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - html/cgi-bin/ovpnmain.cgi
fireinfo.cgi: Fix kernel version
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / ovpnmain.cgi
index eac962e6c7ba9f16fb7f0bd3778adaaf5df80b2f..7a2833ce61bd5c283ef72112d41fd7e48df96092 100644 (file)
@@ -35,7 +35,7 @@ require '/var/ipfire/general-functions.pl';
 require "${General::swroot}/lang.pl";
 require "${General::swroot}/header.pl";
 require "${General::swroot}/countries.pl";
-require "${General::swroot}/geoip-functions.pl";
+require "${General::swroot}/location-functions.pl";
 
 # enable only the following on debugging purpose
 #use warnings;
@@ -47,7 +47,7 @@ undef (@dummy);
 my %color = ();
 my %mainsettings = ();
 &General::readhash("${General::swroot}/main/settings", \%mainsettings);
-&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
+&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color);
 
 ###
 ### Initialize variables
@@ -64,6 +64,8 @@ my %cahash=();
 my %selected=();
 my $warnmessage = '';
 my $errormessage = '';
+my $cryptoerror = '';
+my $cryptowarning = '';
 my %settings=();
 my $routes_push_file = '';
 my $confighost="${General::swroot}/fwhosts/customhosts";
@@ -97,6 +99,8 @@ $cgiparams{'DCIPHER'} = '';
 $cgiparams{'DAUTH'} = '';
 $cgiparams{'TLSAUTH'} = '';
 $routes_push_file = "${General::swroot}/ovpn/routes_push";
+# Perform crypto and configration test
+&pkiconfigcheck;
 
 # Add CCD files if not already presant
 unless (-e $routes_push_file) {
@@ -170,7 +174,12 @@ sub cleanssldatabase
        print FILE "";
        close FILE;
     }
+    if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt.attr")) {
+      print FILE "";
+      close FILE;
+    }
     unlink ("${General::swroot}/ovpn/certs/index.txt.old");
+    unlink ("${General::swroot}/ovpn/certs/index.txt.attr.old");
     unlink ("${General::swroot}/ovpn/certs/serial.old");
     unlink ("${General::swroot}/ovpn/certs/01.pem");
 }
@@ -183,9 +192,13 @@ sub newcleanssldatabase
        close FILE;
     }
     if (! -s ">${General::swroot}/ovpn/certs/index.txt") {
-       system ("touch ${General::swroot}/ovpn/certs/index.txt");
+       &General::system("touch", "${General::swroot}/ovpn/certs/index.txt");
+    }
+    if (! -s ">${General::swroot}/ovpn/certs/index.txt.attr") {
+       &General::system("touch", "${General::swroot}/ovpn/certs/index.txt.attr");
     }
     unlink ("${General::swroot}/ovpn/certs/index.txt.old");
+    unlink ("${General::swroot}/ovpn/certs/index.txt.attr.old");
     unlink ("${General::swroot}/ovpn/certs/serial.old");
 }
 
@@ -199,6 +212,57 @@ sub deletebackupcert
        }
 }
 
+###
+### Check for PKI and configure problems
+###
+
+sub pkiconfigcheck
+{
+       # Warning if DH parameter is 1024 bit
+       if (-f "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}") {
+               my @dhparameter = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}");
+               my $dhbit;
+
+               # Loop through the output and search for the DH bit lenght.
+               foreach my $line (@dhparameter) {
+                       if ($line =~ (/(\d+)/)) {
+                               # Assign match to dhbit value.
+                               $dhbit = $1;
+
+                               last;
+                       }
+               }
+
+               # Check if the used key lenght is at least 2048 bit.
+               if ($dhbit < 2048) {
+                       $cryptoerror = "$Lang::tr{'ovpn error dh'}";
+                       goto CRYPTO_ERROR;
+               }
+       }
+
+       # Warning if md5 is in usage
+       if (-f "${General::swroot}/ovpn/certs/servercert.pem") {
+               my @signature = &General::system_output("/usr/bin/openssl", "x509", "-noout", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
+               if (grep(/md5WithRSAEncryption/, @signature) ) {
+                       $cryptoerror = "$Lang::tr{'ovpn error md5'}";
+                       goto CRYPTO_ERROR;
+               }
+       }
+
+       CRYPTO_ERROR:
+
+       # Warning if certificate is not compliant to RFC3280 TLS rules
+       if (-f "${General::swroot}/ovpn/certs/servercert.pem") {
+               my @extendkeyusage = &General::system_output("/usr/bin/openssl", "x509", "-noout", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
+               if ( ! grep(/TLS Web Server Authentication/, @extendkeyusage)) {
+                       $cryptowarning = "$Lang::tr{'ovpn warning rfc3280'}";
+                       goto CRYPTO_WARNING;
+               }
+       }
+
+       CRYPTO_WARNING:
+}
+
 sub writeserverconf {
     my %sovpnsettings = ();  
     my @temp = ();  
@@ -228,14 +292,7 @@ sub writeserverconf {
     print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
     #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n";
 
-    # Check if we are using mssfix, fragment or mtu-disc and set the corretct mtu of 1500.
-    # If we doesn't use one of them, we can use the configured mtu value.
-    if ($sovpnsettings{'MSSFIX'} eq 'on') 
-       { print CONF "tun-mtu 1500\n"; }
-    elsif ($sovpnsettings{'FRAGMENT'} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') 
-       { print CONF "tun-mtu 1500\n"; }
-    else 
-       { print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; }
+    print CONF "tun-mtu $sovpnsettings{'DMTU'}\n";
 
     if ($vpnsettings{'ROUTES_PUSH'} ne '') {
                @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'});
@@ -268,6 +325,8 @@ sub writeserverconf {
     }
     if ($sovpnsettings{MSSFIX} eq 'on') {
                print CONF "mssfix\n";
+    } else {
+               print CONF "mssfix 0\n";
     }
     if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') {
                print CONF "fragment $sovpnsettings{'FRAGMENT'}\n";
@@ -280,11 +339,10 @@ sub writeserverconf {
     print CONF "status /var/run/ovpnserver.log 30\n";
     print CONF "ncp-disable\n";
     print CONF "cipher $sovpnsettings{DCIPHER}\n";
-    if ($sovpnsettings{'DAUTH'} eq '') {
-        print CONF "";
-    } else {
        print CONF "auth $sovpnsettings{'DAUTH'}\n";
-    }
+    # Set TLSv2 as minimum
+    print CONF "tls-version-min 1.2\n";
+
     if ($sovpnsettings{'TLSAUTH'} eq 'on') {
        print CONF "tls-auth ${General::swroot}/ovpn/certs/ta.key\n";
     }
@@ -306,10 +364,10 @@ sub writeserverconf {
         print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n";
     }
     
-    if ($sovpnsettings{DHCP_WINS} eq '') {
+    if ($sovpnsettings{MAX_CLIENTS} eq '') {
        print CONF "max-clients 100\n";
     }
-    if ($sovpnsettings{DHCP_WINS} ne '') {
+    if ($sovpnsettings{MAX_CLIENTS} ne '') {
        print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n";
     }  
     print CONF "tls-verify /usr/lib/openvpn/verify\n";
@@ -323,6 +381,11 @@ sub writeserverconf {
        } else {
                print CONF "verb 3\n";
        }
+
+    print CONF "# Log clients connecting/disconnecting\n";
+    print CONF "client-connect \"/usr/sbin/openvpn-metrics client-connect\"\n";
+    print CONF "client-disconnect \"/usr/sbin/openvpn-metrics client-disconnect\"\n";
+
     # Print server.conf.local if entries exist to server.conf
     if ( !-z $local_serverconf  && $sovpnsettings{'ADDITIONAL_CONFIGS'} eq 'on') {
        open (LSC, "$local_serverconf");
@@ -417,10 +480,7 @@ sub addccdnet
                $errormessage=$Lang::tr{'ccd err invalidnet'};
                return;
        }
-       
-       $errormessage=&General::checksubnets($ccdname,$ccdnet);
-       
-               
+
        if (!$errormessage) {
                my %ccdconfhash=();
                $baseaddress=&General::getnetworkip($ccdip,$subcidr);
@@ -444,6 +504,13 @@ sub modccdnet
        my $oldname=$_[1];
        my %ccdconfhash=();
        my %ccdhash=();
+
+       # Check if the new name is valid.
+       if(!&General::validhostname($newname)) {
+               $errormessage=$Lang::tr{'ccd err invalidname'};
+               return;
+       }
+
        &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
        foreach my $key (keys %ccdconfhash) {
                if ($ccdconfhash{$key}[0] eq $oldname) {
@@ -679,7 +746,7 @@ sub writecollectdconf {
        close(COLLECTDVPN);
 
        # Reload collectd afterwards
-       system("/usr/local/bin/collectdctrl restart &>/dev/null");
+       &General::system("/usr/local/bin/collectdctrl", "restart");
 }
 
 #hier die refresh page
@@ -709,11 +776,11 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} ||
     #start openvpn server
     if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'}){
        &emptyserverlog();
-       system('/usr/local/bin/openvpnctrl', '-s');
+       &General::system("/usr/local/bin/openvpnctrl", "-s");
     }   
     #stop openvpn server
     if ($cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'}){
-       system('/usr/local/bin/openvpnctrl', '-k');
+       &General::system("/usr/local/bin/openvpnctrl", "-k");
        &emptyserverlog();      
     }   
 #    #restart openvpn server
@@ -739,13 +806,12 @@ 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{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'};
     $vpnsettings{'ADDITIONAL_CONFIGS'} = $cgiparams{'ADDITIONAL_CONFIGS'};
     $vpnsettings{'DHCP_DOMAIN'} = $cgiparams{'DHCP_DOMAIN'};
     $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'};
     $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'};
     $vpnsettings{'ROUTES_PUSH'} = $cgiparams{'ROUTES_PUSH'};
-    $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'};
-    $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'};
     my @temp=();
     
     if ($cgiparams{'FRAGMENT'} eq '') {
@@ -833,7 +899,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) {
        undef $vpnsettings{'ROUTES_PUSH'};
        &write_routepushfile;
     }
-    if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 255 )) {
+    if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 1024 )) {
         $errormessage = $Lang::tr{'invalid input for max clients'};
         goto ADV_ERROR;
     }
@@ -853,17 +919,6 @@ 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
 }
@@ -927,7 +982,7 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}};
   print SERVERCONF "tun-mtu $tunmtu\n";
   if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment $cgiparams{'FRAGMENT'}\n";} 
-  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }
+  if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; } else { print SERVERCONF "mssfix 0\n" };
   }
 
   print SERVERCONF "# Auth. Server\n"; 
@@ -950,6 +1005,9 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
     print SERVERCONF "auth $cgiparams{'DAUTH'}\n";
   }
 
+  # Set TLSv1.2 as minimum
+  print SERVERCONF "tls-version-min 1.2\n";
+
   if ($cgiparams{'COMPLZO'} eq 'on') {
    print SERVERCONF "# Enable Compression\n";
    print SERVERCONF "comp-lzo\n";
@@ -1023,14 +1081,14 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}};
   print CLIENTCONF "tun-mtu $tunmtu\n";
   if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment $cgiparams{'FRAGMENT'}\n";}
-  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }
+  if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; } else { print CLIENTCONF "mssfix 0\n" };
   }
 
   # Check host certificate if X509 is RFC3280 compliant.
   # If not, old --ns-cert-type directive will be used.
   # If appropriate key usage extension exists, new --remote-cert-tls directive will be used.
-  my $hostcert = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
-  if ($hostcert !~ /TLS Web Server Authentication/) {
+  my @hostcert = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
+  if ( ! grep(/TLS Web Server Authentication/, @hostcert)) {
        print CLIENTCONF "ns-cert-type server\n";
   } else {
        print CLIENTCONF "remote-cert-tls server\n";
@@ -1052,6 +1110,9 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
     print CLIENTCONF "auth $cgiparams{'DAUTH'}\n";
   }
 
+  # Set TLSv1.2 as minimum
+  print CLIENTCONF "tls-version-min 1.2\n";
+
   if ($cgiparams{'COMPLZO'} eq 'on') {
    print CLIENTCONF "# Enable Compression\n";
    print CLIENTCONF "comp-lzo\n";
@@ -1069,7 +1130,7 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General
   close(CLIENTCONF);
 
 }
-  
+
 ###
 ### Save main settings
 ###
@@ -1144,6 +1205,18 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg
        goto SETTINGS_ERROR;
     }
 
+       # Create ta.key for tls-auth if not presant
+       if ($cgiparams{'TLSAUTH'} eq 'on') {
+               if ( ! -e "${General::swroot}/ovpn/certs/ta.key") {
+                       # This system call is safe, because all arguements are passed as an array.
+                       system("/usr/sbin/openvpn", "--genkey", "--secret", "${General::swroot}/ovpn/certs/ta.key");
+                       if ($?) {
+                               $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
+                               goto SETTINGS_ERROR;
+                       }
+               }
+       }
+
     $vpnsettings{'ENABLED_BLUE'} = $cgiparams{'ENABLED_BLUE'};
     $vpnsettings{'ENABLED_ORANGE'} =$cgiparams{'ENABLED_ORANGE'};
     $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'};
@@ -1155,11 +1228,28 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg
     $vpnsettings{'DMTU'} = $cgiparams{'DMTU'};
     $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'};
     $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'};
+    $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'};
+    $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'};
 #wrtie enable
 
-  if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable_blue 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable_blue 2>/dev/null");}
-  if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable_orange 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable_orange 2>/dev/null");}
-  if ( $vpnsettings{'ENABLED'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable 2>/dev/null");}
+  if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' ) {
+         &General::system("touch", "${General::swroot}/ovpn/enable_blue");
+  } else {
+         unlink("${General::swroot}/ovpn/enable_blue");
+  }
+
+  if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' ) {
+         &General::system("touch", "${General::swroot}/ovpn/enable_orange");
+  } else {
+         unlink("${General::swroot}/ovpn/enable_orange");
+  }
+
+  if ( $vpnsettings{'ENABLED'} eq 'on' ) {
+         &General::system("touch", "${General::swroot}/ovpn/enable");
+  } else {
+         unlink("${General::swroot}/ovpn/enable");
+  }
+
 #new settings for daemon    
     &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings);
     &writeserverconf();#hier ok
@@ -1172,7 +1262,7 @@ SETTINGS_ERROR:
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
     # Kill all N2N connections
-    system("/usr/local/bin/openvpnctrl -kn2n &>/dev/null");
+    &General::system("/usr/local/bin/openvpnctrl", "-kn2n");
 
     foreach my $key (keys %confighash) {
        my $name = $confighash{$cgiparams{'$key'}}[1];
@@ -1181,7 +1271,7 @@ SETTINGS_ERROR:
            delete $confighash{$cgiparams{'$key'}};
        }
 
-       system ("/usr/local/bin/openvpnctrl -drrd $name");
+       &General::system("/usr/local/bin/openvpnctrl", "-drrd", "$name");
     }
     while ($file = glob("${General::swroot}/ovpn/ca/*")) {
        unlink $file;
@@ -1220,7 +1310,7 @@ SETTINGS_ERROR:
        close FILE;
     }
     while ($file = glob("${General::swroot}/ovpn/n2nconf/*")) {
-       system ("rm -rf $file");
+       unlink($file);
     }
 
     # Remove everything from the collectd configuration
@@ -1266,7 +1356,8 @@ END
         unlink "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}";
        }
        # Create Diffie Hellmann Parameter
-       system('/usr/bin/openssl', 'dhparam', '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}");
+       # The system call is safe, because all arguments are passed as an array.
+       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");
@@ -1291,7 +1382,6 @@ END
                <form method='post'><input type='hidden' name='AREUSURE' value='yes' />
                <input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />
                        <select name='DHLENGHT'>
-                               <option value='1024' $selected{'DHLENGHT'}{'1024'}>1024 $Lang::tr{'bit'} ($Lang::tr{'vpn weak'})</option>
                                <option value='2048' $selected{'DHLENGHT'}{'2048'}>2048 $Lang::tr{'bit'}</option>
                                <option value='3072' $selected{'DHLENGHT'}{'3072'}>3072 $Lang::tr{'bit'}</option>
                                <option value='4096' $selected{'DHLENGHT'}{'4096'}>4096 $Lang::tr{'bit'}</option>
@@ -1326,7 +1416,7 @@ END
 ### Upload DH key
 ###
 } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload dh key'}) {
-    if (ref ($cgiparams{'FH'}) ne 'Fh') {
+    unless (ref ($cgiparams{'FH'})) {
          $errormessage = $Lang::tr{'there was no file upload'};
          goto UPLOADCA_ERROR;
     }
@@ -1336,8 +1426,8 @@ END
         $errormessage = $!;
        goto UPLOADCA_ERROR;
     }
-    my $temp = `/usr/bin/openssl dhparam -text -in $filename`;
-    if ($temp !~ /DH Parameters: \((1024|2048|3072|4096) bit\)/) {
+    my @temp = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "$filename");
+    if ( ! grep(/DH Parameters: \((2048|3072|4096) bit\)/, @temp)) {
         $errormessage = $Lang::tr{'not a valid dh key'};
         unlink ($filename);
         goto UPLOADCA_ERROR;
@@ -1383,7 +1473,7 @@ END
        }
     }
 
-    if (ref ($cgiparams{'FH'}) ne 'Fh') {
+    unless (ref ($cgiparams{'FH'})) {
        $errormessage = $Lang::tr{'there was no file upload'};
        goto UPLOADCA_ERROR;
     }
@@ -1393,8 +1483,8 @@ END
        $errormessage = $!;
        goto UPLOADCA_ERROR;
     }
-    my $temp = `/usr/bin/openssl x509 -text -in $filename`;
-    if ($temp !~ /CA:TRUE/i) {
+    my @temp = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "$filename");
+    if ( ! grep(/CA:TRUE/i, @temp )) {
        $errormessage = $Lang::tr{'not a valid ca certificate'};
        unlink ($filename);
        goto UPLOADCA_ERROR;
@@ -1407,11 +1497,19 @@ END
        }
     }
 
-    my $casubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem`;
-    $casubject    =~ /Subject: (.*)[\n]/;
-    $casubject    = $1;
-    $casubject    =~ s+/Email+, E+;
-    $casubject    =~ s/ ST=/ S=/;
+    my @casubject = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/ca/$cgiparams{'CA_NAME'}cert.pem");
+    my $casubject;
+
+    foreach my $line (@casubject) {
+       if ($line =~ /Subject: (.*)[\n]/) {
+               $casubject    = $1;
+               $casubject    =~ s+/Email+, E+;
+               $casubject    =~ s/ ST=/ S=/;
+
+               last;
+       }
+    }
+
     $casubject    = &Header::cleanhtml($casubject);
 
     my $key = &General::findhasharraykey (\%cahash);
@@ -1433,9 +1531,9 @@ END
        &Header::openpage($Lang::tr{'ovpn'}, 1, '');
        &Header::openbigbox('100%', 'LEFT', '', $errormessage);
        &Header::openbox('100%', 'LEFT', "$Lang::tr{'ca certificate'}:");
-       my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`;
-       $output = &Header::cleanhtml($output,"y");
-       print "<pre>$output</pre>\n";
+       my @output = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem");
+       @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();
@@ -1454,7 +1552,10 @@ END
     if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
        print "Content-Type: application/octet-stream\r\n";
        print "Content-Disposition: filename=$cahash{$cgiparams{'KEY'}}[0]cert.pem\r\n\r\n";
-       print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem`;
+
+       my @tmp =  &General::system_output("/usr/bin/openssl", "x509", "-in", "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem");
+       print "@tmp";
+
        exit(0);
     } else {
        $errormessage = $Lang::tr{'invalid key'};
@@ -1469,8 +1570,8 @@ END
 
     if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
        foreach my $key (keys %confighash) {
-           my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
-           if ($test =~ /: OK/) {
+           my @test = &General::system_output("/usr/bin/openssl", "verify", "-CAfile", "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem", "${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem");
+           if (grep(/: OK/, @test)) {
                # Delete connection
 #              if ($vpnsettings{'ENABLED'} eq 'on' ||
 #                  $vpnsettings{'ENABLED_BLUE'} eq 'on') {
@@ -1500,8 +1601,8 @@ END
     my $assignedcerts = 0;
     if ( -f "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem" ) {
        foreach my $key (keys %confighash) {
-           my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
-           if ($test =~ /: OK/) {
+           my @test = &General::system_output("/usr/bin/openssl", "verify", "-CAfile", "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem", "${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem");
+           if (grep(/: OK/, @test)) {
                $assignedcerts++;
            }
        }
@@ -1540,19 +1641,19 @@ END
 ###
 }elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'} ||
     $cgiparams{'ACTION'} eq $Lang::tr{'show host certificate'}) {
-    my $output;
+    my @output;
     &Header::showhttpheaders();
     &Header::openpage($Lang::tr{'ovpn'}, 1, '');
     &Header::openbigbox('100%', 'LEFT', '', '');
     if ($cgiparams{'ACTION'} eq $Lang::tr{'show root certificate'}) {
        &Header::openbox('100%', 'LEFT', "$Lang::tr{'root certificate'}:");
-       $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/ca/cacert.pem`;
+       @output = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/ca/cacert.pem");
     } else {
        &Header::openbox('100%', 'LEFT', "$Lang::tr{'host certificate'}:");
-       $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
+       @output = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
     }
-    $output = &Header::cleanhtml($output,"y");
-    print "<pre>$output</pre>\n";
+    @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();
@@ -1566,7 +1667,10 @@ END
     if ( -f "${General::swroot}/ovpn/ca/cacert.pem" ) {
        print "Content-Type: application/octet-stream\r\n";
        print "Content-Disposition: filename=cacert.pem\r\n\r\n";
-       print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/ca/cacert.pem`;
+
+       my @tmp = &General::system_output("/usr/bin/openssl", "x509", "-in", "${General::swroot}/ovpn/ca/cacert.pem");
+       print "@tmp";
+
        exit(0);
     }
     
@@ -1577,7 +1681,10 @@ END
     if ( -f "${General::swroot}/ovpn/certs/servercert.pem" ) {
        print "Content-Type: application/octet-stream\r\n";
        print "Content-Disposition: filename=servercert.pem\r\n\r\n";
-       print `/usr/bin/openssl x509 -in ${General::swroot}/ovpn/certs/servercert.pem`;
+
+       my @tmp = &General::system_output("/usr/bin/openssl", "x509", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
+       print "@tmp";
+
        exit(0);
     }
 
@@ -1588,7 +1695,13 @@ END
     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`;
+
+       open(FILE, "${General::swroot}/ovpn/certs/ta.key");
+       my @tmp = <FILE>;
+       close(FILE);
+
+       print "@tmp";
+
        exit(0);
     }
 
@@ -1616,8 +1729,7 @@ END
            }
        }
     } elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload p12 file'}) {
-
-       if (ref ($cgiparams{'FH'}) ne 'Fh') {
+       unless (ref ($cgiparams{'FH'})) {
            $errormessage = $Lang::tr{'there was no file upload'};
            goto ROOTCERT_ERROR;
        }
@@ -1866,6 +1978,7 @@ END
        }
        
        # Sign the host certificate request
+       # This system call is safe, because all argeuments are passed as an array.
        system('/usr/bin/openssl', 'ca', '-days', '999999',
                '-batch', '-notext',
                '-in',  "${General::swroot}/ovpn/certs/serverreq.pem",
@@ -1887,6 +2000,7 @@ END
        }
 
        # Create an empty CRL
+       # System call is safe, because all arguments are passed as array.
        system('/usr/bin/openssl', 'ca', '-gencrl',
                '-out', "${General::swroot}/ovpn/crls/cacrl.pem",
                '-config', "${General::swroot}/ovpn/openssl/ovpn.cnf" );
@@ -1901,7 +2015,16 @@ END
 #      } else {
 #          &cleanssldatabase();
        }
+       # Create ta.key for tls-auth
+       # This system call is safe, because all arguments are passed as an array.
+       system('/usr/sbin/openvpn', '--genkey', '--secret', "${General::swroot}/ovpn/certs/ta.key");
+       if ($?) {
+           $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
+           &cleanssldatabase();
+           goto ROOTCERT_ERROR;
+       }
        # Create Diffie Hellmann Parameter
+       # The system call is safe, because all arguments are passed as an array.
        system('/usr/bin/openssl', 'dhparam', '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}");
        if ($?) {
            $errormessage = "$Lang::tr{'openssl produced an error'}: $?";
@@ -1915,13 +2038,6 @@ END
 #      } 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:
@@ -1973,7 +2089,6 @@ END
            </select></td>
        <tr><td class='base'>$Lang::tr{'ovpn dh'}:</td>
                <td class='base'><select name='DHLENGHT'>
-                               <option value='1024' $selected{'DHLENGHT'}{'1024'}>1024 $Lang::tr{'bit'} ($Lang::tr{'vpn weak'}</option>
                                <option value='2048' $selected{'DHLENGHT'}{'2048'}>2048 $Lang::tr{'bit'}</option>
                                <option value='3072' $selected{'DHLENGHT'}{'3072'}>3072 $Lang::tr{'bit'}</option>
                                <option value='4096' $selected{'DHLENGHT'}{'4096'}>4096 $Lang::tr{'bit'}</option>
@@ -2024,7 +2139,7 @@ END
     }
 
     ROOTCERT_SUCCESS:
-    system ("chmod 600 ${General::swroot}/ovpn/certs/serverkey.pem");
+    &General::system("chmod", "600", "${General::swroot}/ovpn/certs/serverkey.pem");
 #    if ($vpnsettings{'ENABLED'} eq 'on' ||
 #      $vpnsettings{'ENABLE_BLUE'} eq 'on') {
 #      system('/usr/local/bin/ipsecctrl', 'S');
@@ -2042,8 +2157,12 @@ END
     
     &General::readhash("${General::swroot}/ovpn/settings", \%vpnsettings);
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
-#    my $n2nactive = '';
-    my $n2nactive = `/bin/ps ax|grep $confighash{$cgiparams{'KEY'}}[1]|grep -v grep|awk \'{print \$1}\'`;
+    my $n2nactive = '';
+    my @ps = &General::system_output("/bin/ps", "ax");
+
+    if(grep(/$confighash{$cgiparams{'KEY'}}[1]/, @ps)) {
+       $n2nactive = "1";
+    }
     
     if ($confighash{$cgiparams{'KEY'}}) {
                if ($confighash{$cgiparams{'KEY'}}[0] eq 'off') {
@@ -2051,7 +2170,7 @@ END
                        &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
                        if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
-                               system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]);
+                               &General::system("/usr/local/bin/openvpnctrl", "-sn2n", "$confighash{$cgiparams{'KEY'}}[1]");
                                &writecollectdconf();
                        }
                } else {
@@ -2061,7 +2180,7 @@ END
 
                        if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
                                if ($n2nactive ne '') {
-                                       system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]);
+                                       &General::system("/usr/local/bin/openvpnctrl", "-kn2n", "$confighash{$cgiparams{'KEY'}}[1]");
                                        &writecollectdconf();
                                }
  
@@ -2140,22 +2259,13 @@ if ($confighash{$cgiparams{'KEY'}}[3] eq 'net'){
    if ($confighash{$cgiparams{'KEY'}}[31] eq '') {$tunmtu = '1500'} else {$tunmtu = $confighash{$cgiparams{'KEY'}}[31]};
    print CLIENTCONF "tun-mtu $tunmtu\n";
    if ($confighash{$cgiparams{'KEY'}}[24] ne '') {print CLIENTCONF "fragment $confighash{$cgiparams{'KEY'}}[24]\n";}
-   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF "mssfix\n";}
-   }
-   if (($confighash{$cgiparams{'KEY'}}[38] eq 'yes') ||
-       ($confighash{$cgiparams{'KEY'}}[38] eq 'maybe') ||
-       ($confighash{$cgiparams{'KEY'}}[38] eq 'no' )) {
-       if (($confighash{$cgiparams{'KEY'}}[23] ne 'on') || ($confighash{$cgiparams{'KEY'}}[24] eq '')) {
-               if ($tunmtu eq '1500' ) {
-                       print CLIENTCONF "mtu-disc $confighash{$cgiparams{'KEY'}}[38]\n";
-               }
-       }
+   if ($confighash{$cgiparams{'KEY'}}[23] eq 'on') {print CLIENTCONF "mssfix\n";} else { print CLIENTCONF "mssfix 0\n"; }
    }
    # Check host certificate if X509 is RFC3280 compliant.
    # If not, old --ns-cert-type directive will be used.
    # If appropriate key usage extension exists, new --remote-cert-tls directive will be used.
-   my $hostcert = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
-   if ($hostcert !~ /TLS Web Server Authentication/) {
+   my @hostcert = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
+   if (! grep(/TLS Web Server Authentication/, @hostcert)) {
                print CLIENTCONF "ns-cert-type server\n";
    } else {
                print CLIENTCONF "remote-cert-tls server\n";
@@ -2230,15 +2340,7 @@ else
     print CLIENTCONF "nobind\r\n";
     print CLIENTCONF "dev tun\r\n";
     print CLIENTCONF "proto $vpnsettings{'DPROTOCOL'}\r\n";
-
-    # Check if we are using fragment, mssfix or mtu-disc and set MTU to 1500
-    # or use configured value.
-    if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' )
-       { print CLIENTCONF "tun-mtu 1500\r\n"; }
-    elsif ($vpnsettings{MSSFIX} eq 'on')
-       { print CLIENTCONF "tun-mtu 1500\r\n"; }
-    else
-       { print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n"; }
+    print CLIENTCONF "tun-mtu $vpnsettings{'DMTU'}\r\n";
 
     if ( $vpnsettings{'ENABLED'} eq 'on'){
        print CLIENTCONF "remote $vpnsettings{'VPN_IP'} $vpnsettings{'DDEST_PORT'}\r\n";
@@ -2273,6 +2375,7 @@ else
                $zip->addFile("${General::swroot}/ovpn/ca/cacert.pem", "cacert.pem")  or die "Can't add file cacert.pem\n";
 
                # Extract the certificate
+               # This system call is safe, because all arguments are passed as an array.
                system('/usr/bin/openssl', 'pkcs12', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
                        '-clcerts', '-nokeys', '-nodes', '-out', "$file_crt" , '-passin', 'pass:');
                if ($?) {
@@ -2283,6 +2386,7 @@ else
                print CLIENTCONF ";cert $confighash{$cgiparams{'KEY'}}[1].pem\r\n";
 
                # Extract the key
+               # This system call is safe, because all arguments are passed as an array.
                system('/usr/bin/openssl', 'pkcs12', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
                        '-nocerts', '-nodes', '-out', "$file_key", '-passin', 'pass:');
                if ($?) {
@@ -2303,11 +2407,8 @@ else
        $zip->addFile( "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem", "$confighash{$cgiparams{'KEY'}}[1]cert.pem") or die "Can't add file $confighash{$cgiparams{'KEY'}}[1]cert.pem\n";    
     }
     print CLIENTCONF "cipher $vpnsettings{DCIPHER}\r\n";
-    if ($vpnsettings{'DAUTH'} eq '') {
-        print CLIENTCONF "";
-    } else {
        print CLIENTCONF "auth $vpnsettings{'DAUTH'}\r\n";
-    }
+
     if ($vpnsettings{'TLSAUTH'} eq 'on') {
        if ($cgiparams{'MODE'} eq 'insecure') {
                print CLIENTCONF ";";
@@ -2322,8 +2423,8 @@ else
        # Check host certificate if X509 is RFC3280 compliant.
        # If not, old --ns-cert-type directive will be used.
        # If appropriate key usage extension exists, new --remote-cert-tls directive will be used.
-       my $hostcert = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
-       if ($hostcert !~ /TLS Web Server Authentication/) {
+       my @hostcert = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
+       if (! grep(/TLS Web Server Authentication/, @hostcert)) {
                print CLIENTCONF "ns-cert-type server\r\n";
        } else {
                print CLIENTCONF "remote-cert-tls server\r\n";
@@ -2331,6 +2432,8 @@ else
     print CLIENTCONF "verify-x509-name $vpnsettings{ROOTCERT_HOSTNAME} name\r\n";
     if ($vpnsettings{MSSFIX} eq 'on') {
        print CLIENTCONF "mssfix\r\n";
+    } else {
+       print CLIENTCONF "mssfix 0\r\n";
     }
     if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) {
        print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
@@ -2423,8 +2526,8 @@ else
 
        if ($confighash{$cgiparams{'KEY'}}) {
                # Revoke certificate if certificate was deleted and rewrite the CRL
-               my $temp = `/usr/bin/openssl ca -revoke ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
-               my $tempA = `/usr/bin/openssl ca -gencrl -out ${General::swroot}/ovpn/crls/cacrl.pem -config ${General::swroot}/ovpn/openssl/ovpn.cnf`;
+               &General::system("/usr/bin/openssl", "ca", "-revoke", "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem", "-config", "${General::swroot}/ovpn/openssl/ovpn.cnf");
+               &General::system("/usr/bin/openssl", "ca", "-gencrl", "-out", "${General::swroot}/ovpn/crls/cacrl.pem", "-config", "${General::swroot}/ovpn/openssl/ovpn.cnf");
 
 ###
 # m.a.d net2net
@@ -2432,7 +2535,7 @@ else
 
                if ($confighash{$cgiparams{'KEY'}}[3] eq 'net') {
                        # Stop the N2N connection before it is removed
-                       system("/usr/local/bin/openvpnctrl -kn2n $confighash{$cgiparams{'KEY'}}[1] &>/dev/null");
+                       &General::system("/usr/local/bin/openvpnctrl", "-kn2n", "$confighash{$cgiparams{'KEY'}}[1]");
 
                        my $conffile = glob("${General::swroot}/ovpn/n2nconf/$confighash{$cgiparams{'KEY'}}[1]/$confighash{$cgiparams{'KEY'}}[1].conf");
                        my $certfile = glob("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
@@ -2474,10 +2577,10 @@ else
 # CCD end
                # Update collectd configuration and delete all RRD files of the removed connection
                &writecollectdconf();
-               system ("/usr/local/bin/openvpnctrl -drrd $confighash{$cgiparams{'KEY'}}[1]");
+               &General::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::system("/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);
 
        } else {
@@ -2493,7 +2596,12 @@ else
 
     print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . ".p12\r\n";
     print "Content-Type: application/octet-stream\r\n\r\n";
-    print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12`;
+
+    open(FILE, "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12");
+    my @tmp = <FILE>;
+    close(FILE);
+
+    print "@tmp";
     exit (0);
 
 ###
@@ -2507,9 +2615,9 @@ else
        &Header::openpage($Lang::tr{'ovpn'}, 1, '');
        &Header::openbigbox('100%', 'LEFT', '', '');
        &Header::openbox('100%', 'LEFT', "$Lang::tr{'certificate'}:");
-       my $output = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`;
-       $output = &Header::cleanhtml($output,"y");
-       print "<pre>$output</pre>\n";
+       my @output = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
+       @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();
@@ -2529,9 +2637,9 @@ else
                &Header::openpage($Lang::tr{'ovpn'}, 1, '');
                &Header::openbigbox('100%', 'LEFT', '', '');
                &Header::openbox('100%', 'LEFT', "$Lang::tr{'dh'}:");
-               my $output = `/usr/bin/openssl dhparam -text -in ${General::swroot}/ovpn/ca/dh1024.pem`;
-               $output = &Header::cleanhtml($output,"y");
-               print "<pre>$output</pre>\n";
+               my @output = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "${General::swroot}/ovpn/ca/dh1024.pem");
+               @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();
@@ -2551,9 +2659,13 @@ else
                &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";
+
+               open(FILE, "${General::swroot}/ovpn/certs/ta.key");
+               my @output = <FILE>;
+               close(FILE);
+
+               @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();
@@ -2574,9 +2686,9 @@ else
        &Header::openpage($Lang::tr{'ovpn'}, 1, '');
        &Header::openbigbox('100%', 'LEFT', '', '');
        &Header::openbox('100%', 'LEFT', "$Lang::tr{'crl'}:");
-       my $output = `/usr/bin/openssl crl -text -noout -in ${General::swroot}/ovpn/crls/cacrl.pem`;
-       $output = &Header::cleanhtml($output,"y");
-       print "<pre>$output</pre>\n";
+       my @output = &General::system_output("/usr/bin/openssl", "crl", "-text", "-noout", "-in", "${General::swroot}/ovpn/crls/cacrl.pem");
+       @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();
@@ -2613,9 +2725,6 @@ ADV_ERROR:
     if ($cgiparams{'LOG_VERB'} eq '') {
                $cgiparams{'LOG_VERB'} =  '3';
     }
-    if ($cgiparams{'DAUTH'} eq '') {
-               $cgiparams{'DAUTH'} = 'SHA512';
-    }
     if ($cgiparams{'TLSAUTH'} eq '') {
                $cgiparams{'TLSAUTH'} = 'off';
     }
@@ -2625,6 +2734,9 @@ ADV_ERROR:
     $checked{'REDIRECT_GW_DEF1'}{'off'} = '';
     $checked{'REDIRECT_GW_DEF1'}{'on'} = '';
     $checked{'REDIRECT_GW_DEF1'}{$cgiparams{'REDIRECT_GW_DEF1'}} = 'CHECKED';
+    $checked{'DCOMPLZO'}{'off'} = '';
+    $checked{'DCOMPLZO'}{'on'} = '';
+    $checked{'DCOMPLZO'}{$cgiparams{'DCOMPLZO'}} = 'CHECKED';
     $checked{'ADDITIONAL_CONFIGS'}{'off'} = '';
     $checked{'ADDITIONAL_CONFIGS'}{'on'} = '';
     $checked{'ADDITIONAL_CONFIGS'}{$cgiparams{'ADDITIONAL_CONFIGS'}} = 'CHECKED';
@@ -2644,15 +2756,6 @@ ADV_ERROR:
     $selected{'LOG_VERB'}{'10'} = '';
     $selected{'LOG_VERB'}{'11'} = '';
     $selected{'LOG_VERB'}{$cgiparams{'LOG_VERB'}} = 'SELECTED';
-    $selected{'DAUTH'}{'whirlpool'} = '';
-    $selected{'DAUTH'}{'SHA512'} = '';
-    $selected{'DAUTH'}{'SHA384'} = '';
-    $selected{'DAUTH'}{'SHA256'} = '';
-    $selected{'DAUTH'}{'SHA1'} = '';
-    $selected{'DAUTH'}{$cgiparams{'DAUTH'}} = 'SELECTED';
-    $checked{'TLSAUTH'}{'off'} = '';
-    $checked{'TLSAUTH'}{'on'} = '';
-    $checked{'TLSAUTH'}{$cgiparams{'TLSAUTH'}} = 'CHECKED';
    
     &Header::showhttpheaders();
     &Header::openpage($Lang::tr{'status ovpn'}, 1, '');
@@ -2712,7 +2815,7 @@ print <<END;
        </tr>
 
        <tr>
-               <td width='20%'></td> <td width='15%'> </td><td width='15%'> </td><td width='15%'></td><td width='35%'></td>
+               <td width='20%'></td> <td width='15%'> </td><td width='35%'> </td><td width='20%'></td><td width='35%'></td>
        </tr>
 
        <tr>
@@ -2725,6 +2828,11 @@ print <<END;
                <td><input type='checkbox' name='REDIRECT_GW_DEF1' $checked{'REDIRECT_GW_DEF1'}{'on'} /></td>
        </tr>
 
+    <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'comp-lzo'}</td>
+        <td><input type='checkbox' name='DCOMPLZO' $checked{'DCOMPLZO'}{'on'} /></td>
+        <td>$Lang::tr{'openvpn default'}: off <font color='red'>($Lang::tr{'attention'} exploitable via Voracle)</font></td>
+    </tr>
+
        <tr>
                <td class='base'>$Lang::tr{'ovpn add conf'}</td>
                <td><input type='checkbox' name='ADDITIONAL_CONFIGS' $checked{'ADDITIONAL_CONFIGS'}{'on'} /></td>
@@ -2782,36 +2890,6 @@ print <<END;
     </table>
 
 <hr size='1'>
-<table width='100%'>
-    <tr>
-               <td class'base'><b>$Lang::tr{'ovpn crypt options'}</b></td>
-       </tr>
-       <tr>
-               <td width='20%'></td> <td width='30%'> </td><td width='25%'> </td><td width='25%'></td>
-    </tr>      
-    <tr><td class='base'>$Lang::tr{'ovpn ha'}</td>
-               <td><select name='DAUTH'>
-                               <option value='whirlpool'               $selected{'DAUTH'}{'whirlpool'}>Whirlpool (512 $Lang::tr{'bit'})</option>
-                               <option value='SHA512'                  $selected{'DAUTH'}{'SHA512'}>SHA2 (512 $Lang::tr{'bit'})</option>
-                               <option value='SHA384'                  $selected{'DAUTH'}{'SHA384'}>SHA2 (384 $Lang::tr{'bit'})</option>
-                               <option value='SHA256'                  $selected{'DAUTH'}{'SHA256'}>SHA2 (256 $Lang::tr{'bit'})</option>
-                               <option value='SHA1'                    $selected{'DAUTH'}{'SHA1'}>SHA1 (160 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
-                       </select>
-               </td>
-               <td>$Lang::tr{'openvpn default'}: <span class="base">SHA1 (160 $Lang::tr{'bit'})</span></td>
-    </tr>
-</table>
-
-<table width='100%'>
-    <tr>
-       <td width='20%'></td> <td width='15%'> </td><td width='15%'> </td><td width='15%'></td><td width='35%'></td>
-    </tr>
-
-    <tr>
-       <td class='base'>HMAC tls-auth</td>
-       <td><input type='checkbox' name='TLSAUTH' $checked{'TLSAUTH'}{'on'} /></td>
-    </tr>
-    </table><hr>
 END
 
 if ( -e "/var/run/openvpn.pid"){
@@ -3034,8 +3112,8 @@ END
                    $users[$uid]{'Proto'} = $proto;
 
                    # get country code for "RealAddress"...
-                   my $ccode = &GeoIP::lookup((split ':', $users[$uid]{'RealAddress'})[0]);
-                   my $flag_icon = &GeoIP::get_flag_icon($ccode);
+                   my $ccode = &Location::Functions::lookup_country_code((split ':', $users[$uid]{'RealAddress'})[0]);
+                   my $flag_icon = &Location::Functions::get_flag_icon($ccode);
                    $users[$uid]{'Country'} = "<a href='country.cgi#$ccode'><img src='$flag_icon' border='0' align='absmiddle' alt='$ccode' title='$ccode' /></a>";
                    $uid++;
                }    
@@ -3098,7 +3176,12 @@ END
     if ( -f "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem") {
        print "Content-Disposition: filename=" . $confighash{$cgiparams{'KEY'}}[1] . "cert.pem\r\n";
        print "Content-Type: application/octet-stream\r\n\r\n";
-       print `/bin/cat ${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem`;
+
+       open(FILE, "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]cert.pem");
+       my @tmp = <FILE>;
+       close(FILE);
+
+       print "@tmp";
        exit (0);
     }
 
@@ -3219,9 +3302,8 @@ END
 
        &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);    
 
-# Check if a file is uploaded
-
-       if (ref ($cgiparams{'FH'}) ne 'Fh') {
+       # Check if a file is uploaded
+       unless (ref ($cgiparams{'FH'})) {
                $errormessage = $Lang::tr{'there was no file upload'};
                goto N2N_ERROR;
     }
@@ -3337,7 +3419,6 @@ my $complzoactive;
 my $mssfixactive;
 my $authactive;
 my $n2nfragment;
-my @n2nmtudisc = split(/ /, (grep { /^mtu-disc/ } @firen2nconf)[0]);
 my @n2nproto2 = split(/ /, (grep { /^proto/ } @firen2nconf)[0]);
 my @n2nproto = split(/-/, $n2nproto2[1]);
 my @n2nport = split(/ /, (grep { /^port/ } @firen2nconf)[0]);
@@ -3373,7 +3454,6 @@ $n2nremsub[2] =~ s/\n|\r//g;
 $n2nlocalsub[2] =~ s/\n|\r//g;
 $n2nfragment[1] =~ s/\n|\r//g;
 $n2nmgmt[2] =~ s/\n|\r//g;
-$n2nmtudisc[1] =~ s/\n|\r//g;
 $n2ncipher[1] =~ s/\n|\r//g;
 $n2nauth[1] =~ s/\n|\r//g;
 chomp ($complzoactive);
@@ -3450,7 +3530,6 @@ foreach my $dkey (keys %confighash) {
        $confighash{$key}[29] = $n2nport[1];
        $confighash{$key}[30] = $complzoactive;
        $confighash{$key}[31] = $n2ntunmtu[1];
-       $confighash{$key}[38] = $n2nmtudisc[1];
        $confighash{$key}[39] = $n2nauth[1];
        $confighash{$key}[40] = $n2ncipher[1];
        $confighash{$key}[41] = 'disabled';
@@ -3490,9 +3569,8 @@ foreach my $dkey (keys %confighash) {
                <tr><td class='boldbase' nowrap='nowrap'>MSSFIX:</td><td><b>$confighash{$key}[23]</b></td></tr>
                <tr><td class='boldbase' nowrap='nowrap'>Fragment:</td><td><b>$confighash{$key}[24]</b></td></tr>
                <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}</td><td><b>$confighash{$key}[31]</b></td></tr>
-               <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn mtu-disc'}</td><td><b>$confighash{$key}[38]</b></td></tr>
                <tr><td class='boldbase' nowrap='nowrap'>Management Port </td><td><b>$confighash{$key}[22]</b></td></tr>
-               <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn hmac'}:</td><td><b>$confighash{$key}[39]</b></td></tr>
+               <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'ovpn tls auth'}:</td><td><b>$confighash{$key}[39]</b></td></tr>
                <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'cipher'}</td><td><b>$confighash{$key}[40]</b></td></tr>
                <tr><td>&nbsp;</td><td>&nbsp;</td></tr> 
     </table>
@@ -3765,41 +3843,42 @@ if ($cgiparams{'TYPE'} eq 'host') {
 #CCD End
 
        
- if ($cgiparams{'TYPE'} !~ /^(host|net)$/) {
-           $errormessage = $Lang::tr{'connection type is invalid'};
-           if ($cgiparams{'TYPE'} eq 'net') {
-      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{'TYPE'} !~ /^(host|net)$/) {
+               $errormessage = $Lang::tr{'connection type is invalid'};
+               if ($cgiparams{'TYPE'} eq 'net') {
+                       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;
+               }
+               goto VPNCONF_ERROR;
        }
 
-
        if ($cgiparams{'NAME'} !~ /^[a-zA-Z0-9]+$/) {
-           $errormessage = $Lang::tr{'name must only contain characters'};
-      if ($cgiparams{'TYPE'} eq 'net') {
-      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;
-  }
+               $errormessage = $Lang::tr{'name must only contain characters'};
+               if ($cgiparams{'TYPE'} eq 'net') {
+                       goto VPNCONF_ERROR;
+               }
+               goto VPNCONF_ERROR;
+       }
 
        if ($cgiparams{'NAME'} =~ /^(host|01|block|private|clear|packetdefault)$/) {
-           $errormessage = $Lang::tr{'name is invalid'};
-           if ($cgiparams{'TYPE'} eq 'net') {
-      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;
+               $errormessage = $Lang::tr{'name is invalid'};
+               if ($cgiparams{'TYPE'} eq 'net') {
+                       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;
+               }
+               goto VPNCONF_ERROR;
        }
 
        if (length($cgiparams{'NAME'}) >60) {
-           $errormessage = $Lang::tr{'name too long'};
-           if ($cgiparams{'TYPE'} eq 'net') {
-      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;
+               $errormessage = $Lang::tr{'name too long'};
+               if ($cgiparams{'TYPE'} eq 'net') {
+                       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;
+               }
+               goto VPNCONF_ERROR;
        }
 
 ###
@@ -3980,6 +4059,16 @@ if ($cgiparams{'TYPE'} eq 'net') {
                goto VPNCONF_ERROR;
        }
 
+       # Check for N2N that OpenSSL maximum of valid days will not be exceeded
+       if ($cgiparams{'TYPE'} eq 'net') {
+               if ($cgiparams{'DAYS_VALID'} >= '999999') {
+                       $errormessage = $Lang::tr{'invalid input for valid till days'};
+                       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{'ENABLED'} !~ /^(on|off)$/) {
            $errormessage = $Lang::tr{'invalid input'};
            goto VPNCONF_ERROR;
@@ -4004,7 +4093,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
                $errormessage = $Lang::tr{'cant change certificates'};
                goto VPNCONF_ERROR;
            }
-           if (ref ($cgiparams{'FH'}) ne 'Fh') {
+           unless (ref ($cgiparams{'FH'})) {
                $errormessage = $Lang::tr{'there was no file upload'};
                goto VPNCONF_ERROR;
            }
@@ -4018,6 +4107,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
 
            # Sign the certificate request and move it
            # Sign the host certificate request
+           # The system call is safe, because all arguments are passed as an array.
            system('/usr/bin/openssl', 'ca', '-days', "$cgiparams{'DAYS_VALID'}",
                '-batch', '-notext',
                '-in', $filename,
@@ -4034,11 +4124,19 @@ if ($cgiparams{'TYPE'} eq 'net') {
                &deletebackupcert();
            }
 
-           my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`;
-           $temp =~ /Subject:.*CN=(.*)[\n]/;
-           $temp = $1;
-           $temp =~ s+/Email+, E+;
-           $temp =~ s/ ST=/ S=/;
+           my @temp = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
+           my $temp;
+
+           foreach my $line (@temp) {
+               if ($line =~ /Subject:.*CN\s?=\s?(.*)[\n]/) {
+                       $temp = $1;
+                       $temp =~ s+/Email+, E+;
+                       $temp =~ s/ ST=/ S=/;
+
+                       last;
+               }
+           }
+               
            $cgiparams{'CERT_NAME'} = $temp;
            $cgiparams{'CERT_NAME'} =~ s/,//g;
            $cgiparams{'CERT_NAME'} =~ s/\'//g;
@@ -4051,7 +4149,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
                $errormessage = $Lang::tr{'cant change certificates'};
                goto VPNCONF_ERROR;
            }
-           if (ref ($cgiparams{'FH'}) ne 'Fh') {
+           unless (ref ($cgiparams{'FH'})) {
                $errormessage = $Lang::tr{'there was no file upload'};
                goto VPNCONF_ERROR;
            }
@@ -4064,13 +4162,13 @@ if ($cgiparams{'TYPE'} eq 'net') {
 
            # Verify the certificate has a valid CA and move it
            my $validca = 0;
-           my $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/cacert.pem $filename`;
-           if ($test =~ /: OK/) {
+           my @test = &General::system_output("/usr/bin/openssl", "verify", "-CAfile", "${General::swroot}/ovpn/ca/cacert.pem", "$filename");
+           if (grep(/: OK/, @test)) {
                $validca = 1;
            } else {
                foreach my $key (keys %cahash) {
-                   $test = `/usr/bin/openssl verify -CAfile ${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem $filename`;
-                   if ($test =~ /: OK/) {
+                   @test = &General::system_output("/usr/bin/openssl", "verify", "-CAfile", "${General::swroot}/ovpn/ca/$cahash{$key}[0]cert.pem", "$filename");
+                   if (grep(/: OK/, @test)) {
                        $validca = 1;
                    }
                }
@@ -4088,11 +4186,19 @@ if ($cgiparams{'TYPE'} eq 'net') {
                }
            }
 
-           my $temp = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem`;
-           $temp =~ /Subject:.*CN=(.*)[\n]/;
-           $temp = $1;
-           $temp =~ s+/Email+, E+;
-           $temp =~ s/ ST=/ S=/;
+           my @temp = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem");
+           my $temp;
+
+           foreach my $line (@temp) {
+               if ($line =~ /Subject:.*CN\s?=\s?(.*)[\n]/) {
+                       $temp = $1;
+                       $temp =~ s+/Email+, E+;
+                       $temp =~ s/ ST=/ S=/;
+
+                       last;
+               }
+           }
+
            $cgiparams{'CERT_NAME'} = $temp;
            $cgiparams{'CERT_NAME'} =~ s/,//g;
            $cgiparams{'CERT_NAME'} =~ s/\'//g;
@@ -4157,11 +4263,29 @@ 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]+$/) {
+           if ($cgiparams{'DAYS_VALID'} eq '' && $cgiparams{'DAYS_VALID'} !~ /^[0-9]+$/) {
                $errormessage = $Lang::tr{'invalid input for valid till days'};
                goto VPNCONF_ERROR;
            }
 
+           # Check for RW that OpenSSL maximum of valid days will not be exceeded
+           if ($cgiparams{'TYPE'} eq 'host') {
+               if ($cgiparams{'DAYS_VALID'} >= '999999') {
+                       $errormessage = $Lang::tr{'invalid input for valid till days'};
+                       goto VPNCONF_ERROR;
+               }
+           }
+
+               # Check for RW if client name is already set
+               if ($cgiparams{'TYPE'} eq 'host') {
+                       foreach my $key (keys %confighash) {
+                               if ($confighash{$key}[1] eq $cgiparams{'NAME'}) {
+                                       $errormessage = $Lang::tr{'a connection with this name already exists'};
+                                       goto VPNCONF_ERROR;
+                               }
+                       }
+               }
+
            # Replace empty strings with a .
            (my $ou = $cgiparams{'CERT_OU'}) =~ s/^\s*$/\./;
            (my $city = $cgiparams{'CERT_CITY'}) =~ s/^\s*$/\./;
@@ -4201,6 +4325,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
            }
        
            # Sign the host certificate request
+           # The system call is safe, because all arguments are passed as an array.
            system('/usr/bin/openssl', 'ca', '-days', "$cgiparams{'DAYS_VALID'}",
                '-batch', '-notext',
                '-in',  "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem",
@@ -4219,6 +4344,7 @@ if ($cgiparams{'TYPE'} eq 'net') {
            }
 
            # Create the pkcs12 file
+           # The system call is safe, because all arguments are passed as an array.
            system('/usr/bin/openssl', 'pkcs12', '-export', 
                '-inkey', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem",
                '-in', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}cert.pem",
@@ -4384,21 +4510,24 @@ if ($cgiparams{'TYPE'} eq 'net') {
        
        if ($cgiparams{'TYPE'} eq 'net') {
        
-       if (-e "/var/run/$confighash{$key}[1]n2n.pid") {
-  system('/usr/local/bin/openvpnctrl', '-kn2n', $confighash{$cgiparams{'KEY'}}[1]);
+               if (-e "/var/run/$confighash{$key}[1]n2n.pid") {
+                       &General::system("/usr/local/bin/openvpnctrl", "-kn2n", "$confighash{$cgiparams{'KEY'}}[1]");
        
-  &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
-       my $key = $cgiparams{'KEY'};
-       if (! $key) {
-           $key = &General::findhasharraykey (\%confighash);
-           foreach my $i (0 .. 31) { $confighash{$key}[$i] = "";}
-           }
-  $confighash{$key}[0] = 'on';
-  &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
+                       &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
+                       my $key = $cgiparams{'KEY'};
+                       if (! $key) {
+                           $key = &General::findhasharraykey (\%confighash);
+                           foreach my $i (0 .. 31) {
+                                   $confighash{$key}[$i] = "";
+                           }
+                       }
+
+                       $confighash{$key}[0] = 'on';
+                       &General::writehasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
   
-  system('/usr/local/bin/openvpnctrl', '-sn2n', $confighash{$cgiparams{'KEY'}}[1]);
-        }          
-  }
+                       &General::system("/usr/local/bin/openvpnctrl", "-sn2n", "$confighash{$cgiparams{'KEY'}}[1]");
+               }
+       }
 
 ###
 # m.a.d n2n end
@@ -4433,7 +4562,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'};
+       $cgiparams{'DAYS_VALID'}        = $vpnsettings{'DAYS_VALID'} = '730';
     }
 
     VPNCONF_ERROR:
@@ -4504,12 +4633,10 @@ if ($cgiparams{'TYPE'} eq 'net') {
     $selected{'DAUTH'}{'SHA384'} = '';
     $selected{'DAUTH'}{'SHA256'} = '';
     $selected{'DAUTH'}{'SHA1'} = '';
-    # If no hash algorythm has been choosen yet, select
-    # the old default value (SHA1) for compatiblity reasons.
-    if ($cgiparams{'DAUTH'} eq '') {
-       $cgiparams{'DAUTH'} = 'SHA1';
-    }
     $selected{'DAUTH'}{$cgiparams{'DAUTH'}} = 'SELECTED';
+    $checked{'TLSAUTH'}{'off'} = '';
+    $checked{'TLSAUTH'}{'on'} = '';
+    $checked{'TLSAUTH'}{$cgiparams{'TLSAUTH'}} = 'CHECKED';
 
     if (1) {
        &Header::showhttpheaders();
@@ -4813,7 +4940,7 @@ END
 if ($cgiparams{'TYPE'} eq 'host') {
        print <<END;
        </select></td></tr>
-               <td>&nbsp;</td><td class='base'>$Lang::tr{'valid till'} (days):</td>
+               <td>&nbsp;</td><td class='base'>$Lang::tr{'valid till'} (days):&nbsp;<img src='/blob.gif' alt='*' /</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>
@@ -4828,7 +4955,7 @@ END
 }else{
        print <<END;
        </select></td></tr>
-               <td>&nbsp;</td><td class='base'>$Lang::tr{'valid till'} (days):</td>
+               <td>&nbsp;</td><td class='base'>$Lang::tr{'valid till'} (days):&nbsp;<img src='/blob.gif' alt='*' /</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>
@@ -5017,7 +5144,9 @@ END
     &General::readhasharray("${General::swroot}/ovpn/caconfig", \%cahash);
     &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash);
 
-    my @status = `/bin/cat /var/run/ovpnserver.log`;
+    open(FILE, "/var/run/ovpnserver.log");
+    my @status = <FILE>;
+    close(FILE);
 
     if ($cgiparams{'VPN_IP'} eq '' && -e "${General::swroot}/red/active") {
                if (open(IPADDR, "${General::swroot}/red/local-ipaddress")) {
@@ -5045,8 +5174,20 @@ END
                $cgiparams{'MSSFIX'} = 'off';
     }
        if ($cgiparams{'DAUTH'} eq '') {
-               $cgiparams{'DAUTH'} = 'SHA512';
-    }
+               if (-z "${General::swroot}/ovpn/ovpnconfig") {
+                       $cgiparams{'DAUTH'} = 'SHA512';
+               }
+               foreach my $key (keys %confighash) {
+                       if ($confighash{$key}[3] ne 'host') {
+                               $cgiparams{'DAUTH'} = 'SHA512';
+                       } else {
+                               $cgiparams{'DAUTH'} = 'SHA1';
+                       }
+               }
+       }
+       if ($cgiparams{'TLSAUTH'} eq '') {
+               $cgiparams{'TLSAUTH'} = 'off';
+       }
     if ($cgiparams{'DOVPN_SUBNET'} eq '') {
                $cgiparams{'DOVPN_SUBNET'} = '10.' . int(rand(256)) . '.' . int(rand(256)) . '.0/255.255.255.0';
     }
@@ -5089,6 +5230,10 @@ END
     $selected{'DAUTH'}{'SHA1'} = '';
     $selected{'DAUTH'}{$cgiparams{'DAUTH'}} = 'SELECTED';
 
+    $checked{'TLSAUTH'}{'off'} = '';
+    $checked{'TLSAUTH'}{'on'} = '';
+    $checked{'TLSAUTH'}{$cgiparams{'TLSAUTH'}} = 'CHECKED';
+
     $checked{'DCOMPLZO'}{'off'} = '';
     $checked{'DCOMPLZO'}{'on'} = '';
     $checked{'DCOMPLZO'}{$cgiparams{'DCOMPLZO'}} = 'CHECKED';
@@ -5109,6 +5254,20 @@ END
        &Header::closebox();
     }
 
+       if ($cryptoerror) {
+               &Header::openbox('100%', 'LEFT', $Lang::tr{'crypto error'});
+               print "<class name='base'>$cryptoerror";
+               print "&nbsp;</class>";
+               &Header::closebox();
+       }
+
+       if ($cryptowarning) {
+               &Header::openbox('100%', 'LEFT', $Lang::tr{'crypto warning'});
+               print "<class name='base'>$cryptowarning";
+               print "&nbsp;</class>";
+               &Header::closebox();
+       }
+
        if ($warnmessage) {
                &Header::openbox('100%', 'LEFT', $Lang::tr{'warning messages'});
                print "$warnmessage<br>";
@@ -5149,8 +5308,16 @@ END
     if (&haveOrangeNet()) {    
        print "<tr><td class='boldbase'>$Lang::tr{'ovpn on orange'}</td>";
        print "<td><input type='checkbox' name='ENABLED_ORANGE' $checked{'ENABLED_ORANGE'}{'on'} /></td>";
-    }  
-    print <<END;
+    }
+
+       print <<END;
+
+       <tr><td colspan='4'><br></td></tr>
+       <tr>
+               <td class'base'><b>$Lang::tr{'net config'}:</b></td>
+       </tr>
+    <tr><td colspan='1'><br></td></tr>
+
     <tr><td class='base' nowrap='nowrap' colspan='2'>$Lang::tr{'local vpn hostname/ip'}:<br /><input type='text' name='VPN_IP' value='$cgiparams{'VPN_IP'}' size='30' /></td>
        <td class='boldbase' nowrap='nowrap' colspan='2'>$Lang::tr{'ovpn subnet'}<br /><input type='TEXT' name='DOVPN_SUBNET' value='$cgiparams{'DOVPN_SUBNET'}' size='30' /></td></tr>
     <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'protocol'}</td>
@@ -5160,6 +5327,24 @@ END
         <td><input type='TEXT' name='DDEST_PORT' value='$cgiparams{'DDEST_PORT'}' size='5' /></td></tr>
     <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}&nbsp;</td>
         <td> <input type='TEXT' name='DMTU' VALUE='$cgiparams{'DMTU'}' size='5' /></td>
+    </tr>
+
+       <tr><td colspan='4'><br></td></tr>
+       <tr>
+               <td class'base'><b>$Lang::tr{'ovpn crypt options'}:</b></td>
+       </tr>
+       <tr><td colspan='1'><br></td></tr>
+
+       <tr>
+               <td class='base'>$Lang::tr{'ovpn ha'}</td>
+               <td><select name='DAUTH'>
+                               <option value='whirlpool'               $selected{'DAUTH'}{'whirlpool'}>Whirlpool (512 $Lang::tr{'bit'})</option>
+                               <option value='SHA512'                  $selected{'DAUTH'}{'SHA512'}>SHA2 (512 $Lang::tr{'bit'})</option>
+                               <option value='SHA384'                  $selected{'DAUTH'}{'SHA384'}>SHA2 (384 $Lang::tr{'bit'})</option>
+                               <option value='SHA256'                  $selected{'DAUTH'}{'SHA256'}>SHA2 (256 $Lang::tr{'bit'})</option>
+                               <option value='SHA1'                    $selected{'DAUTH'}{'SHA1'}>SHA1 (160 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
+                       </select>
+               </td>
 
                <td class='boldbase' nowrap='nowrap'>$Lang::tr{'cipher'}</td>
                <td><select name='DCIPHER'>
@@ -5180,9 +5365,14 @@ END
                                <option value='CAST5-CBC' $selected{'DCIPHER'}{'CAST5-CBC'}>CAST5-CBC (128 $Lang::tr{'bit'}, $Lang::tr{'vpn weak'})</option>
                        </select>
                </td>
-    <tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'comp-lzo'}</td>
-        <td><input type='checkbox' name='DCOMPLZO' $checked{'DCOMPLZO'}{'on'} /></td>
        </tr>
+
+    <tr><td colspan='4'><br></td></tr>
+       <tr>
+               <td class='base'>$Lang::tr{'ovpn tls auth'}</td>
+               <td><input type='checkbox' name='TLSAUTH' $checked{'TLSAUTH'}{'on'} /></td>
+       </tr>
+
     <tr><td colspan='4'><br><br></td></tr>
 END
 ;                                 
@@ -5268,9 +5458,17 @@ END
        #} else {
            #print "<td align='left'>&nbsp;</td>";
        #}
-       my $cavalid = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem`;
-       $cavalid    =~ /Not After : (.*)[\n]/;
-       $cavalid    = $1;
+       my @cavalid = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem");
+       my $cavalid;
+
+       foreach my $line (@cavalid) {
+               if ($line =~ /Not After : (.*)[\n]/) {
+                       $cavalid    = $1;
+
+                       last;
+               }
+       }
+
        print "<td align='center' $col>$confighash{$key}[25]</td>";
        $col1="bgcolor='${Header::colourred}'";
        my $active = "<b><font color='#FFFFFF'>$Lang::tr{'capsclosed'}</font></b>";
@@ -5481,11 +5679,19 @@ END
     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]/;
-               $casubject    = $1;
-               $casubject    =~ s+/Email+, E+;
-               $casubject    =~ s/ ST=/ S=/;
+               my @casubject = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/ca/cacert.pem");
+               my $casubject;
+
+               foreach my $line (@casubject) {
+                       if ($line =~ /Subject: (.*)[\n]/) {
+                               $casubject    = $1;
+                               $casubject    =~ s+/Email+, E+;
+                               $casubject    =~ s/ ST=/ S=/;
+
+                               last;
+                       }
+               }
+
                print <<END;
                <tr>
                        <td class='base' $col1>$Lang::tr{'root certificate'}</td>
@@ -5515,11 +5721,18 @@ END
     }
 
     if (-f "${General::swroot}/ovpn/certs/servercert.pem") {
-               my $hostsubject = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`;
-               $hostsubject    =~ /Subject: (.*)[\n]/;
-               $hostsubject    = $1;
-               $hostsubject    =~ s+/Email+, E+;
-               $hostsubject    =~ s/ ST=/ S=/;
+               my @hostsubject = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
+               my $hostsubject;
+
+               foreach my $line (@hostsubject) {
+                       if ($line =~ /Subject: (.*)[\n]/) {
+                               $hostsubject    = $1;
+                               $hostsubject    =~ s+/Email+, E+;
+                               $hostsubject    =~ s/ ST=/ S=/;
+
+                               last;
+                       }
+               }
 
                print <<END;
                <tr>
@@ -5551,10 +5764,16 @@ 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;
+               my @dhsubject = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "${General::swroot}/ovpn/ca/dh1024.pem");
+               my $dhsubject;
 
+               foreach my $line (@dhsubject) {
+                       if ($line =~ /    (.*)[\n]/) {
+                               $dhsubject = $1;
+
+                               last;
+                       }
+               }
 
        print <<END;
                <tr>
@@ -5584,9 +5803,19 @@ 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;
+               open(FILE, "${General::swroot}/ovpn/certs/ta.key");
+               my @tasubject = <FILE>;
+               close(FILE);
+
+               my $tasubject;
+               foreach my $line (@tasubject) {
+                       if($line =~ /# (.*)[\n]/) {
+                               $tasubject    = $1;
+
+                               last;
+                       }
+               }
+
                print <<END;
 
                <tr>