diff --git a/administrator/components/com_admin/sql/updates/mysql/3.2.3-2014-02-20.sql b/administrator/components/com_admin/sql/updates/mysql/3.2.3-2014-02-20.sql
new file mode 100644
index 0000000000000..0bd96df127480
--- /dev/null
+++ b/administrator/components/com_admin/sql/updates/mysql/3.2.3-2014-02-20.sql
@@ -0,0 +1 @@
+UPDATE `#__extensions` ext1, `#__extensions` ext2 SET ext1.`params` = ext2.`params` WHERE ext1.`name` = 'plg_authentication_cookie' AND ext2.`name` = 'plg_system_remember';
diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.2.3-2014-02-20.sql b/administrator/components/com_admin/sql/updates/postgresql/3.2.3-2014-02-20.sql
new file mode 100644
index 0000000000000..9f69a3f91e358
--- /dev/null
+++ b/administrator/components/com_admin/sql/updates/postgresql/3.2.3-2014-02-20.sql
@@ -0,0 +1 @@
+UPDATE "#__extensions" SET "params" = (SELECT "params" FROM "#__extensions" WHERE "name" = 'plg_system_remember') WHERE "name" = 'plg_authentication_cookie';
diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.2.3-2014-02-20.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.2.3-2014-02-20.sql
new file mode 100644
index 0000000000000..0c4ac188da3c8
--- /dev/null
+++ b/administrator/components/com_admin/sql/updates/sqlazure/3.2.3-2014-02-20.sql
@@ -0,0 +1 @@
+UPDATE [#__extensions] SET [params] = (SELECT [params] FROM [#__extensions] WHERE [name] = 'plg_system_remember') WHERE [name] = 'plg_authentication_cookie';
\ No newline at end of file
diff --git a/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini b/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini
index 3ae23c618dae6..6300798211792 100644
--- a/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini
+++ b/administrator/language/en-GB/en-GB.plg_authentication_cookie.ini
@@ -5,3 +5,9 @@
PLG_AUTH_COOKIE_XML_DESCRIPTION="Handles Joomla's cookie User authentication Warning! You must have at least one other authentication plugin enabled. You will also need a plugin such as the System - Remember Me plugin to implement cookie login."
PLG_AUTHENTICATION_COOKIE="Authentication - Cookie"
+PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_DESC="The number of days until the authentication cookie will expire. Other factors may cause it to expire before this. Longer lengths are less secure."
+PLG_AUTH_COOKIE_FIELD_COOKIE_LIFETIME_LABEL="Cookie Lifetime"
+PLG_AUTH_COOKIE_ERROR_LOG_INVALIDATED_COOKIES="The authentication tokens were invalidated for user %u because there was no matching record "
+PLG_AUTH_COOKIE_ERROR_LOG_LOGIN_FAILED="Cookie login failed for user %u"
+PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_DESC="The length of the key to use to encrypt the cookie. Longer lengths are more secure, but they will slow performance."
+PLG_AUTH_COOKIE_FIELD_KEY_LENGTH_LABEL="Key Length"
diff --git a/administrator/language/en-GB/en-GB.plg_system_remember.ini b/administrator/language/en-GB/en-GB.plg_system_remember.ini
index ff6313b5665f5..c0fff5623906d 100644
--- a/administrator/language/en-GB/en-GB.plg_system_remember.ini
+++ b/administrator/language/en-GB/en-GB.plg_system_remember.ini
@@ -5,9 +5,3 @@
PLG_REMEMBER_XML_DESCRIPTION="Provides remember me functionality. The cookie authentication plugin must be enabled for this plugin to function."
PLG_SYSTEM_REMEMBER="System - Remember Me"
-PLG_SYSTEM_REMEMBER_FIELD_COOKIE_LIFETIME_DESC="The number of days until the Remember Me cookie will expire. Other factors may cause it to expire before this. Longer lengths are less secure."
-PLG_SYSTEM_REMEMBER_FIELD_COOKIE_LIFETIME_LABEL="Cookie Lifetime"
-PLG_SYSTEM_REMEMBER_ERROR_LOG_INVALIDATED_COOKIES="The remember me tokens were invalidated for user %u because there was no matching record "
-PLG_SYSTEM_REMEMBER_ERROR_LOG_LOGIN_FAILED="Remember me login failed for user %u"
-PLG_SYSTEM_REMEMBER_FIELD_KEY_LENGTH_DESC="The length of the key to use to encrypt the cookie. Longer lengths are more secure, but they will slow performance."
-PLG_SYSTEM_REMEMBER_FIELD_KEY_LENGTH_LABEL="Key Length"
diff --git a/libraries/cms/application/cms.php b/libraries/cms/application/cms.php
index bb1a4d7a14378..ee06eb6fc3d4b 100644
--- a/libraries/cms/application/cms.php
+++ b/libraries/cms/application/cms.php
@@ -800,13 +800,6 @@ public function login($credentials, $options = array())
$options['user'] = $user;
$options['responseType'] = $response->type;
- if (isset($response->length) && isset($response->secure) && isset($response->lifetime))
- {
- $options['length'] = $response->length;
- $options['secure'] = $response->secure;
- $options['lifetime'] = $response->lifetime;
- }
-
// The user is successfully logged in. Run the after login events
$this->triggerEvent('onUserAfterLogin', array($options));
}
diff --git a/libraries/joomla/user/helper.php b/libraries/joomla/user/helper.php
index f7b38f7e84611..41316ef36f6d9 100644
--- a/libraries/joomla/user/helper.php
+++ b/libraries/joomla/user/helper.php
@@ -718,7 +718,7 @@ private static function _bin($hex)
* @return boolean True on success
*
* @since 3.2
- * @see JInput::setCookie for more details
+ * @deprecated 4.0 This is handled in the authentication plugin itself. The 'invalid' column in the db should be removed as well
*/
public static function invalidateCookie($userId, $cookieName)
{
@@ -746,6 +746,7 @@ public static function invalidateCookie($userId, $cookieName)
* @return mixed Database query result
*
* @since 3.2
+ * @deprecated 4.0 This is handled in the authentication plugin itself
*/
public static function clearExpiredTokens()
{
@@ -765,6 +766,7 @@ public static function clearExpiredTokens()
* @return mixed An array of information from an authentication cookie or false if there is no cookie
*
* @since 3.2
+ * @deprecated 4.0 This is handled in the authentication plugin itself
*/
public static function getRememberCookieData()
{
diff --git a/plugins/authentication/cookie/cookie.php b/plugins/authentication/cookie/cookie.php
index 5dcf9cf0aceb8..f484e7df1b859 100644
--- a/plugins/authentication/cookie/cookie.php
+++ b/plugins/authentication/cookie/cookie.php
@@ -15,6 +15,8 @@
* @package Joomla.Plugin
* @subpackage Authentication.cookie
* @since 3.2
+ * @note Code based on http://jaspan.com/improved_persistent_login_cookie_best_practice
+ * and http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/
*/
class PlgAuthenticationCookie extends JPlugin
{
@@ -53,35 +55,53 @@ public function onUserAuthenticate($credentials, $options, &$response)
return false;
}
- JLoader::register('JAuthentication', JPATH_LIBRARIES . '/joomla/user/authentication.php');
-
$response->type = 'Cookie';
- // We need to validate the cookie data because there may be no Remember Me plugin to do it.
- // Create the cookie name and data.
- $rememberArray = JUserHelper::getRememberCookieData();
+ // Get cookie
+ $cookieName = JUserHelper::getShortHashedUserAgent();
+
+ $cookieValue = $this->app->input->cookie->get($cookieName);
+ if (!$cookieValue)
+ {
+ return;
+ }
+
+ $cookieArray = explode('.', $cookieValue);
- if ($rememberArray == false)
+ // Check for valid cookie value
+ if (count($cookieArray) != 2)
{
+ // Destroy the cookie in the browser.
+ $this->app->input->cookie->set($cookieName, false, time() - 42000, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain'));
+ JLog::add('Invalid cookie detected.', JLog::WARNING, 'error');
+
return false;
}
- list($privateKey, $series, $uastring) = $rememberArray;
+ // Filter series since we're going to use it in the query
+ $filter = new JFilterInput;
+ $series = $filter->clean($cookieArray[1], 'ALNUM');
+
+ // Remove expired tokens
+ $query = $this->db->getQuery(true)
+ ->delete('#__user_keys')
+ ->where($this->db->quoteName('time') . ' < ' . $this->db->quote(time()));
+ $this->db->setQuery($query)->execute();
// Find the matching record if it exists.
$query = $this->db->getQuery(true)
- ->select($this->db->quoteName(array('user_id', 'token', 'series', 'time', 'invalid')))
- ->from($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('series') . ' = ' . $this->db->quote(base64_encode($series)))
- ->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($uastring))
- ->order($this->db->quoteName('time') . ' DESC');
+ ->select($this->db->quoteName(array('user_id', 'token', 'series', 'time')))
+ ->from($this->db->quoteName('#__user_keys'))
+ ->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
+ ->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))
+ ->order($this->db->quoteName('time') . ' DESC');
$results = $this->db->setQuery($query)->loadObjectList();
- $countResults = count($results);
-
- if ($countResults !== 1)
+ if (count($results) !== 1)
{
+ // Destroy the cookie in the browser.
+ $this->app->input->cookie->set($cookieName, false, time() - 42000, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain'));
$response->status = JAuthentication::STATUS_FAILURE;
return;
@@ -90,44 +110,34 @@ public function onUserAuthenticate($credentials, $options, &$response)
// We have a user with one cookie with a valid series and a corresponding record in the database.
else
{
- if (substr($results[0]->token, 0, 4) === '$2y$')
- {
- if (JCrypt::hasStrongPasswordSupport())
- {
- $match = password_verify($privateKey, $results[0]->token);
- }
- }
- else
+ $token = JUserHelper::hashPassword($cookieArray[0]);
+ if (!JUserHelper::verifyPassword($cookieArray[0], $results[0]->token))
{
- if (JCrypt::timingSafeCompare($results[0]->token, $privateKey))
- {
- $match = true;
- }
- }
+ // This is a real attack! Either the series was guessed correctly or a cookie was stolen and used twice (once by attacker and once by victim).
+ // Delete all tokens for this user!
+ $query = $this->db->getQuery(true)
+ ->delete('#__user_keys')
+ ->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($results[0]->user_id));
+ $this->db->setQuery($query)->execute();
+
+ // Destroy the cookie in the browser.
+ $this->app->input->cookie->set($cookieName, false, time() - 42000, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain'));
+
+ // Issue warning by email to user and/or admin?
+
+ JLog::add(JText::sprintf('PLG_AUTH_COOKIE_ERROR_LOG_LOGIN_FAILED', $results[0]->user_id), JLog::WARNING, 'security');
- if (empty($match))
- {
- JUserHelper::invalidateCookie($results[0]->user_id, $uastring);
- JLog::add(JText::sprintf('PLG_SYSTEM_REMEMBER_ERROR_LOG_LOGIN_FAILED', $user->username), JLog::WARNING, 'security');
$response->status = JAuthentication::STATUS_FAILURE;
return false;
}
}
- // Set cookie params.
- if (!empty($options['lifetime']) && !empty($options['length']) && !empty($options['secure']))
- {
- $response->lifetime = $options['lifetime'];
- $response->length = $options['length'];
- $response->secure = $options['secure'];
- }
-
// Make sure there really is a user with this name and get the data for the session.
$query = $this->db->getQuery(true)
->select($this->db->quoteName(array('id', 'username', 'password')))
->from($this->db->quoteName('#__users'))
- ->where($this->db->quoteName('username') . ' = ' . $this->db->quote($credentials['username']));
+ ->where($this->db->quoteName('username') . ' = ' . $this->db->quote($results[0]->user_id));
$result = $this->db->setQuery($query)->loadObject();
@@ -135,13 +145,6 @@ public function onUserAuthenticate($credentials, $options, &$response)
{
// Bring this in line with the rest of the system
$user = JUser::getInstance($result->id);
- $cookieName = JUserHelper::getShortHashedUserAgent();
-
- // If there is no cookie, bail out
- if (!$this->app->input->cookie->get($cookieName))
- {
- return;
- }
// Set response data.
$response->username = $result->username;
@@ -160,4 +163,154 @@ public function onUserAuthenticate($credentials, $options, &$response)
$response->error_message = JText::_('JGLOBAL_AUTH_NO_USER');
}
}
+
+ /**
+ * We set the authentication cookie only after login is successfullly finished.
+ * We set a new cookie either for a user with no cookies or one
+ * where the user used a cookie to authenticate.
+ *
+ * @param array options Array holding options
+ *
+ * @return boolean True on success
+ *
+ * @since 3.2
+ */
+ public function onUserAfterLogin($options)
+ {
+ // No remember me for admin
+ if ($this->app->isAdmin())
+ {
+ return false;
+ }
+
+ if (isset($options['responseType']) && $options['responseType'] == 'Cookie')
+ {
+ // Logged in using a cookie
+ $cookieName = JUserHelper::getShortHashedUserAgent();
+
+ // We need the old data to get the existing series
+ $cookieValue = $this->app->input->cookie->get($cookieName);
+ $cookieArray = explode('.', $cookieValue);
+ // Filter series since we're going to use it in the query
+ $filter = new JFilterInput;
+ $series = $filter->clean($cookieArray[1], 'ALNUM');
+ }
+ elseif (!empty($options['remember']))
+ {
+ // Remember checkbox is set
+ $cookieName = JUserHelper::getShortHashedUserAgent();
+
+ // Create an unique series which will be used over the lifespan of the cookie
+ $unique = false;
+ do
+ {
+ $series = JUserHelper::genRandomPassword(20);
+
+ $query = $this->db->getQuery(true)
+ ->select($this->db->quoteName('series'))
+ ->from($this->db->quoteName('#__user_keys'))
+ ->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series));
+
+ $results = $this->db->setQuery($query)->loadResult();
+
+ if (is_null($results))
+ {
+ $unique = true;
+ }
+ }
+ while ($unique === false);
+ }
+ else
+ {
+ return false;
+ }
+
+ // Get the parameter values
+ $lifetime = $this->params->get('cookie_lifetime', '60') * 24 * 60 * 60;
+ $length = $this->params->get('key_length', '16');
+
+ // Generate new cookie
+ $token = JUserHelper::genRandomPassword($length);
+ $cookieValue = $token . '.' . $series;
+
+ // Overwrite existing cookie with new value
+ $this->app->input->cookie->set(
+ $cookieName, $cookieValue, time() + $lifetime, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain'), $this->app->isSSLConnection()
+ );
+
+ $query = $this->db->getQuery(true);
+
+ if (!empty($options['remember']))
+ {
+ // Create new record
+ $query
+ ->insert($this->db->quoteName('#__user_keys'))
+ ->set($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
+ ->set($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
+ ->set($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))
+ ->set($this->db->quoteName('time') . ' = ' . (time() + $lifetime));
+ }
+ else
+ {
+ // Update existing record with new token
+ $query
+ ->update($this->db->quoteName('#__user_keys'))
+ ->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
+ ->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series))
+ ->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName));
+ }
+
+ $hashed_token = JUserHelper::hashPassword($token);
+ $query
+ ->set($this->db->quoteName('token') . ' = ' . $this->db->quote($hashed_token));
+
+ $this->db->setQuery($query)->execute();
+
+ return true;
+ }
+
+ /**
+ * This is where we delete any authentication cookie when a user logs out
+ *
+ * @param array $options Array holding options (length, timeToExpiration)
+ *
+ * @return boolean True on success
+ *
+ * @since 3.2
+ */
+ public function onUserAfterLogout($options)
+ {
+ // No remember me for admin
+ if ($this->app->isAdmin())
+ {
+ return false;
+ }
+
+ $cookieName = JUserHelper::getShortHashedUserAgent();
+ $cookieValue = $this->app->input->cookie->get($cookieName);
+ // There are no cookies to delete.
+ if (!$cookieValue)
+ {
+ return true;
+ }
+
+ $cookieArray = explode('.', $cookieValue);
+
+ // Filter series since we're going to use it in the query
+ $filter = new JFilterInput;
+ $series = $filter->clean($cookieArray[1], 'ALNUM');
+
+ // Remove the record from the database
+ $query = $this->db->getQuery(true);
+ $query
+ ->delete('#__user_keys')
+ ->where($this->db->quoteName('series') . ' = ' . $this->db->quote($series));
+
+ $this->db->setQuery($query)->execute();
+
+ // Destroy the cookie
+ $this->app->input->cookie->set($cookieName, false, time() - 42000, $this->app->get('cookie_path', '/'), $this->app->get('cookie_domain'));
+
+ return true;
+ }
}
diff --git a/plugins/authentication/cookie/cookie.xml b/plugins/authentication/cookie/cookie.xml
index e72b7f757f02f..42746552ac944 100644
--- a/plugins/authentication/cookie/cookie.xml
+++ b/plugins/authentication/cookie/cookie.xml
@@ -17,4 +17,30 @@
en-GB.plg_authentication_cookie.inien-GB.plg_authentication_cookie.sys.ini
+
+
+
+
+
diff --git a/plugins/system/remember/remember.php b/plugins/system/remember/remember.php
index 6aed3d02583e5..ea01fcf43dd6a 100644
--- a/plugins/system/remember/remember.php
+++ b/plugins/system/remember/remember.php
@@ -15,9 +15,8 @@
* @package Joomla.Plugin
* @subpackage System.remember
* @since 1.5
- * @note Code improvements inspired by http://jaspan.com/improved_persistent_login_cookie_best_practice
- * and http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/
*/
+
class PlgSystemRemember extends JPlugin
{
/**
@@ -29,79 +28,8 @@ class PlgSystemRemember extends JPlugin
protected $app;
/**
- * Database object.
- *
- * @var JDatabaseDriver
- * @since 3.2
- */
- protected $db;
-
- /**
- * Domain for the cookie.
- *
- * @var string
- * @since 3.2
- */
- protected $cookie_domain;
-
- /**
- * Path for the cookie.
- *
- * @var string
- * @since 3.2
- */
- protected $cookie_path;
-
- /**
- * Whether to set as secure or not.
- *
- * @var boolean
- * @since 3.2
- */
- protected $secure = false;
-
- /**
- * Cookie lifetime in days.
- *
- * @var integer
- * @since 3.2
- */
- protected $lifetime;
-
- /**
- * Length of random string.
- *
- * @var integer
- * @since 3.2
- */
- protected $length;
-
- /**
- * Constructor.
- *
- * Used to set the application and database properties.
- *
- * @param object &$subject The object to observe.
- * @param array $config An optional associative array of configuration settings.
- * Recognized key values include 'name', 'group', 'params', 'language'
- * (this list is not meant to be comprehensive).
- *
- * @since 3.2
- */
- public function __construct(&$subject, $config = array())
- {
- parent::__construct($subject, $config);
-
- // Use domain and path set in config for cookie if it exists.
- $this->cookie_domain = $this->app->get('cookie_domain', '');
- $this->cookie_path = $this->app->get('cookie_path', '/');
- $this->lifetime = time() + ($this->params->get('cookie_lifetime', '60') * 24 * 60 * 60);
- $this->secure = $this->app->isSSLConnection();
- $this->length = $this->params->get('key_length', '16');
- }
-
- /**
- * Remember me method to run onAfterInitialise.
+ * Remember me method to run onAfterInitialise
+ * Only purpose is to initialise the login authentication process if a cookie is present
*
* @return boolean
*
@@ -116,79 +44,36 @@ public function onAfterInitialise()
return false;
}
- $user = JFactory::getUser();
-
- $this->app->rememberCookieLifetime = $this->lifetime;
- $this->app->rememberCookieSecure = $this->secure;
- $this->app->rememberCookieLength = $this->length;
-
- // Check for a cookie.
- if ($user->get('guest') == 1)
+ // Check for a cookie if user is not logged in
+ if (JFactory::getUser()->get('guest'))
{
- // Create the cookie name and data.
- $rememberArray = JUserHelper::getRememberCookieData();
+ $cookieName = JUserHelper::getShortHashedUserAgent();
- if ($rememberArray !== false)
+ // Check for the cookie
+ if ($this->app->input->cookie->get($cookieName))
{
- if (count($rememberArray) != 3)
- {
- // Destroy the cookie in the browser.
- $this->app->input->cookie->set(end($rememberArray), false, time() - 42000, $this->app->get('cookie_path'), $this->app->get('cookie_domain'));
- JLog::add('Invalid cookie detected.', JLog::WARNING, 'error');
-
- return false;
- }
-
- list($privateKey, $series, $uastring) = $rememberArray;
-
- if (!JUserHelper::clearExpiredTokens($this))
- {
- JLog::add('Error in deleting expired cookie tokens.', JLog::WARNING, 'error');
- }
-
- // Find the matching record if it exists.
- $query = $this->db->getQuery(true)
- ->select($this->db->quoteName(array('user_id', 'token', 'series', 'time', 'invalid')))
- ->from($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('series') . ' = ' . $this->db->quote(base64_encode($series)))
- ->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($uastring))
- ->order($this->db->quoteName('time') . ' DESC');
-
- $results = $this->db->setQuery($query)->loadObjectList();
-
- $countResults = count($results);
-
- // We have a user but a cookie that is not in the database, or it is invalid. This is a possible attack, so invalidate everything.
- if (($countResults === 0 || $results[0]->invalid != 0) && !empty($results[0]->user_id))
- {
- JUserHelper::invalidateCookie($results[0]->user_id, $uastring);
- JLog::add(JText::sprintf('PLG_SYSTEM_REMEMBER_ERROR_LOG_INVALIDATED_COOKIES', $user->username), JLog::WARNING, 'security');
-
- // Possibly e-mail user and admin here.
- return false;
- }
+ return $this->app->login(array('username' => ''), array('silent' => true));
+ }
+ }
- // We have a user with one cookie with a valid series and a corresponding record in the database.
- if ($countResults === 1)
- {
- if (!JCrypt::timingSafeCompare($results[0]->token, $privateKey))
- {
- JUserHelper::invalidateCookie($results[0]->user_id, $uastring);
- JLog::add(JText::sprintf('PLG_SYSTEM_REMEMBER_ERROR_LOG_LOGIN_FAILED', $user->username), JLog::WARNING, 'security');
+ return false;
+ }
- return false;
- }
+ public function onUserLogout($options)
+ {
+ // No remember me for admin
+ if ($this->app->isAdmin())
+ {
+ return false;
+ }
- // Set up the credentials array to pass to onUserAuthenticate.
- $credentials = array(
- 'username' => $results[0]->user_id,
- );
+ $cookieName = JUserHelper::getShortHashedUserAgent();
- return $this->app->login($credentials, array('silent' => true, 'lifetime' => $this->lifetime, 'secure' => $this->secure, 'length' => $this->length));
- }
- }
+ // Check for the cookie
+ if ($this->app->input->cookie->get($cookieName))
+ {
+ // Make sure authentication group is loaded to process onUserAfterLogout event
+ JPluginHelper::importPlugin('authentication');
}
-
- return false;
}
}
diff --git a/plugins/system/remember/remember.xml b/plugins/system/remember/remember.xml
index 6e7e3d14df98f..10b1310f7b178 100644
--- a/plugins/system/remember/remember.xml
+++ b/plugins/system/remember/remember.xml
@@ -17,31 +17,4 @@
en-GB.plg_system_remember.inien-GB.plg_system_remember.sys.ini
-
-
-
-
-
-
diff --git a/plugins/user/joomla/joomla.php b/plugins/user/joomla/joomla.php
index 6fcbe51a44d62..da600a4964bdf 100644
--- a/plugins/user/joomla/joomla.php
+++ b/plugins/user/joomla/joomla.php
@@ -321,154 +321,4 @@ protected function _getUser($user, $options = array())
return $instance;
}
-
- /**
- * We set the authentication cookie only after login is successfullly finished.
- * We set a new cookie either for a user with no cookies or one
- * where the user used a cookie to authenticate.
- *
- * @param array $options Array holding options
- *
- * @return boolean True on success
- *
- * @since 3.2
- */
- public function onUserAfterLogin($options)
- {
- // Currently this portion of the method only applies to Cookie based login.
- if (!isset($options['responseType']) || ($options['responseType'] != 'Cookie' && empty($options['remember'])))
- {
- return true;
- }
-
- // We get the parameter values differently for cookie and non-cookie logins.
- $cookieLifetime = empty($options['lifetime']) ? $this->app->rememberCookieLifetime : $options['lifetime'];
- $length = empty($options['length']) ? $this->app->rememberCookieLength : $options['length'];
- $secure = empty($options['secure']) ? $this->app->rememberCookieSecure : $options['secure'];
-
- // We need the old data to match against the current database
- $rememberArray = JUserHelper::getRememberCookieData();
-
- $privateKey = JUserHelper::genRandomPassword($length);
-
- // We are going to concatenate with . so we need to remove it from the strings.
- $privateKey = str_replace('.', '', $privateKey);
-
- $cryptedKey = JUserHelper::getCryptedPassword($privateKey, '', 'bcrypt', false);
-
- $cookieName = JUserHelper::getShortHashedUserAgent();
-
- // Create an identifier and make sure that it is unique.
- $unique = false;
-
- do
- {
- // Unique identifier for the device-user
- $series = JUserHelper::genRandomPassword(20);
-
- // We are going to concatenate with . so we need to remove it from the strings.
- $series = str_replace('.', '', $series);
-
- $query = $this->db->getQuery(true)
- ->select($this->db->quoteName('series'))
- ->from($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('series') . ' = ' . $this->db->quote(base64_encode($series)));
-
- $results = $this->db->setQuery($query)->loadResult();
-
- if (is_null($results))
- {
- $unique = true;
- }
- }
-
- while ($unique === false);
-
- // If a user logs in with non cookie login and remember me checked we will
- // delete any invalid entries so that he or she can use remember once again.
- if ($options['responseType'] !== 'Cookie')
- {
- $query = $this->db->getQuery(true)
- ->delete('#__user_keys')
- ->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))
- ->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username));
-
- $this->db->setQuery($query)->execute();
- }
-
- $cookieValue = $cryptedKey . '.' . $series . '.' . $cookieName;
-
- // Destroy the old cookie.
- $this->app->input->cookie->set($cookieName, false, time() - 42000, $this->app->get('cookie_path'), $this->app->get('cookie_domain'));
-
- // And make a new one.
- $this->app->input->cookie->set(
- $cookieName, $cookieValue, $cookieLifetime, $this->app->get('cookie_path'), $this->app->get('cookie_domain'), $secure
- );
-
- $query = $this->db->getQuery(true);
-
- if (empty($options['user']->cookieLogin) || $options['responseType'] != 'Cookie')
- {
- // For users doing login from Joomla or other systems
- $query->insert($this->db->quoteName('#__user_keys'));
- }
- else
- {
- $query
- ->update($this->db->quoteName('#__user_keys'))
- ->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
- ->where($this->db->quoteName('series') . ' = ' . $this->db->quote(base64_encode($rememberArray[1])))
- ->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName));
- }
-
- $query
- ->set($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['user']->username))
- ->set($this->db->quoteName('time') . ' = ' . $cookieLifetime)
- ->set($this->db->quoteName('token') . ' = ' . $this->db->quote($cryptedKey))
- ->set($this->db->quoteName('series') . ' = ' . $this->db->quote(base64_encode($series)))
- ->set($this->db->quoteName('invalid') . ' = 0')
- ->set($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName));
-
- $this->db->setQuery($query)->execute();
-
- return true;
- }
-
- /**
- * This is where we delete any authentication cookie when a user logs out
- *
- * @param array $options Array holding options (length, timeToExpiration)
- *
- * @return boolean True on success
- *
- * @since 3.2
- */
- public function onUserAfterLogout($options)
- {
- $rememberArray = JUserHelper::getRememberCookieData();
-
- // There are no cookies to delete.
- if ($rememberArray === false)
- {
- return true;
- }
-
- list($privateKey, $series, $cookieName) = $rememberArray;
-
- // Remove the record from the database
- $query = $this->db->getQuery(true);
-
- $query
- ->delete('#__user_keys')
- ->where($this->db->quoteName('uastring') . ' = ' . $this->db->quote($cookieName))
- ->where($this->db->quoteName('user_id') . ' = ' . $this->db->quote($options['username']));
-
- $this->db->setQuery($query)->execute();
-
- // Destroy the cookie
- $this->app->input->cookie->set($cookieName, false, time() - 42000, $this->app->get('cookie_path'), $this->app->get('cookie_domain'));
-
- return true;
- }
}