The ~24 legit Cadline customizations on the Joomla core (audit sec.16.1): reCAPTCHA anti-spam (registration/reset/remind/login flow, captcha rule), content view tweaks, mod_login template, phpversioncheck. build-baseline.sh overlays these live versions onto the official-package core so the baseline matches live for the legit mods, while the 3 trojanized core files stay clean. NOTE: com_users/controllers/registration.php carries a hardcoded reCAPTCHA secret (redacted; rotate on cleanup) — see malware-iocs.md. Signed-off-by: LÁZÁR Imre <imre@illusion.hu> Assisted-by: claude-code@claude-opus-4-8
375 lines
8.5 KiB
PHP
375 lines
8.5 KiB
PHP
<?php
|
|
/**
|
|
* @package Joomla.Site
|
|
* @subpackage com_users
|
|
*
|
|
* @copyright Copyright (C) 2005 - 2018 Open Source Matters, Inc. All rights reserved.
|
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
|
*/
|
|
|
|
defined('_JEXEC') or die;
|
|
|
|
JLoader::register('UsersController', JPATH_COMPONENT . '/controller.php');
|
|
|
|
/**
|
|
* Registration controller class for Users.
|
|
*
|
|
* @since 1.6
|
|
*/
|
|
class UsersControllerUser extends UsersController
|
|
{
|
|
/**
|
|
* Method to log in a user.
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 1.6
|
|
*/
|
|
public function login()
|
|
{
|
|
$this->checkToken('post');
|
|
|
|
$app = JFactory::getApplication();
|
|
$input = $app->input->getInputForRequestMethod();
|
|
|
|
// Populate the data array:
|
|
$data = array();
|
|
|
|
$data['return'] = base64_decode($input->get('return', '', 'BASE64'));
|
|
$data['username'] = $input->get('username', '', 'USERNAME');
|
|
$data['password'] = $input->get('password', '', 'RAW');
|
|
$data['secretkey'] = $input->get('secretkey', '', 'RAW');
|
|
|
|
// Check for a simple menu item id
|
|
if (is_numeric($data['return']))
|
|
{
|
|
if (JLanguageMultilang::isEnabled())
|
|
{
|
|
$db = JFactory::getDbo();
|
|
$query = $db->getQuery(true)
|
|
->select('language')
|
|
->from($db->quoteName('#__menu'))
|
|
->where('client_id = 0')
|
|
->where('id =' . $data['return']);
|
|
|
|
$db->setQuery($query);
|
|
|
|
try
|
|
{
|
|
$language = $db->loadResult();
|
|
}
|
|
catch (RuntimeException $e)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ($language !== '*')
|
|
{
|
|
$lang = '&lang=' . $language;
|
|
}
|
|
else
|
|
{
|
|
$lang = '';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$lang = '';
|
|
}
|
|
|
|
$data['return'] = 'index.php?Itemid=' . $data['return'] . $lang;
|
|
}
|
|
else
|
|
{
|
|
// Don't redirect to an external URL.
|
|
if (!JUri::isInternal($data['return']))
|
|
{
|
|
$data['return'] = '';
|
|
}
|
|
}
|
|
|
|
// Set the return URL if empty.
|
|
if (empty($data['return']))
|
|
{
|
|
$data['return'] = 'index.php?option=com_users&view=profile';
|
|
}
|
|
|
|
// Set the return URL in the user state to allow modification by plugins
|
|
$app->setUserState('users.login.form.return', $data['return']);
|
|
|
|
// Get the log in options.
|
|
$options = array();
|
|
$options['remember'] = $this->input->getBool('remember', false);
|
|
$options['return'] = $data['return'];
|
|
|
|
// Get the log in credentials.
|
|
$credentials = array();
|
|
$credentials['username'] = $data['username'];
|
|
$credentials['password'] = $data['password'];
|
|
$credentials['secretkey'] = $data['secretkey'];
|
|
|
|
// Perform the log in.
|
|
if (true !== $app->login($credentials, $options))
|
|
{
|
|
// Login failed !
|
|
// Clear user name, password and secret key before sending the login form back to the user.
|
|
$data['remember'] = (int) $options['remember'];
|
|
$data['username'] = '';
|
|
$data['password'] = '';
|
|
$data['secretkey'] = '';
|
|
$app->setUserState('users.login.form.data', $data);
|
|
$uri = JFactory::getURI();
|
|
$url = $uri->toString();
|
|
$app->redirect(JRoute::_($url, false));
|
|
//$app->redirect(JRoute::_('index.php?option=com_users&view=login', false)); //Eredeti
|
|
}
|
|
|
|
// Success
|
|
if ($options['remember'] == true)
|
|
{
|
|
$app->setUserState('rememberLogin', true);
|
|
}
|
|
|
|
$app->setUserState('users.login.form.data', array());
|
|
$app->redirect(JRoute::_($app->getUserState('users.login.form.return'), false));
|
|
}
|
|
|
|
/**
|
|
* Method to log out a user.
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 1.6
|
|
*/
|
|
public function logout()
|
|
{
|
|
$this->checkToken('request');
|
|
|
|
$app = JFactory::getApplication();
|
|
|
|
// Prepare the logout options.
|
|
$options = array(
|
|
'clientid' => $app->get('shared_session', '0') ? null : 0,
|
|
);
|
|
|
|
// Perform the log out.
|
|
$error = $app->logout(null, $options);
|
|
$input = $app->input->getInputForRequestMethod();
|
|
|
|
// Check if the log out succeeded.
|
|
if ($error instanceof Exception)
|
|
{
|
|
$app->redirect(JRoute::_('index.php?option=com_users&view=login', false));
|
|
}
|
|
|
|
// Get the return URL from the request and validate that it is internal.
|
|
$return = $input->get('return', '', 'BASE64');
|
|
$return = base64_decode($return);
|
|
|
|
// Check for a simple menu item id
|
|
if (is_numeric($return))
|
|
{
|
|
if (JLanguageMultilang::isEnabled())
|
|
{
|
|
$db = JFactory::getDbo();
|
|
$query = $db->getQuery(true)
|
|
->select('language')
|
|
->from($db->quoteName('#__menu'))
|
|
->where('client_id = 0')
|
|
->where('id =' . $return);
|
|
|
|
$db->setQuery($query);
|
|
|
|
try
|
|
{
|
|
$language = $db->loadResult();
|
|
}
|
|
catch (RuntimeException $e)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ($language !== '*')
|
|
{
|
|
$lang = '&lang=' . $language;
|
|
}
|
|
else
|
|
{
|
|
$lang = '';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$lang = '';
|
|
}
|
|
|
|
$return = 'index.php?Itemid=' . $return . $lang;
|
|
}
|
|
else
|
|
{
|
|
// Don't redirect to an external URL.
|
|
if (!JUri::isInternal($return))
|
|
{
|
|
$return = '';
|
|
}
|
|
}
|
|
|
|
// In case redirect url is not set, redirect user to homepage
|
|
if (empty($return))
|
|
{
|
|
$return = JUri::root();
|
|
}
|
|
|
|
// Redirect the user.
|
|
$app->redirect(JRoute::_($return, false));
|
|
}
|
|
|
|
/**
|
|
* Method to logout directly and redirect to page.
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 3.5
|
|
*/
|
|
public function menulogout()
|
|
{
|
|
// Get the ItemID of the page to redirect after logout
|
|
$app = JFactory::getApplication();
|
|
$itemid = $app->getMenu()->getActive()->params->get('logout');
|
|
|
|
// Get the language of the page when multilang is on
|
|
if (JLanguageMultilang::isEnabled())
|
|
{
|
|
if ($itemid)
|
|
{
|
|
$db = JFactory::getDbo();
|
|
$query = $db->getQuery(true)
|
|
->select('language')
|
|
->from($db->quoteName('#__menu'))
|
|
->where('client_id = 0')
|
|
->where('id =' . $itemid);
|
|
|
|
$db->setQuery($query);
|
|
|
|
try
|
|
{
|
|
$language = $db->loadResult();
|
|
}
|
|
catch (RuntimeException $e)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ($language !== '*')
|
|
{
|
|
$lang = '&lang=' . $language;
|
|
}
|
|
else
|
|
{
|
|
$lang = '';
|
|
}
|
|
|
|
// URL to redirect after logout
|
|
$url = 'index.php?Itemid=' . $itemid . $lang;
|
|
}
|
|
else
|
|
{
|
|
// Logout is set to default. Get the home page ItemID
|
|
$lang_code = $app->input->cookie->getString(JApplicationHelper::getHash('language'));
|
|
$item = $app->getMenu()->getDefault($lang_code);
|
|
$itemid = $item->id;
|
|
|
|
// Redirect to Home page after logout
|
|
$url = 'index.php?Itemid=' . $itemid;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// URL to redirect after logout, default page if no ItemID is set
|
|
$url = $itemid ? 'index.php?Itemid=' . $itemid : JUri::root();
|
|
}
|
|
|
|
// Logout and redirect
|
|
$this->setRedirect('index.php?option=com_users&task=user.logout&' . JSession::getFormToken() . '=1&return=' . base64_encode($url));
|
|
}
|
|
|
|
/**
|
|
* Method to request a username reminder.
|
|
*
|
|
* @return boolean
|
|
*
|
|
* @since 1.6
|
|
*/
|
|
public function remind()
|
|
{
|
|
// Check the request token.
|
|
$this->checkToken('post');
|
|
|
|
$app = JFactory::getApplication();
|
|
$model = $this->getModel('User', 'UsersModel');
|
|
$data = $this->input->post->get('jform', array(), 'array');
|
|
|
|
// Submit the username remind request.
|
|
$return = $model->processRemindRequest($data);
|
|
|
|
// Check for a hard error.
|
|
if ($return instanceof Exception)
|
|
{
|
|
// Get the error message to display.
|
|
$message = $app->get('error_reporting')
|
|
? $return->getMessage()
|
|
: JText::_('COM_USERS_REMIND_REQUEST_ERROR');
|
|
|
|
// Get the route to the next page.
|
|
$itemid = UsersHelperRoute::getRemindRoute();
|
|
$itemid = $itemid !== null ? '&Itemid=' . $itemid : '';
|
|
$route = 'index.php?option=com_users&view=remind' . $itemid;
|
|
|
|
// Go back to the complete form.
|
|
$this->setRedirect(JRoute::_($route, false), $message, 'error');
|
|
|
|
return false;
|
|
}
|
|
|
|
if ($return === false)
|
|
{
|
|
// Complete failed.
|
|
// Get the route to the next page.
|
|
$itemid = UsersHelperRoute::getRemindRoute();
|
|
$itemid = $itemid !== null ? '&Itemid=' . $itemid : '';
|
|
$route = 'index.php?option=com_users&view=remind' . $itemid;
|
|
|
|
// Go back to the complete form.
|
|
$message = JText::sprintf('COM_USERS_REMIND_REQUEST_FAILED', $model->getError());
|
|
$this->setRedirect(JRoute::_($route, false), $message, 'notice');
|
|
|
|
return false;
|
|
}
|
|
|
|
// Complete succeeded.
|
|
// Get the route to the next page.
|
|
$itemid = UsersHelperRoute::getLoginRoute();
|
|
$itemid = $itemid !== null ? '&Itemid=' . $itemid : '';
|
|
$route = 'index.php?option=com_users&view=login' . $itemid;
|
|
|
|
// Proceed to the login form.
|
|
$message = JText::_('COM_USERS_REMIND_REQUEST_SUCCESS');
|
|
$this->setRedirect(JRoute::_($route, false), $message);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Method to resend a user.
|
|
*
|
|
* @return void
|
|
*
|
|
* @since 1.6
|
|
*/
|
|
public function resend()
|
|
{
|
|
// Check for request forgeries
|
|
// $this->checkToken('post');
|
|
}
|
|
}
|