###############################################################################
# #
# IPFire.org - A linux based firewall #
-# Copyright (C) 2007-2014 IPFire Team <info@ipfire.org> #
+# Copyright (C) 2007-2023 IPFire Team <info@ipfire.org> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
-###
-# Based on IPFireCore 77
-###
+
use CGI;
use CGI qw/:standard/;
use Imager::QRCode;
use MIME::Base32;
use MIME::Base64;
+use URI::Encode qw(uri_encode uri_decode);;
use Net::DNS;
use Net::Ping;
use Net::Telnet;
use strict;
use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
use Sort::Naturally;
+use Date::Parse;
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/lang.pl";
require "${General::swroot}/header.pl";
my $col="";
my $local_serverconf = "${General::swroot}/ovpn/scripts/server.conf.local";
my $local_clientconf = "${General::swroot}/ovpn/scripts/client.conf.local";
+my $dhparameter = "/etc/ssl/ffdhe4096.pem";
&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
$cgiparams{'ENABLED'} = 'off';
$cgiparams{'ONLY_PROPOSED'} = 'off';
$cgiparams{'ACTION'} = '';
$cgiparams{'CA_NAME'} = '';
-$cgiparams{'DH_NAME'} = 'dh1024.pem';
-$cgiparams{'DHLENGHT'} = '';
$cgiparams{'DHCP_DOMAIN'} = '';
$cgiparams{'DHCP_DNS'} = '';
$cgiparams{'DHCP_WINS'} = '';
###
### Useful functions
###
+sub iscertlegacy
+{
+ my $file=$_[0];
+ my @certinfo = &General::system_output("/usr/bin/openssl", "pkcs12", "-info", "-nodes",
+ "-in", "$file.p12", "-noout", "-passin", "pass:''");
+ if (index ($certinfo[0], "MAC: sha1") != -1) {
+ return 1;
+ }
+ return 0;
+}
+
sub haveOrangeNet
{
if ($netsettings{'CONFIG_TYPE'} == 2) {return 1;}
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");
print CONF "ca ${General::swroot}/ovpn/ca/cacert.pem\n";
print CONF "cert ${General::swroot}/ovpn/certs/servercert.pem\n";
print CONF "key ${General::swroot}/ovpn/certs/serverkey.pem\n";
- print CONF "dh ${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}\n";
+ print CONF "dh $dhparameter\n";
my @tempovpnsubnet = split("\/",$sovpnsettings{'DOVPN_SUBNET'});
print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n";
#print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\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 CONF "\n";
+
+ print CONF "# Enable Management Socket\n";
+ print CONF "management /var/run/openvpn.sock unix\n";
+ print CONF "management-client-auth\n";
# Print server.conf.local if entries exist to server.conf
if ( !-z $local_serverconf && $sovpnsettings{'ADDITIONAL_CONFIGS'} eq 'on') {
return
}
- if(!&General::validhostname($ccdname))
+ if(!&General::validccdname($ccdname))
{
$errormessage=$Lang::tr{'ccd err invalidname'};
return;
my %ccdhash=();
# Check if the new name is valid.
- if(!&General::validhostname($newname)) {
+ if(!&General::validccdname($newname)) {
$errormessage=$Lang::tr{'ccd err invalidname'};
return;
}
print SERVERCONF "ca ${General::swroot}/ovpn/ca/cacert.pem\n";
print SERVERCONF "cert ${General::swroot}/ovpn/certs/servercert.pem\n";
print SERVERCONF "key ${General::swroot}/ovpn/certs/serverkey.pem\n";
- print SERVERCONF "dh ${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}\n";
+ print SERVERCONF "dh $dhparameter\n";
print SERVERCONF "# Cipher\n";
print SERVERCONF "cipher $cgiparams{'DCIPHER'}\n";
print CLIENTCONF "# Activate Management Interface and Port\n";
if ($cgiparams{'OVPN_MGMT'} eq '') {print CLIENTCONF "management localhost $cgiparams{'DEST_PORT'}\n"}
else {print CLIENTCONF "management localhost $cgiparams{'OVPN_MGMT'}\n"};
+ if (&iscertlegacy("${General::swroot}/ovpn/certs/$cgiparams{'NAME'}")) {
+ print CLIENTCONF "providers legacy default\n";
+ }
close(CLIENTCONF);
}
exit (0);
###
-### Generate DH key step 2
-###
-} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate dh key'} && $cgiparams{'AREUSURE'} eq 'yes') {
- # Delete if old key exists
- if (-f "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}") {
- unlink "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}";
- }
- # 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'}: $?";
- unlink ("${General::swroot}/ovpn/ca/dh1024.pem");
- }
-
-###
-### Generate DH key step 1
-###
-} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'generate dh key'}) {
- &Header::showhttpheaders();
- &Header::openpage($Lang::tr{'ovpn'}, 1, '');
- &Header::openbigbox('100%', 'LEFT', '', '');
- &Header::openbox('100%', 'LEFT', "$Lang::tr{'gen dh'}:");
- print <<END;
- <table width='100%'>
- <tr>
- <td width='20%'> </td> <td width='15%'></td> <td width='65%'></td>
- </tr>
- <tr>
- <td class='base'>$Lang::tr{'ovpn dh'}:</td>
- <td align='center'>
- <form method='post'><input type='hidden' name='AREUSURE' value='yes' />
- <input type='hidden' name='KEY' value='$cgiparams{'KEY'}' />
- <select name='DHLENGHT'>
- <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>
- </select>
- </td>
- </tr>
- <tr><td colspan='4'><br></td></tr>
- </table>
- <table width='100%'>
- <tr>
- <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}: </font></b>$Lang::tr{'dh key warn'}
- </tr>
- <tr>
- <td class='base'>$Lang::tr{'dh key warn1'}</td>
- </tr>
- <tr><td colspan='2'><br></td></tr>
- <tr>
- <td align='center'><input type='submit' name='ACTION' value='$Lang::tr{'generate dh key'}' /></td>
- </form>
- </tr>
- </table>
-
-END
- ;
- &Header::closebox();
- print "<div align='center'><a href='/cgi-bin/ovpnmain.cgi'>$Lang::tr{'back'}</a></div>";
- &Header::closebigbox();
- &Header::closepage();
- exit (0);
-
-###
-### Upload DH key
-###
-} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload dh key'}) {
- unless (ref ($cgiparams{'FH'})) {
- $errormessage = $Lang::tr{'there was no file upload'};
- goto UPLOADCA_ERROR;
- }
- # Move uploaded dh key to a temporary file
- (my $fh, my $filename) = tempfile( );
- if (copy ($cgiparams{'FH'}, $fh) != 1) {
- $errormessage = $!;
- goto UPLOADCA_ERROR;
- }
- 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;
- } else {
- # Delete if old key exists
- if (-f "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}") {
- unlink "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}";
- }
-
- unless(move($filename, "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}")) {
- $errormessage = "$Lang::tr{'dh key move failed'}: $!";
- unlink ($filename);
- goto UPLOADCA_ERROR;
- }
- }
-###
### Upload CA Certificate
###
} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'upload ca certificate'}) {
print "Content-Disposition: filename=$cahash{$cgiparams{'KEY'}}[0]cert.pem\r\n\r\n";
my @tmp = &General::system_output("/usr/bin/openssl", "x509", "-in", "${General::swroot}/ovpn/ca/$cahash{$cgiparams{'KEY'}}[0]cert.pem");
- print "@tmp";
+ print @tmp;
exit(0);
} else {
print "Content-Disposition: filename=cacert.pem\r\n\r\n";
my @tmp = &General::system_output("/usr/bin/openssl", "x509", "-in", "${General::swroot}/ovpn/ca/cacert.pem");
- print "@tmp";
+ print @tmp;
exit(0);
}
print "Content-Disposition: filename=servercert.pem\r\n\r\n";
my @tmp = &General::system_output("/usr/bin/openssl", "x509", "-in", "${General::swroot}/ovpn/certs/servercert.pem");
- print "@tmp";
+ print @tmp;
exit(0);
}
my @tmp = <FILE>;
close(FILE);
- print "@tmp";
+ print @tmp;
exit(0);
}
}
} else { # child
unless (exec ('/usr/bin/openssl', 'req', '-nodes',
- '-newkey', 'rsa:2048',
+ '-newkey', 'rsa:4096',
'-keyout', "${General::swroot}/ovpn/certs/serverkey.pem",
'-out', "${General::swroot}/ovpn/certs/serverreq.pem",
'-extensions', 'server',
&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'}: $?";
- unlink ("${General::swroot}/ovpn/certs/serverkey.pem");
- unlink ("${General::swroot}/ovpn/certs/servercert.pem");
- unlink ("${General::swroot}/ovpn/ca/cacert.pem");
- unlink ("${General::swroot}/ovpn/crls/cacrl.pem");
- unlink ("${General::swroot}/ovpn/ca/dh1024.pem");
- &cleanssldatabase();
- goto ROOTCERT_ERROR;
-# } else {
-# &cleanssldatabase();
- }
goto ROOTCERT_SUCCESS;
}
ROOTCERT_ERROR:
}
print <<END;
</select></td>
- <tr><td class='base'>$Lang::tr{'ovpn dh'}:</td>
- <td class='base'><select name='DHLENGHT'>
- <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>
- </select>
- </td>
- </tr>
<tr><td> </td>
<td><input type='submit' name='ACTION' value='$Lang::tr{'generate root/host certificates'}' /></td>
<tr><td class='base' colspan='4' align='left'>
<img src='/blob.gif' valign='top' alt='*' /> $Lang::tr{'required field'}</td></tr>
<tr><td colspan='2'><br></td></tr>
- <table width='100%'>
- <tr>
- <b><font color='${Header::colourred}'>$Lang::tr{'capswarning'}: </font></b>$Lang::tr{'ovpn generating the root and host certificates'}
- <td class='base'>$Lang::tr{'dh key warn'}</td>
- </tr>
- <tr>
- <td class='base'>$Lang::tr{'dh key warn1'}</td>
- </tr>
- <tr><td colspan='2'><br></td></tr>
- <tr>
</table>
<table width='100%'>
if ($confighash{$cgiparams{'KEY'}}[22] eq '') {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[29]\n"}
else {print CLIENTCONF "management localhost $confighash{$cgiparams{'KEY'}}[22]\n"};
print CLIENTCONF "# remsub $confighash{$cgiparams{'KEY'}}[11]\n";
+ if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
+ print CLIENTCONF "providers legacy default\n";
+ }
+
close(CLIENTCONF);
# 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 ($?) {
- die "openssl error: $?";
+ if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
+ system('/usr/bin/openssl', 'pkcs12', '-legacy', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
+ '-clcerts', '-nokeys', '-nodes', '-out', "$file_crt" , '-passin', 'pass:');
+ if ($?) {
+ die "openssl error: $?";
+ }
+ } else {
+ system('/usr/bin/openssl', 'pkcs12', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
+ '-clcerts', '-nokeys', '-nodes', '-out', "$file_crt" , '-passin', 'pass:');
+ if ($?) {
+ die "openssl error: $?";
+ }
}
$zip->addFile("$file_crt", "$confighash{$cgiparams{'KEY'}}[1].pem") or die;
# 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 ($?) {
- die "openssl error: $?";
+ if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
+ system('/usr/bin/openssl', 'pkcs12', '-legacy', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
+ '-nocerts', '-nodes', '-out', "$file_key", '-passin', 'pass:');
+ if ($?) {
+ die "openssl error: $?";
+ }
+ } else {
+ system('/usr/bin/openssl', 'pkcs12', '-in', "${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1].p12",
+ '-nocerts', '-nodes', '-out', "$file_key", '-passin', 'pass:');
+ if ($?) {
+ die "openssl error: $?";
+ }
}
$zip->addFile("$file_key", "$confighash{$cgiparams{'KEY'}}[1].key") or die;
if ($vpnsettings{FRAGMENT} ne '' && $vpnsettings{DPROTOCOL} ne 'tcp' ) {
print CLIENTCONF "fragment $vpnsettings{'FRAGMENT'}\r\n";
}
- if ($confighash{$cgiparams{'KEY'}}[43] eq 'on') {
- print CLIENTCONF "auth-nocache\r\n";
- print CLIENTCONF "auth-user-pass credentials\r\n";
- print CLIENTCONF "static-challenge \"One Time Password (OTP): \" 1\r\n";
- open(CLIENTCREDS, ">$tempdir/credentials") or die "Unable to open tempfile: $!";
- print CLIENTCREDS "user\r\n";
- print CLIENTCREDS "password";
- close(CLIENTCREDS);
- $zip->addFile( "$tempdir/credentials", "credentials") or die "Can't add file credentials\n";
- }
+ # Disable storing any credentials in memory
+ print CLIENTCONF "auth-nocache\r\n";
+
+ # Set a fake user name for authentication
+ print CLIENTCONF "auth-token-user USER\r\n";
+ print CLIENTCONF "auth-token TOTP\r\n";
+
+ # If the server is asking for TOTP this needs to happen interactively
+ print CLIENTCONF "auth-retry interact\r\n";
+
+ # Add provider line if certificate is legacy type
+ if (&iscertlegacy("${General::swroot}/ovpn/certs/$confighash{$cgiparams{'KEY'}}[1]")) {
+ print CLIENTCONF "providers legacy default\r\n";
+ }
if ($include_certs) {
print CLIENTCONF "\r\n";
my @tmp = <FILE>;
close(FILE);
- print "@tmp";
+ print @tmp;
exit (0);
###
lightcolor => Imager::Color->new(255, 255, 255),
darkcolor => Imager::Color->new(0, 0, 0),
);
- my $cn = $confighash{$cgiparams{'KEY'}}[2];
- my $secret = encode_base32($confighash{$cgiparams{'KEY'}}[44]);
- my $issuer = "$mainsettings{'HOSTNAME'}.$mainsettings{'DOMAINNAME'}";
+ my $cn = uri_encode($confighash{$cgiparams{'KEY'}}[2]);
+ my $secret = encode_base32(pack('H*', $confighash{$cgiparams{'KEY'}}[44]));
+ my $issuer = uri_encode("$mainsettings{'HOSTNAME'}.$mainsettings{'DOMAINNAME'}");
my $qrcodeimg = $qrcode->plot("otpauth://totp/$cn?secret=$secret&issuer=$issuer");
my $qrcodeimgdata;
$qrcodeimg->write(data => \$qrcodeimgdata, type=> 'png')
###
} elsif ($cgiparams{'ACTION'} eq $Lang::tr{'show dh'}) {
- if (! -e "${General::swroot}/ovpn/ca/dh1024.pem") {
+ if (! -e "$dhparameter") {
$errormessage = $Lang::tr{'not present'};
} else {
&Header::showhttpheaders();
&Header::openpage($Lang::tr{'ovpn'}, 1, '');
&Header::openbigbox('100%', 'LEFT', '', '');
&Header::openbox('100%', 'LEFT', "$Lang::tr{'dh'}:");
- my @output = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "${General::swroot}/ovpn/ca/dh1024.pem");
+ my @output = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "$dhparameter");
my $output = &Header::cleanhtml(join("", @output) ,"y");
print "<pre>$output</pre>\n";
&Header::closebox();
<hr size='1'>
<table width='100%'>
<tr>
- <td class'base'><b>$Lang::tr{'misc-options'}</b></td>
+ <td class='base'><b>$Lang::tr{'misc-options'}</b></td>
</tr>
<tr>
<hr size='1'>
<table width='100%'>
<tr>
- <td class'base'><b>$Lang::tr{'log-options'}</b></td>
+ <td class='base'><b>$Lang::tr{'log-options'}</b></td>
</tr>
<tr>
<td width='20%'></td> <td width='30%'> </td><td width='25%'> </td><td width='25%'></td>
my @tmp = <FILE>;
close(FILE);
- print "@tmp";
+ print @tmp;
exit (0);
}
print FILE "# Logfile\n";
print FILE "status-version 1\n";
print FILE "status /var/run/openvpn/$n2nname[0]-n2n 10\n";
+ if (&iscertlegacy("${General::swroot}/ovpn/certs/$cgiparams{'n2nname'}")) {
+ print CLIENTCONF "providers legacy default\n";
+ }
+
close FILE;
unless(move("$tempdir/$uplconffilename", "${General::swroot}/ovpn/n2nconf/$n2nname[0]/$uplconffilename2")) {
}
} else { # child
unless (exec ('/usr/bin/openssl', 'req', '-nodes',
- '-newkey', 'rsa:2048',
+ '-newkey', 'rsa:4096',
'-keyout', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}key.pem",
'-out', "${General::swroot}/ovpn/certs/$cgiparams{'NAME'}req.pem",
'-config',"${General::swroot}/ovpn/openssl/ovpn.cnf")) {
$confighash{$key}[42] = 'HOTP/T30/6';
$confighash{$key}[43] = $cgiparams{'OTP_STATE'};
- if (($confighash{$key}[43] == 'on') && ($confighash{$key}[44] == '')) {
+ if (($confighash{$key}[43] eq 'on') && ($confighash{$key}[44] eq '')) {
my @otp_secret = &General::system_output("/usr/bin/openssl", "rand", "-hex", "20");
+ chomp($otp_secret[0]);
$confighash{$key}[44] = $otp_secret[0];
- } elsif ($confighash{$key}[43] == '') {
+ } elsif ($confighash{$key}[43] eq '') {
$confighash{$key}[44] = '';
}
<tr><td colspan=4><hr /></td></tr><tr>
<tr>
- <td class'base'><b>$Lang::tr{'MTU settings'}</b></td>
+ <td class='base'><b>$Lang::tr{'MTU settings'}</b></td>
</tr>
<tr><td class='boldbase' nowrap='nowrap'>$Lang::tr{'MTU'}</td>
<tr><td colspan=4><hr /></td></tr><tr>
<tr>
- <td class'base'><b>$Lang::tr{'ovpn crypt options'}:</b></td>
+ <td class='base'><b>$Lang::tr{'ovpn crypt options'}:</b></td>
</tr>
<tr><td class='boldbase'>$Lang::tr{'cipher'}</td>
<tr><td colspan='4'><br></td></tr>
<tr>
- <td class'base'><b>$Lang::tr{'net config'}:</b></td>
+ <td class='base'><b>$Lang::tr{'net config'}:</b></td>
</tr>
<tr><td colspan='1'><br></td></tr>
<tr><td colspan='4'><br></td></tr>
<tr>
- <td class'base'><b>$Lang::tr{'ovpn crypt options'}:</b></td>
+ <td class='base'><b>$Lang::tr{'ovpn crypt options'}:</b></td>
</tr>
<tr><td colspan='1'><br></td></tr>
print "<input type='submit' name='ACTION' value='$Lang::tr{'ccd net'}' />";
print "<input type='submit' name='ACTION' value='$Lang::tr{'advanced server'}' />";
if (( -e "${General::swroot}/ovpn/ca/cacert.pem" &&
- -e "${General::swroot}/ovpn/ca/dh1024.pem" &&
+ -e "$dhparameter" &&
-e "${General::swroot}/ovpn/certs/servercert.pem" &&
-e "${General::swroot}/ovpn/certs/serverkey.pem") &&
(( $cgiparams{'ENABLED'} eq 'on') ||
END
}
if ($confighash{$key}[0] eq 'on') { $gif = 'on.gif'; } else { $gif = 'off.gif'; }
- if ($id % 2) {
- print "<tr>";
+
+ # Create some simple booleans to check the status
+ my $hasExpired;
+ my $expiresSoon;
+
+ # Fetch information about the certificate for non-N2N connections only
+ if ($confighash{$key}[3] ne 'net') {
+ my @cavalid = &General::system_output("/usr/bin/openssl", "x509", "-text",
+ "-in", "${General::swroot}/ovpn/certs/$confighash{$key}[1]cert.pem");
+
+ my $expiryDate = 0;
+
+ # Parse the certificate information
+ foreach my $line (@cavalid) {
+ if ($line =~ /Not After : (.*)[\n]/) {
+ $expiryDate = &Date::Parse::str2time($1);
+ last;
+ }
+ }
+
+ # Calculate the remaining time
+ my $remainingTime = $expiryDate - time();
+
+ # Determine whether the certificate has already expired, or will so soon
+ $hasExpired = ($remainingTime <= 0);
+ $expiresSoon = ($remainingTime <= 30 * 24 * 3600);
+
+ } else {
+ # Populate booleans with dummy values for N2N connections (#13066)
+ $hasExpired = 0;
+ $expiresSoon = 0;
+ }
+
+ print "<tr>";
+
+ if ($hasExpired || $expiresSoon) {
+ $col="bgcolor='$color{'color14'}'";
+ } elsif ($id % 2) {
$col="bgcolor='$color{'color20'}'";
} else {
- print "<tr>";
$col="bgcolor='$color{'color22'}'";
}
- print "<td align='center' nowrap='nowrap' $col>$confighash{$key}[1]</td>";
- print "<td align='center' nowrap='nowrap' $col>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</td>";
- #if ($confighash{$key}[4] eq 'cert') {
- #print "<td align='left' nowrap='nowrap'>$confighash{$key}[2]</td>";
- #} else {
- #print "<td align='left'> </td>";
- #}
- 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' nowrap='nowrap' $col>$confighash{$key}[1]";
+ if ($hasExpired) {
+ print " ($Lang::tr{'openvpn cert has expired'})";
+ } elsif ($expiresSoon) {
+ print " ($Lang::tr{'openvpn cert expires soon'})";
}
-
+ print "</td>";
+ print "<td align='center' nowrap='nowrap' $col>" . $Lang::tr{"$confighash{$key}[3]"} . " (" . $Lang::tr{"$confighash{$key}[4]"} . ")</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>";
}
# Adding DH parameter to chart
- if (-f "${General::swroot}/ovpn/ca/dh1024.pem") {
- my @dhsubject = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "${General::swroot}/ovpn/ca/dh1024.pem");
+ if (-f "$dhparameter") {
+ my @dhsubject = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "$dhparameter");
my $dhsubject;
foreach my $line (@dhsubject) {
print <<END;
<tr>
- <td class='base' $col3>$Lang::tr{'dh parameter'}</td>
+ <td class='base' $col3>$Lang::tr{'dh'}</td>
<td class='base' $col3>$dhsubject</td>
<form method='post' name='frmdhparam'><td width='3%' align='center' $col3>
<input type='hidden' name='ACTION' value='$Lang::tr{'show dh'}' />
# Nothing
print <<END;
<tr>
- <td width='25%' class='base' $col3>$Lang::tr{'dh parameter'}:</td>
+ <td width='25%' class='base' $col3>$Lang::tr{'dh'}:</td>
<td class='base' $col3>$Lang::tr{'not present'}</td>
</td><td colspan='3' $col3> </td>
</tr>
<td align='right'><input type='submit' name='ACTION' value='$Lang::tr{'show crl'}' /></td>
</tr>
</table>
-
- <br>
-
- <table border='0' width='100%'>
- <tr>
- <td colspan='4'><b>$Lang::tr{'ovpn dh parameters'}</b></td>
- </tr>
-
- <tr>
- <td width='40%'>$Lang::tr{'ovpn dh upload'}:</td>
- <td width='30%'><input type='file' name='FH' size='25'>
- <td width='30%' align='right'><input type='submit' name='ACTION' value='$Lang::tr{'upload dh key'}'></td>
- </tr>
-
- <tr>
- <td width='40%'>$Lang::tr{'ovpn dh new key'}:</td>
- <td colspan='2' width='60%' align='right'><input type='submit' name='ACTION' value='$Lang::tr{'generate dh key'}' /></td>
- </tr>
- </table>
</form>
<br><hr>