File manager - Edit - /home/ferretapmx/public_html/Adapter.tar
Back
TufAdapter.php 0000644 00000015542 15231064064 0007324 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2024 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Updater\Adapter; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Factory; use Joomla\CMS\Http\HttpFactory; use Joomla\CMS\Table\Table; use Joomla\CMS\Table\Tuf as MetadataTable; use Joomla\CMS\TUF\TufFetcher; use Joomla\CMS\Updater\ConstraintChecker; use Joomla\CMS\Updater\UpdateAdapter; use Joomla\CMS\Updater\Updater; use Symfony\Component\OptionsResolver\OptionsResolver; use Tuf\Exception\MetadataException; /** * TUF Update Adapter Class * * @since 5.1.0 * * @internal Currently this class is only used for Joomla! updates and will be extended in the future to support 3rd party updates * Don't extend this class in your own code, it is subject to change without notice. */ class TufAdapter extends UpdateAdapter { /** * Finds an update. * * @param array $options Update options. * * @return array|boolean Array containing the array of update sites and array of updates. False on failure * * @since 5.1.0 */ public function findUpdate($options) { $updates = []; $targets = $this->getUpdateTargets($options); if ($targets) { foreach ($targets as $target) { $updateTable = Table::getInstance('update'); $updateTable->update_site_id = $options['update_site_id']; $updateTable->bind($target); $updates[] = $updateTable; } } return ['update_sites' => [], 'updates' => $updates]; } /** * Finds targets. * * @param array $options Update options. * * @return array|boolean Array containing the array of update sites and array of updates. False on failure * * @since 5.1.0 */ public function getUpdateTargets($options) { $versions = []; /** @var MetadataTable $metadataTable */ $metadataTable = new MetadataTable($this->db); $metadataTable->load(['update_site_id' => $options['update_site_id']]); $tufFetcher = new TufFetcher($metadataTable, $options['location'], $this->db, (new HttpFactory())->getHttp(), Factory::getApplication()); $metaData = $tufFetcher->getValidUpdate(); $metaData = json_decode((string) $metaData, true); if (!isset($metaData['signed']['targets'])) { return false; } foreach ($metaData['signed']['targets'] as $filename => $target) { $version = $this->processTufTarget($filename, $target); if (!$version) { continue; } $version['detailsurl'] = $options['location']; $versions[] = $version; } // We only want the latest version we support usort($versions, function ($a, $b) { return version_compare($b['version'], $a['version']); }); $constraintChecker = new ConstraintChecker(); foreach ($versions as $version) { // Return the version as a match if either all constraints are matched // or "only" env related constraints fail - the later one is the existing behavior of the XML updater if ( $constraintChecker->check($version, $options['minimum_stability'] ?? Updater::STABILITY_STABLE) === true || !empty((array) $constraintChecker->getFailedEnvironmentConstraints()) ) { return [$version]; } } return false; } protected function processTufTarget(string $filename, array $target): bool|array { $resolver = new OptionsResolver(); try { $this->configureUpdateOptions($resolver); $customKeys = $resolver->getDefinedOptions(); } catch (\Exception $e) { return false; } $values = []; if (!isset($target["hashes"])) { throw new MetadataException("No trusted hashes are available for '$filename'"); } foreach ($customKeys as $key) { if (isset($target["custom"][$key])) { $values[$key] = $target["custom"][$key]; } } if (isset($values['client']) && \is_string($values['client'])) { $client = ApplicationHelper::getClientInfo($values['client'], true); if (\is_object($client)) { $values['client_id'] = $client->id; } unset($values['client']); } if (isset($values['infourl']['url'])) { $values['infourl'] = $values['infourl']['url']; } try { $values = $resolver->resolve($values); } catch (\Exception) { return false; } return $values; } /** * Configures default values or pass arguments to params * * @param OptionsResolver $resolver The OptionsResolver for the params * * @return void * * @since 5.1.0 */ protected function configureUpdateOptions(OptionsResolver $resolver) { $resolver->setDefaults( [ 'name' => null, 'description' => '', 'element' => '', 'type' => null, 'client_id' => 0, 'version' => "1", 'data' => '', 'detailsurl' => '', 'infourl' => '', 'downloads' => [], 'targetplatform' => new \StdClass(), 'php_minimum' => null, 'channel' => null, 'supported_databases' => new \StdClass(), 'stability' => '', ] ) ->setAllowedTypes('version', 'string') ->setAllowedTypes('name', 'string') ->setAllowedTypes('element', 'string') ->setAllowedTypes('data', 'string') ->setAllowedTypes('description', 'string') ->setAllowedTypes('type', 'string') ->setAllowedTypes('detailsurl', 'string') ->setAllowedTypes('infourl', 'string') ->setAllowedTypes('client_id', 'int') ->setAllowedTypes('downloads', 'array') ->setAllowedTypes('targetplatform', 'array') ->setAllowedTypes('php_minimum', 'string') ->setAllowedTypes('channel', 'string') ->setAllowedTypes('supported_databases', 'array') ->setAllowedTypes('stability', 'string') ->setRequired(['version']); } } ExtensionAdapter.php 0000644 00000031613 15231064064 0010537 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Updater\Adapter; use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Factory; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Language\Text; use Joomla\CMS\Table\Table; use Joomla\CMS\Updater\UpdateAdapter; use Joomla\CMS\Updater\Updater; use Joomla\CMS\Version; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Extension class for updater * * @since 1.7.0 */ class ExtensionAdapter extends UpdateAdapter { protected $currentUpdate; protected $latest; /** * Start element parser callback. * * @param object $parser The parser object. * @param string $name The name of the element. * @param array $attrs The attributes of the element. * * @return void * * @since 1.7.0 */ protected function _startElement($parser, $name, $attrs = []) { $this->stack[] = $name; $tag = $this->_getStackLocation(); // Reset the data if (isset($this->$tag)) { $this->$tag->_data = ''; } switch ($name) { case 'UPDATE': $this->currentUpdate = Table::getInstance('update'); $this->currentUpdate->update_site_id = $this->updateSiteId; $this->currentUpdate->detailsurl = $this->_url; $this->currentUpdate->folder = ''; $this->currentUpdate->client_id = 1; $this->currentUpdate->infourl = ''; break; case 'UPDATES': // Don't do anything break; default: if (\in_array($name, $this->updatecols)) { $name = strtolower($name); $this->currentUpdate->$name = ''; } if ($name === 'TARGETPLATFORM') { $this->currentUpdate->targetplatform = $attrs; } if ($name === 'PHP_MINIMUM') { $this->currentUpdate->php_minimum = ''; } if ($name === 'SUPPORTED_DATABASES') { $this->currentUpdate->supported_databases = $attrs; } break; } } /** * Character Parser Function * * @param object $parser Parser object. * @param object $name The name of the element. * * @return void * * @since 1.7.0 */ protected function _endElement($parser, $name) { array_pop($this->stack); switch ($name) { case 'UPDATE': // Lower case and remove the exclamation mark $product = strtolower(InputFilter::getInstance()->clean(Version::PRODUCT, 'cmd')); // Check that the product matches and that the version matches (optionally a regexp) if ( $product == $this->currentUpdate->targetplatform['NAME'] && preg_match('/^' . $this->currentUpdate->targetplatform['VERSION'] . '/', JVERSION) ) { // Check if PHP version supported via <php_minimum> tag, assume true if tag isn't present if (!isset($this->currentUpdate->php_minimum) || version_compare(PHP_VERSION, $this->currentUpdate->php_minimum, '>=')) { $phpMatch = true; } else { // Notify the user of the potential update $msg = Text::sprintf( 'JLIB_INSTALLER_AVAILABLE_UPDATE_PHP_VERSION', $this->currentUpdate->name, $this->currentUpdate->version, $this->currentUpdate->php_minimum, PHP_VERSION ); Factory::getApplication()->enqueueMessage($msg, 'warning'); $phpMatch = false; } $dbMatch = false; // Check if DB & version is supported via <supported_databases> tag, assume supported if tag isn't present if (isset($this->currentUpdate->supported_databases)) { $db = Factory::getDbo(); $dbType = strtolower($db->getServerType()); $dbVersion = $db->getVersion(); $supportedDbs = $this->currentUpdate->supported_databases; // MySQL and MariaDB use the same database driver but not the same version numbers if ($dbType === 'mysql') { // Check whether we have a MariaDB version string and extract the proper version from it if (stripos($dbVersion, 'mariadb') !== false) { // MariaDB: Strip off any leading '5.5.5-', if present $dbVersion = preg_replace('/^5\.5\.5-/', '', $dbVersion); $dbType = 'mariadb'; } } // $supportedDbs has uppercase keys because they are XML attribute names $dbTypeUcase = strtoupper($dbType); // Do we have an entry for the database? if (\array_key_exists($dbTypeUcase, $supportedDbs)) { $minimumVersion = $supportedDbs[$dbTypeUcase]; $dbMatch = version_compare($dbVersion, $minimumVersion, '>='); if (!$dbMatch) { // Notify the user of the potential update $dbMsg = Text::sprintf( 'JLIB_INSTALLER_AVAILABLE_UPDATE_DB_MINIMUM', $this->currentUpdate->name, $this->currentUpdate->version, Text::_('JLIB_DB_SERVER_TYPE_' . $dbTypeUcase), $dbVersion, $minimumVersion ); Factory::getApplication()->enqueueMessage($dbMsg, 'warning'); } } else { // Notify the user of the potential update $dbMsg = Text::sprintf( 'JLIB_INSTALLER_AVAILABLE_UPDATE_DB_TYPE', $this->currentUpdate->name, $this->currentUpdate->version, Text::_('JLIB_DB_SERVER_TYPE_' . $dbTypeUcase) ); Factory::getApplication()->enqueueMessage($dbMsg, 'warning'); } } else { // Set to true if the <supported_databases> tag is not set $dbMatch = true; } // Check minimum stability $stabilityMatch = true; if (isset($this->currentUpdate->stability) && ($this->currentUpdate->stability < $this->minimum_stability)) { $stabilityMatch = false; } // Some properties aren't valid fields in the update table so unset them to prevent J! from trying to store them unset($this->currentUpdate->targetplatform); if (isset($this->currentUpdate->php_minimum)) { unset($this->currentUpdate->php_minimum); } if (isset($this->currentUpdate->supported_databases)) { unset($this->currentUpdate->supported_databases); } if (isset($this->currentUpdate->stability)) { unset($this->currentUpdate->stability); } // If the PHP version and minimum stability checks pass, consider this version as a possible update if ($phpMatch && $stabilityMatch && $dbMatch) { if (isset($this->latest)) { // We already have a possible update. Check the version. if (version_compare($this->currentUpdate->version, $this->latest->version, '>') == 1) { $this->latest = $this->currentUpdate; } } else { // We don't have any possible updates yet, assume this is an available update. $this->latest = $this->currentUpdate; } } } break; case 'UPDATES': // :D break; } } /** * Character Parser Function * * @param object $parser Parser object. * @param object $data The data. * * @return void * * @note This is public because its called externally. * @since 1.7.0 */ protected function _characterData($parser, $data) { $tag = $this->_getLastTag(); if (\in_array($tag, $this->updatecols)) { $tag = strtolower($tag); $this->currentUpdate->$tag .= $data; } if ($tag === 'PHP_MINIMUM') { $this->currentUpdate->php_minimum = $data; } if ($tag === 'TAG') { $this->currentUpdate->stability = $this->stabilityTagToInteger((string) $data); } } /** * Finds an update. * * @param array $options Update options. * * @return array|boolean Array containing the array of update sites and array of updates. False on failure * * @since 1.7.0 */ public function findUpdate($options) { $response = $this->getUpdateSiteResponse($options); if ($response === false) { return false; } if (\array_key_exists('minimum_stability', $options)) { $this->minimum_stability = $options['minimum_stability']; } $this->xmlParser = xml_parser_create(''); xml_set_element_handler($this->xmlParser, [$this, '_startElement'], [$this, '_endElement']); xml_set_character_data_handler($this->xmlParser, [$this, '_characterData']); if (!xml_parse($this->xmlParser, (string) $response->getBody())) { // If the URL is missing the .xml extension, try appending it and retry loading the update if (!$this->appendExtension && (!str_ends_with($this->_url, '.xml'))) { $options['append_extension'] = true; return $this->findUpdate($options); } $app = Factory::getApplication(); $app->getLogger()->warning("Error parsing url: {$this->_url}", ['category' => 'updater']); $app->enqueueMessage(Text::sprintf('JLIB_UPDATER_ERROR_EXTENSION_PARSE_URL', $this->_url), 'warning'); return false; } if (isset($this->latest)) { if (isset($this->latest->client) && \strlen($this->latest->client)) { /** * The client_id in the update XML manifest can be either an integer (backwards * compatible with Joomla 1.6–3.10) or a string. Backwards compatibility with the * integer key is provided as update servers with the legacy, numeric IDs cause PHP notices * during update retrieval. The proper string key is one of 'site' or 'administrator'. */ $this->latest->client_id = is_numeric($this->latest->client) ? $this->latest->client : ApplicationHelper::getClientInfo($this->latest->client, true)->id; unset($this->latest->client); } $updates = [$this->latest]; } else { $updates = []; } return ['update_sites' => [], 'updates' => $updates]; } /** * Converts a tag to numeric stability representation. If the tag doesn't represent a known stability level (one of * dev, alpha, beta, rc, stable) it is ignored. * * @param string $tag The tag string, e.g. dev, alpha, beta, rc, stable * * @return integer * * @since 3.4 */ protected function stabilityTagToInteger($tag) { $constant = '\\Joomla\\CMS\\Updater\\Updater::STABILITY_' . strtoupper($tag); if (\defined($constant)) { return \constant($constant); } return Updater::STABILITY_STABLE; } } CollectionAdapter.php 0000644 00000016501 15231064064 0010655 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2008 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Updater\Adapter; use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Factory; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Language\Text; use Joomla\CMS\Table\Table; use Joomla\CMS\Updater\UpdateAdapter; use Joomla\CMS\Version; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Collection Update Adapter Class * * @since 1.7.0 */ class CollectionAdapter extends UpdateAdapter { /** * Root of the tree * * @var object * @since 1.7.0 */ protected $base; /** * Tree of objects * * @var array * @since 1.7.0 */ protected $parent = [0]; /** * Used to control if an item has a child or not * * @var integer * @since 1.7.0 */ protected $pop_parent = 0; /** * A list of discovered update sites * * @var array */ protected $update_sites = []; /** * A list of discovered updates * * @var array */ protected $updates = []; /** * Gets the reference to the current direct parent * * @return string * * @since 1.7.0 */ protected function _getStackLocation() { return implode('->', $this->stack); } /** * Get the parent tag * * @return string parent * * @since 1.7.0 */ protected function _getParent() { return end($this->parent); } /** * Opening an XML element * * @param object $parser Parser object * @param string $name Name of element that is opened * @param array $attrs Array of attributes for the element * * @return void * * @since 1.7.0 */ public function _startElement($parser, $name, $attrs = []) { $this->stack[] = $name; $tag = $this->_getStackLocation(); // Reset the data if (isset($this->$tag)) { $this->$tag->_data = ''; } switch ($name) { case 'CATEGORY': if (isset($attrs['REF'])) { $this->update_sites[] = ['type' => 'collection', 'location' => $attrs['REF'], 'update_site_id' => $this->updateSiteId]; } else { // This item will have children, so prepare to attach them $this->pop_parent = 1; } break; case 'EXTENSION': $update = Table::getInstance('update'); $update->update_site_id = $this->updateSiteId; foreach ($this->updatecols as $col) { // Reset the values if it doesn't exist if (!\array_key_exists($col, $attrs)) { $attrs[$col] = ''; if ($col === 'CLIENT') { $attrs[$col] = 'site'; } } } $client = ApplicationHelper::getClientInfo($attrs['CLIENT'], true); if (isset($client->id)) { $attrs['CLIENT_ID'] = $client->id; } $values = []; // Lower case all of the fields foreach ($attrs as $key => $attr) { $values[strtolower($key)] = $attr; } // Only add the update if it is on the same platform and release as we are $ver = new Version(); // Lower case and remove the exclamation mark $product = strtolower(InputFilter::getInstance()->clean($ver::PRODUCT, 'cmd')); /* * Set defaults, the extension file should clarify in case but it may be only available in one version * This allows an update site to specify a targetplatform * targetplatformversion can be a regexp, so 1.[56] would be valid for an extension that supports 1.5 and 1.6 * Note: Whilst the version is a regexp here, the targetplatform is not (new extension per platform) * Additionally, the version is a regexp here and it may also be in an extension file if the extension is * compatible against multiple versions of the same platform (e.g. a library) */ if (!isset($values['targetplatform'])) { $values['targetplatform'] = $product; } // Set this to ourself as a default if (!isset($values['targetplatformversion'])) { $values['targetplatformversion'] = $ver::MAJOR_VERSION . '.' . $ver::MINOR_VERSION; } // Set this to ourselves as a default // validate that we can install the extension if ($product == $values['targetplatform'] && preg_match('/^' . $values['targetplatformversion'] . '/', JVERSION)) { $update->bind($values); $this->updates[] = $update; } break; } } /** * Closing an XML element * Note: This is a protected function though has to be exposed externally as a callback * * @param object $parser Parser object * @param string $name Name of the element closing * * @return void * * @since 1.7.0 */ protected function _endElement($parser, $name) { array_pop($this->stack); if ($name === 'CATEGORY' && $this->pop_parent) { $this->pop_parent = 0; array_pop($this->parent); } } // Note: we don't care about char data in collection because there should be none /** * Finds an update * * @param array $options Options to use: update_site_id: the unique ID of the update site to look at * * @return array|boolean Update_sites and updates discovered. False on failure * * @since 1.7.0 */ public function findUpdate($options) { $response = $this->getUpdateSiteResponse($options); if ($response === false) { return false; } $this->xmlParser = xml_parser_create(''); xml_set_element_handler($this->xmlParser, [$this, '_startElement'], [$this, '_endElement']); if (!xml_parse($this->xmlParser, (string) $response->getBody())) { // If the URL is missing the .xml extension, try appending it and retry loading the update if (!$this->appendExtension && (!str_ends_with($this->_url, '.xml'))) { $options['append_extension'] = true; return $this->findUpdate($options); } $app = Factory::getApplication(); $app->getLogger()->warning("Error parsing url: {$this->_url}", ['category' => 'updater']); $app->enqueueMessage(Text::sprintf('JLIB_UPDATER_ERROR_COLLECTION_PARSE_URL', $this->_url), 'warning'); return false; } // @todo: Decrement the bad counter if non-zero return ['update_sites' => $this->update_sites, 'updates' => $this->updates]; } } .htaccess 0000555 00000000355 15231064064 0006347 0 ustar 00 <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>