From 5cff46d00e5be3be98298a2f5f2885753a4ef57d Mon Sep 17 00:00:00 2001 From: Laurent Declercq Date: Sat, 14 Jun 2014 09:40:18 +0200 Subject: [PATCH] Fixed: In case the passphrase is missing, user must not be prompted to enter it (iMSCP::OpenSSL) Fixed: Missing EOL in SSL certificate containers (iMSCP::OpenSSL) CS fixes --- CHANGELOG | 4 +- autoinstaller/Common.pm | 58 +++++------ .../Common/{SimpleClass.pm => Object.pm} | 63 +++++++++--- engine/PerlLib/Modules/Abstract.pm | 2 +- engine/PerlLib/Modules/NetCard.pm | 2 +- engine/PerlLib/Modules/Plugin.pm | 12 +-- engine/PerlLib/Modules/SSLcertificate.pm | 46 +++------ engine/PerlLib/Modules/User.pm | 2 - engine/PerlLib/iMSCP/Config.pm | 18 ++-- engine/PerlLib/iMSCP/Database.pm | 2 +- engine/PerlLib/iMSCP/Dir.pm | 11 +-- engine/PerlLib/iMSCP/File.pm | 19 +--- engine/PerlLib/iMSCP/Mail.pm | 2 +- engine/PerlLib/iMSCP/OpenSSL.pm | 97 ++++++++++++------- engine/PerlLib/iMSCP/Requirements.pm | 2 +- engine/PerlLib/iMSCP/SystemUser.pm | 12 +-- engine/setup/imscp-setup-methods.pl | 78 +++++++-------- 17 files changed, 217 insertions(+), 213 deletions(-) rename engine/PerlLib/Common/{SimpleClass.pm => Object.pm} (55%) diff --git a/CHANGELOG b/CHANGELOG index 758d3790fc..cc1c163468 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -11,7 +11,9 @@ DISTROS ENGINE: Changed: Dovecot SASL implementation is no longer used in Postfix (Replaced by Cyrus SASL) Changed: SASL authentication is now made against database directly (Postfix) - Fixed: Quota script must ignore maildir which doesn't exist + small fixes + Fixed: In case the passphrase is missing, user must not be prompted to enter it (iMSCP::OpenSSL) + Fixed: Missing EOL in SSL certificate containers (iMSCP::OpenSSL) + Fixed: Quota script must ignore maildir which doesn't exist INSTALLER Fixed: Bind9 cannot start if the resolvconf package is not configured yet (Debian Squeeze) diff --git a/autoinstaller/Common.pm b/autoinstaller/Common.pm index b38be054b8..8987c999f2 100644 --- a/autoinstaller/Common.pm +++ b/autoinstaller/Common.pm @@ -23,12 +23,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # -# @category i-MSCP -# @copyright 2010-2014 by i-MSCP | http://i-mscp.net -# @author Daniel Andreca -# @author Laurent Declercq -# @link http://i-mscp.net i-MSCP Home Site -# @license http://www.gnu.org/licenses/gpl-2.0.html GPL v2 +# @category i-MSCP +# @copyright 2010-2014 by i-MSCP | http://i-mscp.net +# @author Daniel Andreca +# @author Laurent Declercq +# @link http://i-mscp.net i-MSCP Home Site +# @license http://www.gnu.org/licenses/gpl-2.0.html GPL v2 package autoinstaller::Common; @@ -69,7 +69,7 @@ our @EXPORT = qw( together in the %main::imscpConfig variable. The old imscp.conf file is tied to the %main::imscpOldConfig variable and set as readonly. - Return int - 0 + Return int 0 =cut @@ -115,7 +115,7 @@ sub loadConfig Trigger pre-required package installation from distro autoinstaller adapter. - Return int - 0 on success, other otherwise + Return int 0 on success, other otherwise =cut @@ -128,7 +128,7 @@ sub installPreRequiredPackages Check distribution. - Return int - 0 on success, 1 on failure + Return int 0 on success, 1 on failure =cut @@ -202,7 +202,7 @@ Thanks for using i-MSCP. Trigger pre-build tasks from distro autoinstaller adapter. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -215,7 +215,7 @@ sub preBuild Trigger packages uninstallation from distro autoinstaller adapter. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -241,7 +241,7 @@ sub installPackages Test for i-MSCP requirements. - Return int 0 - On error, a fatal error is raised + Return int 0 on error, a fatal error is raised =cut @@ -269,7 +269,7 @@ sub processDistroLayoutFile() Process distribution install.xml files. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -314,7 +314,7 @@ sub processDistroInstallFiles Build i-MSCP daemon - Return int - 0 on success, other on failure. + Return int 0 on success, other on failure. =cut @@ -358,7 +358,7 @@ sub buildImscpDaemon Install engine files in build directory. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -395,7 +395,7 @@ sub installEngine Install GUI files in build directory. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut sub installGui @@ -414,7 +414,7 @@ sub installGui Trigger post-build tasks from distro autoinstaller adapter and save i-MSCP main configuration file. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -464,7 +464,7 @@ sub postBuild Backup current i-MSCP installation (database and conffiles) if any. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -499,7 +499,7 @@ Do you want to continue? Save persistent data in build directory. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -602,7 +602,7 @@ sub savePersistentData Install files from build directory on file system. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -647,7 +647,7 @@ sub installTmp Delete build directory. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -669,7 +669,7 @@ sub removeTmp Check availability of the given command. - Return int - 0 if the given command is available, 1 othewise + Return int 0 if the given command is available, 1 othewise =cut @@ -695,7 +695,7 @@ sub checkCommandAvailability($) Process an install.xml file or distribution layout.xml file. - Return int - 0 on success, other on failure ; A fatal error is raised in case a variable cannot be exported + Return int 0 on success, other on failure ; A fatal error is raised in case a variable cannot be exported =cut @@ -806,7 +806,7 @@ sub _expandVars Process the xml 'folder' node by creating the described directory. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -838,7 +838,7 @@ sub _processFolder Process a 'copy_config' node from an install.xml file. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -893,7 +893,7 @@ sub _copyConfig Process the 'copy' node from an install.xml file. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -933,7 +933,7 @@ sub _copy Create a file. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -948,7 +948,7 @@ sub _createFile Change file/directory owner and/or group recursively. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut @@ -974,7 +974,7 @@ sub _chownFile Process chmod_file from an install.xml file. - Return int - 0 on success, other on failure + Return int 0 on success, other on failure =cut diff --git a/engine/PerlLib/Common/SimpleClass.pm b/engine/PerlLib/Common/Object.pm similarity index 55% rename from engine/PerlLib/Common/SimpleClass.pm rename to engine/PerlLib/Common/Object.pm index 380de3eab2..8a5848c6ad 100644 --- a/engine/PerlLib/Common/SimpleClass.pm +++ b/engine/PerlLib/Common/Object.pm @@ -17,35 +17,70 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # -# @category i-MSCP -# @copyright 2010-2014 by i-MSCP | http://i-mscp.net -# @author Daniel Andreca -# @link http://i-mscp.net i-MSCP Home Site -# @license http://www.gnu.org/licenses/gpl-2.0.html GPL v2 +# @category i-MSCP +# @copyright 2010-2014 by i-MSCP | http://i-mscp.net +# @author Laurent Declercq +# @link http://i-mscp.net i-MSCP Home Site +# @license http://www.gnu.org/licenses/gpl-2.0.html GPL v2 -package Common::SimpleClass; +package Common::Object; use strict; use warnings; +=head1 DESCRIPTION + + Object base class. + +=head1 PUBLIC METHODS + +=over 4 + +=item new([%args]) + + Constructor + + Param hash|hash_ref OPTIONAL hash representing class attributes + Return Common::Object + +=cut + sub new { - my $proto = shift; - my $class = ref $proto || $proto; - my $self = { - 'errors' => [], - 'args' => {@_} || {} - }; - - bless($self, $class); + my $class = shift; + + my $self = bless { @_ && ref $_[0] eq 'HASH' ? %{$_[0]} : @_ }, $class; + $self->_init(); $self; } +=back + +=head1 PRIVATE METHODS + +=over 4 + +=item _init() + + Initialize instance + + Return Common::Object + +=cut + sub _init { $_[0]; } +=back + +=head1 AUTHOR + + Laurent Declercq + +=cut + 1; diff --git a/engine/PerlLib/Modules/Abstract.pm b/engine/PerlLib/Modules/Abstract.pm index d9e4945c13..f2d1cf8c65 100644 --- a/engine/PerlLib/Modules/Abstract.pm +++ b/engine/PerlLib/Modules/Abstract.pm @@ -38,7 +38,7 @@ use warnings; use iMSCP::Debug; use iMSCP::Servers; use iMSCP::Addons; -use parent 'Common::SimpleClass'; +use parent 'Common::Object'; =head1 DESCRIPTION diff --git a/engine/PerlLib/Modules/NetCard.pm b/engine/PerlLib/Modules/NetCard.pm index 8138294e4f..145c926139 100644 --- a/engine/PerlLib/Modules/NetCard.pm +++ b/engine/PerlLib/Modules/NetCard.pm @@ -30,7 +30,7 @@ use warnings; use iMSCP::Debug; use iMSCP::Execute; -use parent 'Common::SimpleClass'; +use parent 'Common::Object'; sub process { diff --git a/engine/PerlLib/Modules/Plugin.pm b/engine/PerlLib/Modules/Plugin.pm index 9b175007fe..4a14bf30da 100644 --- a/engine/PerlLib/Modules/Plugin.pm +++ b/engine/PerlLib/Modules/Plugin.pm @@ -42,7 +42,7 @@ use iMSCP::HooksManager; use iMSCP::File; use version; use JSON; -use parent 'Common::SimpleClass'; +use parent 'Common::Object'; # Map action status to next status my %actionStatusToNextStatus = ( @@ -113,7 +113,7 @@ sub process($$) $rs ? (scalar getMessageByType('error') || 'unknown error') : $actionStatusToNextStatus{$status}, $pluginId ); - my $rdata = $self->{'_db'}->doQuery('dummy', @sql); + my $rdata = $self->{'db'}->doQuery('dummy', @sql); unless(ref $rdata eq 'HASH') { error($rdata); return 1; @@ -141,7 +141,7 @@ sub _init my $self = $_[0]; $self->{'hooksManager'} = iMSCP::HooksManager->getInstance(); - $self->{'_db'} = iMSCP::Database->factory(); + $self->{'db'} = iMSCP::Database->factory(); $self; } @@ -159,7 +159,7 @@ sub _loadData($$) { my ($self, $pluginId) = @_; - my $rdata = $self->{'_db'}->doQuery( + my $rdata = $self->{'db'}->doQuery( 'plugin_id', 'SELECT plugin_id, plugin_name, plugin_info, plugin_status FROM plugin WHERE plugin_id = ?', $pluginId @@ -291,7 +291,7 @@ sub _change($$) if($info->{'__need_change__'}) { $info->{'__need_change__'} = JSON::false; - $rs = $self->{'_db'}->doQuery( + $rs = $self->{'db'}->doQuery( 'dummy', 'UPDATE plugin SET plugin_info = ? WHERE plugin_name = ?', encode_json($info), $pluginName ); unless(ref $rs eq 'HASH') { @@ -334,7 +334,7 @@ sub _update($$) $info->{'version'} = $info->{'__nversion__'}; $info->{'__need_change__'} = JSON::false; - $rs = $self->{'_db'}->doQuery( + $rs = $self->{'db'}->doQuery( 'dummy', 'UPDATE plugin SET plugin_info = ? WHERE plugin_name = ?', encode_json($info), $pluginName ); unless(ref $rs eq 'HASH') { diff --git a/engine/PerlLib/Modules/SSLcertificate.pm b/engine/PerlLib/Modules/SSLcertificate.pm index 694243de56..f6786ea401 100644 --- a/engine/PerlLib/Modules/SSLcertificate.pm +++ b/engine/PerlLib/Modules/SSLcertificate.pm @@ -152,54 +152,30 @@ sub add { my $self = $_[0]; - my $openSSL = iMSCP::OpenSSL->getInstance(); - - # Set OpenSSL binary path on OpenSSL module - $openSSL->{'openssl_path'} = $main::imscpConfig{'CMD_OPENSSL'}; - - # Set SSL certificate directory on OpenSSL module - $openSSL->{'certificate_chains_storage_dir'} = $self->{'certsDir'}; - - # Set certificate chain container name on OpenSSL module - $openSSL->{'certificate_chain_name'} = $self->{'domain_name'}; - - ## Private key - - # Create container for private key + # Private key my $privateKeyContainer = File::Temp->new(); - - # Write private key in container print $privateKeyContainer $self->{'private_key'}; - # Set private key container path on OpenSSL module - $openSSL->{'private_key_container_path'} = $privateKeyContainer; - # Certificate - - # Create container for SSL certificate my $certificateContainer = File::Temp->new(); - - # Write certificate in container print $certificateContainer $self->{'certificate'}; - # Set certificate container path on OpenSSL module - $openSSL->{'certificate_container_path'} = $certificateContainer; - # CA Bundle (intermediate certificate(s)) - if($self->{'ca_bundle'}) { - # Create container for CA bundle my $caBundleContainer = File::Temp->new(); - - # Write CA bundle in container print $caBundleContainer $self->{'ca_bundle'}; - - # Set CA bundle container path on OpenSSL module - $openSSL->{'ca_bundle_container_path'} = $caBundleContainer; - } else { - $openSSL->{'ca_bundle_container_path'} = ''; } + # Create OpenSSL object + my $openSSL = iMSCP::OpenSSL->new( + 'openssl_path' => $main::imscpConfig{'CMD_OPENSSL'}, + 'certificate_chains_storage_dir' => $self->{'certsDir'}, + 'certificate_chain_name' => $self->{'domain_name'}, + 'private_key_container_path' => $privateKeyContainer, + 'certificate_container_path' => $certificateContainer, + 'ca_bundle_container_path' => (defined $caBundleContainer) ? $caBundleContainer : '' + ); + # Check certificate chain my $rs = $openSSL->validateCertificateChain(); return $rs if $rs; diff --git a/engine/PerlLib/Modules/User.pm b/engine/PerlLib/Modules/User.pm index 6c6668e739..4c795e0d44 100644 --- a/engine/PerlLib/Modules/User.pm +++ b/engine/PerlLib/Modules/User.pm @@ -46,8 +46,6 @@ sub _init { my $self = $_[0]; - $self->{$_} = $self->{'args'}->{$_} for keys %{$self->{'args'}}; - $self->{'hooksManager'} = iMSCP::HooksManager->getInstance(); $self->{'type'} = 'User'; diff --git a/engine/PerlLib/iMSCP/Config.pm b/engine/PerlLib/iMSCP/Config.pm index 41d6533b1f..a9dd1b6f14 100644 --- a/engine/PerlLib/iMSCP/Config.pm +++ b/engine/PerlLib/iMSCP/Config.pm @@ -37,7 +37,7 @@ use warnings; use Tie::File; use iMSCP::Debug; use Fcntl 'O_RDWR', 'O_CREAT', 'O_RDONLY'; -use parent 'Common::SimpleClass'; +use parent 'Common::Object'; =head1 DESCRIPTION @@ -84,8 +84,8 @@ sub _init $self->{'configValues'} = {}; $self->{'lineMap'} = {}; - if(defined $self->{'args'}->{'fileName'}) { - $self->{'confFileName'} = $self->{'args'}->{'fileName'}; + if(defined $self->{'fileName'}) { + $self->{'confFileName'} = $self->{'fileName'}; } else { fatal('fileName attribut is not defined'); } @@ -114,20 +114,20 @@ sub _loadConfig debug("Loading $self->{'confFileName'}"); - if($self->{'args'}->{'nocreate'}) { - if($self->{'args'}->{'readonly'}) { + if($self->{'nocreate'}) { + if($self->{'readonly'}) { $mode = O_RDONLY; } else { $mode = O_RDWR; } - } elsif($self->{'args'}->{'readonly'}) { + } elsif($self->{'readonly'}) { $mode = O_RDONLY; } else { $mode = O_RDWR | O_CREAT; } if(! tie @{$self->{'confFile'}}, 'Tie::File', $self->{'confFileName'}, 'mode' => $mode) { - if($self->{'args'}->{'nofail'}) { + if($self->{'nofail'}) { require Tie::Array; tie @{$self->{'confFile'}}, 'Tie::StdArray'; } else { @@ -177,7 +177,7 @@ sub FETCH { my ($self, $config) = @_; - if (! exists $self->{'configValues'}->{$config} && ! $self->{'args'}->{'noerrors'}) { + if (! exists $self->{'configValues'}->{$config} && ! $self->{'noerrors'}) { error(sprintf('Accessing non existing config value %s', $config)); } @@ -196,7 +196,7 @@ sub STORE { my ($self, $config, $value) = @_; - if(! $self->{'args'}->{'readonly'}) { + if(! $self->{'readonly'}) { if(! exists $self->{'configValues'}->{$config}) { $self->_insertConfig($config, $value); } else { diff --git a/engine/PerlLib/iMSCP/Database.pm b/engine/PerlLib/iMSCP/Database.pm index a620c2f4e6..a01449aac5 100644 --- a/engine/PerlLib/iMSCP/Database.pm +++ b/engine/PerlLib/iMSCP/Database.pm @@ -61,7 +61,7 @@ sub factory($$) { my $adapterName = $_[1] || $main::imscpConfig{'DATABASE_TYPE'}; - unless($adapterInstances{$adapterName}) { + unless(defined $adapterInstances{$adapterName}) { my $adapter = "iMSCP::Database::${adapterName}"; eval "require $adapter" or fatal("Unable to load database adapter $adapter: $@"); $adapterInstances{$adapterName} = $adapter->getInstance(); diff --git a/engine/PerlLib/iMSCP/Dir.pm b/engine/PerlLib/iMSCP/Dir.pm index e120aaae59..b94570302b 100644 --- a/engine/PerlLib/iMSCP/Dir.pm +++ b/engine/PerlLib/iMSCP/Dir.pm @@ -32,18 +32,9 @@ use iMSCP::Debug; use iMSCP::File; use File::Path qw/mkpath remove_tree/; use File::Copy; -use parent 'Common::SimpleClass'; +use parent 'Common::Object'; use vars qw/$AUTOLOAD/; -sub _init -{ - my $self = $_[0]; - - $self->{$_} = $self->{'args'}->{$_} for keys %{$self->{'args'}}; - - $self; -} - sub getFiles { my $self = $_[0]; diff --git a/engine/PerlLib/iMSCP/File.pm b/engine/PerlLib/iMSCP/File.pm index 41eb60376f..aefbbdb376 100644 --- a/engine/PerlLib/iMSCP/File.pm +++ b/engine/PerlLib/iMSCP/File.pm @@ -39,7 +39,7 @@ use iMSCP::Debug; use FileHandle; use File::Copy; use File::Basename; -use parent 'Common::SimpleClass'; +use parent 'Common::Object'; =head1 DESCRIPTION @@ -356,23 +356,6 @@ sub moveFile =over 4 -=item _init() - - Initialize instance - - Return iMSCP:File - -=cut - -sub _init -{ - my $self = $_[0]; - - $self->{$_} = $self->{'args'}->{$_} for keys %{$self->{'args'}}; - - $self; -} - =item DESTROY() Close last filehandle opened when instance get destroyed diff --git a/engine/PerlLib/iMSCP/Mail.pm b/engine/PerlLib/iMSCP/Mail.pm index 4a21e630b1..71c53aeb1f 100644 --- a/engine/PerlLib/iMSCP/Mail.pm +++ b/engine/PerlLib/iMSCP/Mail.pm @@ -38,7 +38,7 @@ use parent 'Exporter'; $Text::Wrap::columns = 75; $Text::Wrap::break = qr/[\s\n\|]/; -use parent 'Common::SimpleClass'; +use parent 'Common::Object'; sub errmsg { diff --git a/engine/PerlLib/iMSCP/OpenSSL.pm b/engine/PerlLib/iMSCP/OpenSSL.pm index 3b077441e9..31ed906bca 100644 --- a/engine/PerlLib/iMSCP/OpenSSL.pm +++ b/engine/PerlLib/iMSCP/OpenSSL.pm @@ -25,7 +25,6 @@ iMSCP::OpenSSL - i-MSCP OpenSSL library # # @category i-MSCP # @copyright 2010-2014 by i-MSCP | http://i-mscp.net -# @author Daniel Andreca # @author Laurent Declercq # @link http://i-mscp.net i-MSCP Home Site # @license http://www.gnu.org/licenses/gpl-2.0.html GPL v2 @@ -39,7 +38,7 @@ use iMSCP::Debug; use iMSCP::File; use iMSCP::Execute; use File::Temp; -use parent 'Common::SingletonClass'; +use parent 'Common::Object'; =head1 DESCRIPTION @@ -69,27 +68,25 @@ sub validatePrivateKey return -1; } - my $passphraseFile; - if($self->{'private_key_passphrase'} ne '') { - # Create temporary file for private key passphrase - $passphraseFile = File::Temp->new(); + my $passphraseFile = File::Temp->new(); + # Create temporary file for private key passphrase + $passphraseFile = File::Temp->new(); - # Write SSL private key passphrase into temporary file, which is only readable by root - print $passphraseFile $self->{'private_key_passphrase'}; - } + # Write SSL private key passphrase into temporary file, which is only readable by root + print $passphraseFile $self->{'private_key_passphrase'}; my @cmd = ( "$self->{'openssl_path'} rsa", '-in', escapeShell($self->{'private_key_container_path'}), '-noout', - ($passphraseFile) ? ('-passin', escapeShell("file:$passphraseFile")) : '' + '-passin', escapeShell("file:$passphraseFile") ); my ($stdout, $stderr); my $rs = execute("@cmd", \$stdout, \$stderr); debug($stdout) if $stdout; warning($stderr) if $stderr && ! $rs; - error("Invalid private key or passphrase" . ($stderr ? ": $stderr" : '') . '.') if $rs; + error("Invalid private key or passphrase") if $rs; return $rs if $rs; 0; @@ -118,6 +115,7 @@ sub validateCertificate } my $caBundle = 0; + if ($self->{'ca_bundle_container_path'} ne '' ) { if (-f $self->{'ca_bundle_container_path'}) { $caBundle = 1; @@ -176,7 +174,8 @@ sub importPrivateKey my $self = $_[0]; my $passphraseFile; - if($self->{'private_key_passphrase'} ne '') { + + if($self->{'private_key_passphrase'} ne 'dummy') { # Create temporary file for private key passphrase $passphraseFile = File::Temp->new(); @@ -188,16 +187,15 @@ sub importPrivateKey "$self->{'openssl_path'} rsa", '-in', escapeShell($self->{'private_key_container_path'}), '-out', escapeShell("$self->{'certificate_chains_storage_dir'}/$self->{'certificate_chain_name'}.pem"), - ($passphraseFile) ? ('-passin', escapeShell("file:$passphraseFile")) : '' + (defined $passphraseFile) ? ('-passin', escapeShell("file:$passphraseFile")) : '' ); my ($stdout, $stderr); my $rs = execute("@cmd", \$stdout, \$stderr); debug($stdout) if $stdout; error("Unable to import SSL private key" . (($stderr) ? ": $stderr" : '')) if $rs; - return $rs if $rs; - 0; + $rs; } =item importCertificate() @@ -212,6 +210,22 @@ sub importCertificate { my $self = $_[0]; + my $file = iMSCP::File->new('filename' => $self->{'certificate_container_path'}); + + my $certificate = $file->get(); + unless(defined $certificate) { + error("Unable to read $self->{'certificate_container_path'}"); + return 1; + } + + $certificate =~ s/^(?:\015?\012)+|(?:\015?\012)+$//g; + + my $rs = $file->set("$certificate\n"); + return $rs if $rs; + + $rs = $file->save(); + return $rs if $rs; + my @cmd = ( $main::imscpConfig{'CMD_CAT'}, escapeShell($self->{'certificate_container_path'}), @@ -219,13 +233,12 @@ sub importCertificate ); my ($stdout, $stderr); - my $rs = execute("@cmd", \$stdout, \$stderr); + $rs = execute("@cmd", \$stdout, \$stderr); debug($stdout) if $stdout; warning($stderr) if $stderr && ! $rs; error("Unable to import SSL certificate" . (($stderr) ? ": $stderr" : '')) if $rs; - return $rs if $rs; - 0; + $rs; } =item importCaBundle() @@ -241,6 +254,22 @@ sub ImportCaBundle my $self = $_[0]; if($self->{'ca_bundle_container_path'} ne '') { + my $file = iMSCP::File->new('filename' => $self->{'ca_bundle_container_path'}); + + my $caBundle = $file->get(); + unless(defined $caBundle) { + error("Unable to read $self->{'ca_bundle_container_path'}"); + return 1; + } + + $caBundle =~ s/^(?:\015?\012)+|(?:\015?\012)+$//g; + + my $rs = $file->set("$caBundle\n"); + return $rs if $rs; + + $rs = $file->save(); + return $rs if $rs; + my @cmd = ( $main::imscpConfig{'CMD_CAT'}, escapeShell($self->{'ca_bundle_container_path'}), @@ -248,7 +277,7 @@ sub ImportCaBundle ); my ($stdout, $stderr); - my $rs = execute("@cmd", \$stdout, \$stderr); + $rs = execute("@cmd", \$stdout, \$stderr); debug($stdout) if $stdout; warning($stderr) if $stderr && ! $rs; error("Unable to import CA Bundle" . (($stderr) ? ": $stderr" : '')) if $rs; @@ -263,7 +292,7 @@ sub ImportCaBundle Generate a self-signed SSL certificate Param string $commonName Common Name - Param bool $wildcardSSL OPTIONAL Does a wildcard SSL certificate must be generated (default TRUE) + Param bool $wildcardSSL OPTIONAL Does a wildcard SSL certificate must be generated (default FALSE) Return int 0 on success, other on failure =cut @@ -286,10 +315,9 @@ sub createSelfSignedCertificate my $rs = execute("@cmd", \$stdout, \$stderr); debug($stdout) if $stdout; debug($stderr) if $stderr && ! $rs; - error("Unable to generate self-signed certificate" . (($stderr) ? ": $stderr" : '')) if $rs; - return $rs if($rs); + error('Unable to generate self-signed certificate' . (($stderr) ? ": $stderr" : '')) if $rs; - 0; + $rs } =item createCertificateChain() @@ -328,25 +356,25 @@ sub _init my $self = $_[0]; # Path to the openssl binary - $self->{'openssl_path'} = ''; + $self->{'openssl_path'} = '' unless defined $self->{'openssl_path'}; # Full path to the certificate chains storage directory - $self->{'certificate_chains_storage_dir'} = ''; + $self->{'certificate_chains_storage_dir'} = '' unless defined $self->{'certificate_chains_storage_dir'}; # Certificate chain name - $self->{'certificate_chain_name'} = ''; - - # Full path to the SSL certificate container - $self->{'certificate_container_path'} = ''; - - # Full path to the CA Bundle container (Container which contain one or many intermediate certificates) - $self->{'ca_bundle_container_path'} = ''; + $self->{'certificate_chain_name'} = '' unless defined $self->{'certificate_chain_name'}; # Full path to the private key container - $self->{'private_key_container_path'} = ''; + $self->{'private_key_container_path'} = '' unless defined $self->{'private_key_container_path'}; # Private key passphrase if any - $self->{'private_key_passphrase'} = ''; + $self->{'private_key_passphrase'} = 'dummy' unless defined $self->{'private_key_passphrase'}; + + # Full path to the SSL certificate container + $self->{'certificate_container_path'} = '' unless defined $self->{'certificate_container_path'};; + + # Full path to the CA Bundle container (Container which contain one or many intermediate certificates) + $self->{'ca_bundle_container_path'} = '' unless defined $self->{'ca_bundle_container_path'};; $self; } @@ -355,7 +383,6 @@ sub _init =head1 AUTHORS - Daniel Andreca Laurent Declercq =cut diff --git a/engine/PerlLib/iMSCP/Requirements.pm b/engine/PerlLib/iMSCP/Requirements.pm index 163f50d55f..0b79d8ac0a 100644 --- a/engine/PerlLib/iMSCP/Requirements.pm +++ b/engine/PerlLib/iMSCP/Requirements.pm @@ -37,7 +37,7 @@ use warnings; use iMSCP::Debug; use iMSCP::Execute; use version; -use parent 'Common::SimpleClass'; +use parent 'Common::Object'; # Initializer. # diff --git a/engine/PerlLib/iMSCP/SystemUser.pm b/engine/PerlLib/iMSCP/SystemUser.pm index 8e44d4d97f..e9e09f01d2 100644 --- a/engine/PerlLib/iMSCP/SystemUser.pm +++ b/engine/PerlLib/iMSCP/SystemUser.pm @@ -31,17 +31,7 @@ use warnings; use iMSCP::Debug; use iMSCP::Execute; -use parent 'Common::SimpleClass'; - -# Initialize instance -sub _init -{ - my $self = $_[0]; - - $self->{$_} = $self->{'args'}->{$_} for keys %{$self->{'args'}}; - - $self; -} +use parent 'Common::Object'; # Add the given unix user sub addSystemUser diff --git a/engine/setup/imscp-setup-methods.pl b/engine/setup/imscp-setup-methods.pl index 232a2beb36..f78fb2217f 100644 --- a/engine/setup/imscp-setup-methods.pl +++ b/engine/setup/imscp-setup-methods.pl @@ -963,8 +963,7 @@ sub setupAskPanelSsl my $caBundlePath = setupGetQuestion('PANEL_SSL_CA_BUNDLE_PATH', '/root/'); my $baseServerVhostPrefix = setupGetQuestion('BASE_SERVER_VHOST_PREFIX', 'http://'); - my $openSSL = iMSCP::OpenSSL->getInstance(); - $openSSL->{'openssl_path'} = $main::imscpConfig{'CMD_OPENSSL'}; + my $openSSL = iMSCP::OpenSSL->new('openssl_path' => $main::imscpConfig{'CMD_OPENSSL'}); my $rs = 0; @@ -1029,13 +1028,15 @@ sub setupAskPanelSsl } while($rs != 30 && ! ($caBundlePath && -f $caBundlePath)); $openSSL->{'ca_bundle_container_path'} = $caBundlePath if $rs != 30; + } else { + $openSSL->{'ca_bundle_container_path'} = ''; } $ENV{'DIALOG_CANCEL'} = 30; } if($rs != 30) { - $dialog->msgbox("\nPlease selects your own SSL certificate in next dialog."); + $dialog->msgbox("\nPlease selects your SSL certificate in next dialog."); $rs = 1; @@ -1066,8 +1067,8 @@ sub setupAskPanelSsl $openSSL->{'ca_bundle_container_path'} = "$main::imscpConfig{'GUI_CERT_DIR'}/$domainName.pem"; $openSSL->{'certificate_container_path'} = "$main::imscpConfig{'GUI_CERT_DIR'}/$domainName.pem"; - if($openSSL->validateCertificateChain()){ - iMSCP::Dialog->factory()->msgbox("\nYour SSL certificate is missing or invalid."); + if($openSSL->validateCertificateChain()) { + iMSCP::Dialog->factory()->msgbox("\nYour SSL certificate for the control panel is missing or invalid."); goto SSL_DIALOG; } @@ -1101,8 +1102,7 @@ sub setupAskServicesSsl my $certificatPath = setupGetQuestion('SERVICES_SSL_CERTIFICATE_PATH', "/root/"); my $caBundlePath = setupGetQuestion('SERVICES_SSL_CA_BUNDLE_PATH', '/root/'); - my $openSSL = iMSCP::OpenSSL->getInstance(); - $openSSL->{'openssl_path'} = $main::imscpConfig{'CMD_OPENSSL'}; + my $openSSL = iMSCP::OpenSSL->new('openssl_path' => $main::imscpConfig{'CMD_OPENSSL'}); my $rs = 0; @@ -1169,13 +1169,15 @@ sub setupAskServicesSsl } while($rs != 30 && ! ($caBundlePath && -f $caBundlePath)); $openSSL->{'ca_bundle_container_path'} = $caBundlePath if $rs != 30; + }else { + $openSSL->{'ca_bundle_container_path'} = ''; } $ENV{'DIALOG_CANCEL'} = 30; } if($rs != 30) { - $dialog->msgbox("\nPlease selects your own SSL certificate in next dialog."); + $dialog->msgbox("\nPlease selects your SSL certificate in next dialog."); $rs = 1; @@ -1196,8 +1198,8 @@ sub setupAskServicesSsl $openSSL->{'ca_bundle_container_path'} = "$main::imscpConfig{'GUI_CERT_DIR'}/imscp_services.pem"; $openSSL->{'certificate_container_path'} = "$main::imscpConfig{'GUI_CERT_DIR'}/imscp_services.pem"; - if($openSSL->validateCertificateChain()){ - iMSCP::Dialog->factory()->msgbox("\nYour SSL certificate is missing or invalid."); + if($openSSL->validateCertificateChain()) { + iMSCP::Dialog->factory()->msgbox("\nYour SSL certificate for the services is missing or invalid."); goto SSL_DIALOG; } @@ -1855,23 +1857,23 @@ sub setupPanelSsl my $sslEnabled = setupGetQuestion('PANEL_SSL_ENABLED'); if($sslEnabled eq 'yes' && setupGetQuestion('PANEL_SSL_SETUP', 'yes') eq 'yes') { - my $openSSL = iMSCP::OpenSSL->getInstance(); - $openSSL->{'openssl_path'} = $main::imscpConfig{'CMD_OPENSSL'}; - - # Setup library for new certificate - $openSSL->{'certificate_chains_storage_dir'} = $main::imscpConfig{'GUI_CERT_DIR'}; - $openSSL->{'certificate_chain_name'} = $domainName; - if($selfSignedCertificate) { - my $rs = $openSSL->createSelfSignedCertificate($domainName); + my $rs = iMSCP::OpenSSL->new( + 'openssl_path' => $main::imscpConfig{'CMD_OPENSSL'}, + 'certificate_chains_storage_dir' => $main::imscpConfig{'GUI_CERT_DIR'}, + 'certificate_chain_name' => $domainName + )->createSelfSignedCertificate($domainName); return $rs if $rs; } else { - $openSSL->{'private_key_container_path'} = $privateKeyPath; - $openSSL->{'private_key_passphrase'} = $passphrase; - $openSSL->{'certificate_container_path'} = $certificatePath; - $openSSL->{'ca_bundle_container_path'} = $caBundlePath; - - my $rs = $openSSL->createCertificateChain(); + my $rs = iMSCP::OpenSSL->new( + 'openssl_path' => $main::imscpConfig{'CMD_OPENSSL'}, + 'certificate_chains_storage_dir' => $main::imscpConfig{'GUI_CERT_DIR'}, + 'certificate_chain_name' => $domainName, + 'private_key_container_path' => $privateKeyPath, + 'private_key_passphrase' => $passphrase, + 'certificate_container_path' => $certificatePath, + 'ca_bundle_container_path' => $caBundlePath + )->createCertificateChain(); return $rs if $rs; } } @@ -1891,23 +1893,23 @@ sub setupServiceSsl my $sslEnabled = setupGetQuestion('SERVICES_SSL_ENABLED'); if($sslEnabled eq 'yes' && setupGetQuestion('SERVICES_SSL_SETUP', 'yes') eq 'yes') { - my $openSSL = iMSCP::OpenSSL->getInstance(); - $openSSL->{'openssl_path'} = $main::imscpConfig{'CMD_OPENSSL'}; - - # Setup library for new certificate - $openSSL->{'certificate_chains_storage_dir'} = $main::imscpConfig{'GUI_CERT_DIR'}; - $openSSL->{'certificate_chain_name'} = 'imscp_services'; - if($selfSignedCertificate) { - my $rs = $openSSL->createSelfSignedCertificate($domainName, 1); + my $rs = iMSCP::OpenSSL->new( + 'openssl_path' => $main::imscpConfig{'CMD_OPENSSL'}, + 'certificate_chains_storage_dir' => $main::imscpConfig{'GUI_CERT_DIR'}, + 'certificate_chain_name' => $domainName + )->createSelfSignedCertificate($domainName); return $rs if $rs; } else { - $openSSL->{'private_key_container_path'} = $privateKeyPath; - $openSSL->{'private_key_passphrase'} = $passphrase; - $openSSL->{'certificate_container_path'} = $certificatePath; - $openSSL->{'ca_bundle_container_path'} = $caBundlePath; - - my $rs = $openSSL->createCertificateChain(); + my $rs = iMSCP::OpenSSL->new( + 'openssl_path' => $main::imscpConfig{'CMD_OPENSSL'}, + 'certificate_chains_storage_dir' => $main::imscpConfig{'GUI_CERT_DIR'}, + 'certificate_chain_name' => $domainName, + 'private_key_container_path' => $privateKeyPath, + 'private_key_passphrase' => $passphrase, + 'certificate_container_path' => $certificatePath, + 'ca_bundle_container_path' => $caBundlePath + )->createCertificateChain(); return $rs if $rs; } }