diff --git a/administrator/components/com_installer/Helper/InstallerHelper.php b/administrator/components/com_installer/Helper/InstallerHelper.php index 8304b92b97591..6d025cec25dd6 100644 --- a/administrator/components/com_installer/Helper/InstallerHelper.php +++ b/administrator/components/com_installer/Helper/InstallerHelper.php @@ -157,4 +157,81 @@ public static function getStateOptions() return $options; } + + /** + * Get the correct section in the update server manifest + * + * @param string $updateServerManifest List of update servers in the manifest XML + * + * @return JUpdate The update + * + * @since __DEPLOY_VERSION__ + */ + public static function getUpdateServer($updateServerManifest) + { + $pathToServerManifest = array(); + + if ($updateServerManifest) + { + $pathToServerManifest = $updateServerManifest->children(); + } + + foreach ($pathToServerManifest as $child) + { + $update = new \JUpdate; + $update->loadFromXml((string) $child); + } + + return $update; + } + + /** + * Return the result of the checksum of a package and the SHA1/MD5 tags in the update server manifest + * + * @param string $packagefile Location of the package to be installed + * @param Installer $updateServerManifest Update Server manifest + * @param boolean $forceValidation Boolean if force validation is activated + * + * @return boolean if the installation can continue or not + * + * @since __DEPLOY_VERSION__ + */ + public static function isChecksumValid($packagefile, $updateServerManifest, $forceValidation) + { + $app = \JFactory::getApplication(); + + $hashes = array("sha256", "sha384", "sha512"); + $hashOnFile = false; + + foreach ($hashes as $hash) + { + $hashPackage = hash_file($hash, $packagefile); + $hashRemote = $updateServerManifest->$hash->_data; + + if ($hashRemote) + { + $hashOnFile = true; + + if ($hashPackage !== $hashRemote) + { + if (!$forceValidation) + { + $app->enqueueMessage(\JText::_('COM_INSTALLER_INSTALL_CHECKSUM_WRONG_NO_INSTALL'), 'error'); + + return false; + } + + // Checksum failed but forced installation is activated + $app->enqueueMessage(\JText::_('COM_INSTALLER_INSTALL_CHECKSUM_WRONG'), 'warning'); + } + } + } + + if (!$hashOnFile) + { + $app->enqueueMessage(\JText::_('COM_INSTALLER_INSTALL_CHECKSUM_NOT_FOUND'), 'notice'); + } + + return true; + } } diff --git a/administrator/components/com_installer/Model/Install.php b/administrator/components/com_installer/Model/Install.php index ce1b993e37d88..eac24f08aaec5 100644 --- a/administrator/components/com_installer/Model/Install.php +++ b/administrator/components/com_installer/Model/Install.php @@ -12,6 +12,7 @@ use Joomla\CMS\Model\Model; use Joomla\CMS\Plugin\PluginHelper; +use Joomla\Component\Installer\Administrator\Helper\InstallerHelper; /** * Extension Manager Install Model @@ -171,6 +172,17 @@ public function install() } } + $isValidChecksum = InstallerHelper::isChecksumValid( + $package['packagefile'], + InstallerHelper::getUpdateServer($installer->manifest->updateservers), + $app->input->getString('force_install') + ); + + if (!$isValidChecksum) + { + return false; + } + // Was the package unpacked? if (!$package || !$package['type']) { diff --git a/administrator/components/com_installer/Model/Update.php b/administrator/components/com_installer/Model/Update.php index ba8d6a4a5d7d5..7f67759c1fa8c 100644 --- a/administrator/components/com_installer/Model/Update.php +++ b/administrator/components/com_installer/Model/Update.php @@ -16,6 +16,7 @@ use Joomla\CMS\Plugin\PluginHelper; use Joomla\Utilities\ArrayHelper; use Joomla\CMS\Mvc\Factory\MvcFactoryInterface; +use Joomla\Component\Installer\Administrator\Helper\InstallerHelper; /** * Installer Update Model @@ -424,9 +425,21 @@ private function install($update) $config = $app->getConfig(); $tmp_dest = $config->get('tmp_path'); + $pathToDownloadedFile = $tmp_dest . '/' . $p_file; + + $isValidChecksum = InstallerHelper::isChecksumValid( + $pathToDownloadedFile, + $update, + true + ); + + if (!$isValidChecksum) + { + return false; + } // Unpack the downloaded package file - $package = \JInstallerHelper::unpack($tmp_dest . '/' . $p_file); + $package = \JInstallerHelper::unpack($pathToDownloadedFile); // Get an installer instance $installer = \JInstaller::getInstance(); diff --git a/administrator/language/en-GB/en-GB.com_installer.ini b/administrator/language/en-GB/en-GB.com_installer.ini index 707bb2cc6ff0e..7b94ba9ff9d31 100644 --- a/administrator/language/en-GB/en-GB.com_installer.ini +++ b/administrator/language/en-GB/en-GB.com_installer.ini @@ -63,6 +63,10 @@ COM_INSTALLER_HEADING_UPDATESITE_NAME_ASC="Update Site ascending" COM_INSTALLER_HEADING_UPDATESITE_NAME_DESC="Update Site descending" COM_INSTALLER_HEADING_UPDATESITEID="ID" COM_INSTALLER_INSTALL_BUTTON="Install" +COM_INSTALLER_INSTALL_CHECKSUM_CORRECT="File Checksum OK" +COM_INSTALLER_INSTALL_CHECKSUM_NOT_FOUND="There were no checksums provided in the package." +COM_INSTALLER_INSTALL_CHECKSUM_WRONG="File Checksum Failed" +COM_INSTALLER_INSTALL_CHECKSUM_WRONG_NO_INSTALL="File Checksum Failed, Extension was not installed." COM_INSTALLER_INSTALL_DIRECTORY="Install Folder" COM_INSTALLER_INSTALL_ERROR="Error installing %s" COM_INSTALLER_INSTALL_FROM_DIRECTORY="Install from Folder" diff --git a/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini b/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini index e3494fd8ce4cd..4415115cd0a68 100644 --- a/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini +++ b/administrator/language/en-GB/en-GB.plg_installer_urlinstaller.ini @@ -4,6 +4,8 @@ ; Note : All ini files need to be saved as UTF-8 PLG_INSTALLER_URLINSTALLER_BUTTON="Check and Install" +PLG_INSTALLER_URLINSTALLER_FORCE_INSTALL="Force Install" +PLG_INSTALLER_URLINSTALLER_FORCE_INSTALL_DETAILS="Forces the installation of the package even if it is not trusted." PLG_INSTALLER_URLINSTALLER_NO_URL="Please enter a URL." PLG_INSTALLER_URLINSTALLER_PLUGIN_XML_DESCRIPTION="This plugin allows you to install packages from a URL." PLG_INSTALLER_URLINSTALLER_TEXT="Install from URL" diff --git a/plugins/installer/packageinstaller/tmpl/default.php b/plugins/installer/packageinstaller/tmpl/default.php index 037e02553fe7c..6d95302a3b827 100644 --- a/plugins/installer/packageinstaller/tmpl/default.php +++ b/plugins/installer/packageinstaller/tmpl/default.php @@ -19,6 +19,14 @@
+
+ +
+ +
+

diff --git a/plugins/installer/urlinstaller/tmpl/default.php b/plugins/installer/urlinstaller/tmpl/default.php index 1a4b1e20e694b..98fae404909d2 100644 --- a/plugins/installer/urlinstaller/tmpl/default.php +++ b/plugins/installer/urlinstaller/tmpl/default.php @@ -21,6 +21,14 @@

+
+ +
+ +
+