EVOLUTION-MANAGER
Edit File: ftp.php
<?php /** * @package Joomla.Installation * @subpackage Model * * @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; use Joomla\Utilities\ArrayHelper; /** * FTP configuration model for the Joomla Core Installer. * * @since 3.1 */ class InstallationModelFtp extends JModelBase { /** * Find the ftp filesystem root for a given user/pass pair. * * @param array $options Configuration options. * * @return mixed FTP root for given FTP user, or boolean false if not found. * * @since 3.1 */ public function detectFtpRoot($options) { // Get the options as an object for easier handling. $options = ArrayHelper::toObject($options); // Connect and login to the FTP server. // Use binary transfer mode to be able to compare files. @$ftp = JClientFtp::getInstance($options->get('ftp_host'), $options->get('ftp_port'), array('type' => FTP_BINARY)); // Check to make sure FTP is connected and authenticated. if (!$ftp->isConnected()) { JFactory::getApplication()->enqueueMessage( $options->get('ftp_host') . ':' . $options->get('ftp_port') . ' ' . JText::_('INSTL_FTP_NOCONNECT'), 'error' ); return false; } if (!$ftp->login($options->get('ftp_user'), $options->get('ftp_pass_plain'))) { JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOLOGIN'), 'error'); return false; } // Get the current working directory from the FTP server. $cwd = $ftp->pwd(); if ($cwd === false) { JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOPWD'), 'error'); return false; } $cwd = rtrim($cwd, '/'); // Get a list of folders in the current working directory. $cwdFolders = $ftp->listDetails(null, 'folders'); if ($cwdFolders === false || count($cwdFolders) === 0) { JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NODIRECTORYLISTING'), 'error'); return false; } // Get just the folder names from the list of folder data. for ($i = 0, $n = count($cwdFolders); $i < $n; $i++) { $cwdFolders[$i] = $cwdFolders[$i]['name']; } // Check to see if Joomla is installed at the FTP current working directory. $paths = array(); $known = array('administrator', 'components', 'installation', 'language', 'libraries', 'plugins'); if (count(array_diff($known, $cwdFolders)) === 0) { $paths[] = $cwd . '/'; } // Search through the segments of JPATH_SITE looking for root possibilities. $parts = explode(DIRECTORY_SEPARATOR, JPATH_SITE); $tmp = ''; for ($i = count($parts) - 1; $i >= 0; $i--) { $tmp = '/' . $parts[$i] . $tmp; if (in_array($parts[$i], $cwdFolders, true)) { $paths[] = $cwd . $tmp; } } // Check all possible paths for the real Joomla installation by comparing version files. $rootPath = false; $checkValue = file_get_contents(JPATH_LIBRARIES . '/cms/version/version.php'); foreach ($paths as $tmp) { $filePath = rtrim($tmp, '/') . '/libraries/cms/version/version.php'; $buffer = null; @$ftp->read($filePath, $buffer); if ($buffer === $checkValue) { $rootPath = $tmp; break; } } // Close the FTP connection. $ftp->quit(); // Return an error if no root path was found. if ($rootPath === false) { JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_UNABLE_DETECT_ROOT_FOLDER'), 'error'); return false; } return $rootPath; } /** * Verify the FTP settings as being functional and correct. * * @param array $options Configuration options. * * @return mixed FTP root for given FTP user, or boolean false if not found. * * @since 3.1 */ public function verifyFtpSettings($options) { // Get the options as an object for easier handling. $options = ArrayHelper::toObject($options); // Connect and login to the FTP server. @$ftp = JClientFtp::getInstance($options->get('ftp_host'), $options->get('ftp_port')); // Check to make sure FTP is connected and authenticated. if (!$ftp->isConnected()) { JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOCONNECT'), 'error'); return false; } if (!$ftp->login($options->get('ftp_user'), $options->get('ftp_pass_plain'))) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOLOGIN'), 'error'); return false; } // Since the root path will be trimmed when it gets saved to configuration.php, // we want to test with the same value as well. $root = rtrim($options->get('ftp_root'), '/'); // Verify PWD function. if ($ftp->pwd() === false) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOPWD'), 'error'); return false; } // Verify root path exists. if (!$ftp->chdir($root)) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOROOT'), 'error'); return false; } // Verify NLST function. if (($rootList = $ftp->listNames()) === false) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NONLST'), 'error'); return false; } // Verify LIST function. if ($ftp->listDetails() === false) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOLIST'), 'error'); return false; } // Verify SYST function. if ($ftp->syst() === false) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOSYST'), 'error'); return false; } // Verify valid root path, part one. $checkList = array('robots.txt', 'index.php'); if (count(array_diff($checkList, $rootList))) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_INVALIDROOT'), 'error'); return false; } // Verify RETR function $buffer = null; if ($ftp->read($root . '/libraries/cms/version/version.php', $buffer) === false) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NORETR'), 'error'); return false; } // Verify valid root path, part two. $checkValue = file_get_contents(JPATH_ROOT . '/libraries/cms/version/version.php'); if ($buffer !== $checkValue) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_INVALIDROOT'), 'error'); return false; } // Verify STOR function. if ($ftp->create($root . '/ftp_testfile') === false) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOSTOR'), 'error'); return false; } // Verify DELE function. if ($ftp->delete($root . '/ftp_testfile') === false) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NODELE'), 'error'); return false; } // Verify MKD function. if ($ftp->mkdir($root . '/ftp_testdir') === false) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NOMKD'), 'error'); return false; } // Verify RMD function. if ($ftp->delete($root . '/ftp_testdir') === false) { $ftp->quit(); JFactory::getApplication()->enqueueMessage(JText::_('INSTL_FTP_NORMD'), 'error'); return false; } $ftp->quit(); return true; } }