__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
<?php

/**
 * @package     Joomla.Plugin
 * @subpackage  System.Webauthn
 *
 * @copyright   (C) 2020 Open Source Matters, Inc. <https://www.joomla.org>
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 */

namespace Joomla\Plugin\System\Webauthn\PluginTraits;

use Joomla\CMS\Authentication\Authentication;
use Joomla\CMS\Authentication\AuthenticationResponse;
use Joomla\CMS\Event\Plugin\System\Webauthn\AjaxLogin;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\User\User;
use Joomla\CMS\User\UserFactoryInterface;

// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects

/**
 * Ajax handler for akaction=login
 *
 * Verifies the response received from the browser and logs in the user
 *
 * @since  4.0.0
 */
trait AjaxHandlerLogin
{
    /**
     * Returns the public key set for the user and a unique challenge in a Public Key Credential Request encoded as
     * JSON.
     *
     * @param   AjaxLogin  $event  The event we are handling
     *
     * @return  void
     *
     * @since   4.0.0
     */
    public function onAjaxWebauthnLogin(AjaxLogin $event): void
    {
        // Load plugin language files
        $this->loadLanguage();

        $session   = $this->getApplication()->getSession();
        $returnUrl = $session->get('plg_system_webauthn.returnUrl', Uri::base());
        $userId    = $session->get('plg_system_webauthn.userId', 0);

        try {
            $credentialRepository = $this->authenticationHelper->getCredentialsRepository();

            // No user ID: no username was provided and the resident credential refers to an unknown user handle. DIE!
            if (empty($userId)) {
                Log::add('Cannot determine the user ID', Log::NOTICE, 'webauthn.system');

                throw new \RuntimeException(Text::_('PLG_SYSTEM_WEBAUTHN_ERR_CREATE_INVALID_LOGIN_REQUEST'));
            }

            // Do I have a valid user?
            $user = Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById($userId);

            if ($user->id != $userId) {
                $message = \sprintf('User #%d does not exist', $userId);
                Log::add($message, Log::NOTICE, 'webauthn.system');

                throw new \RuntimeException(Text::_('PLG_SYSTEM_WEBAUTHN_ERR_CREATE_INVALID_LOGIN_REQUEST'));
            }

            // Validate the authenticator response and get the user handle
            $userHandle           = $this->getUserHandleFromResponse($user);

            if (\is_null($userHandle)) {
                Log::add('Cannot retrieve the user handle from the request; the browser did not assert our request.', Log::NOTICE, 'webauthn.system');

                throw new \RuntimeException(Text::_('PLG_SYSTEM_WEBAUTHN_ERR_CREATE_INVALID_LOGIN_REQUEST'));
            }

            // Does the user handle match the user ID? This should never trigger by definition of the login check.
            $validUserHandle = $credentialRepository->getHandleFromUserId($userId);

            if ($userHandle != $validUserHandle) {
                $message = \sprintf('Invalid user handle; expected %s, got %s', $validUserHandle, $userHandle);
                Log::add($message, Log::NOTICE, 'webauthn.system');

                throw new \RuntimeException(Text::_('PLG_SYSTEM_WEBAUTHN_ERR_CREATE_INVALID_LOGIN_REQUEST'));
            }

            // Make sure the user exists
            $user = Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById($userId);

            if ($user->id != $userId) {
                $message = \sprintf('Invalid user ID; expected %d, got %d', $userId, $user->id);
                Log::add($message, Log::NOTICE, 'webauthn.system');

                throw new \RuntimeException(Text::_('PLG_SYSTEM_WEBAUTHN_ERR_CREATE_INVALID_LOGIN_REQUEST'));
            }

            // Login the user
            Log::add("Logging in the user", Log::INFO, 'webauthn.system');
            $this->loginUser((int) $userId);
        } catch (\Throwable $e) {
            $session->set('plg_system_webauthn.publicKeyCredentialRequestOptions', null);

            $response                = $this->getAuthenticationResponseObject();
            $response->status        = Authentication::STATUS_UNKNOWN;
            $response->error_message = $e->getMessage();

            Log::add(\sprintf("Received login failure. Message: %s", $e->getMessage()), Log::ERROR, 'webauthn.system');

            // This also enqueues the login failure message for display after redirection. Look for JLog in that method.
            $this->processLoginFailure($response);
        } finally {
            /**
             * This code needs to run no matter if the login succeeded or failed. It prevents replay attacks and takes
             * the user back to the page they started from.
             */

            // Remove temporary information for security reasons
            $session->set('plg_system_webauthn.publicKeyCredentialRequestOptions', null);
            $session->set('plg_system_webauthn.returnUrl', null);
            $session->set('plg_system_webauthn.userId', null);

            // Redirect back to the page we were before.
            $this->getApplication()->redirect($returnUrl);
        }
    }

    /**
     * Logs in a user to the site, bypassing the authentication plugins.
     *
     * @param   int   $userId   The user ID to log in
     *
     * @return  void
     * @throws  \Exception
     * @since   4.2.0
     */
    private function loginUser(int $userId): void
    {
        // Trick the class auto-loader into loading the necessary classes
        class_exists('Joomla\\CMS\\Authentication\\Authentication', true);

        // Fake a successful login message
        $isAdmin = $this->getApplication()->isClient('administrator');
        $user    = Factory::getContainer()->get(UserFactoryInterface::class)->loadUserById($userId);

        // Does the user account have a pending activation?
        if (!empty($user->activation)) {
            throw new \RuntimeException(Text::_('JGLOBAL_AUTH_ACCESS_DENIED'));
        }

        // Is the user account blocked?
        if ($user->block) {
            throw new \RuntimeException(Text::_('JGLOBAL_AUTH_ACCESS_DENIED'));
        }

        $statusSuccess = Authentication::STATUS_SUCCESS;

        $response                = $this->getAuthenticationResponseObject();
        $response->status        = $statusSuccess;
        $response->username      = $user->username;
        $response->fullname      = $user->name;
        $response->error_message = '';
        $response->language      = $user->getParam('language');
        $response->type          = 'Passwordless';

        if ($isAdmin) {
            $response->language = $user->getParam('admin_language');
        }

        /**
         * Set up the login options.
         *
         * The 'remember' element forces the use of the Remember Me feature when logging in with Webauthn, as the
         * users would expect.
         *
         * The 'action' element is actually required by plg_user_joomla. It is the core ACL action the logged in user
         * must be allowed for the login to succeed. Please note that front-end and back-end logins use a different
         * action. This allows us to provide the WebAuthn button on both front- and back-end and be sure that if a
         * used with no backend access tries to use it to log in Joomla! will just slap him with an error message about
         * insufficient privileges - the same thing that'd happen if you tried to use your front-end only username and
         * password in a back-end login form.
         */
        $options = [
            'remember' => true,
            'action'   => 'core.login.site',
        ];

        if ($isAdmin) {
            $options['action'] = 'core.login.admin';
        }

        // Run the user plugins. They CAN block login by returning boolean false and setting $response->error_message.
        $dispatcher = $this->getApplication()->getDispatcher();

        PluginHelper::importPlugin('user', null, true, $dispatcher);

        $event   = new \Joomla\CMS\Event\User\LoginEvent(
            'onUserLogin',
            [
                'options' => $options,
                'subject' => (array) $response,
            ]
        );
        $result  = $dispatcher->dispatch('onUserLogin', $event);
        $results = !isset($result['result']) || \is_null($result['result']) ? [] : $result['result'];

        // If there is no boolean FALSE result from any plugin the login is successful.
        if (\in_array(false, $results, true) === false) {
            // Set the user in the session, letting Joomla! know that we are logged in.
            $this->getApplication()->getSession()->set('user', $user);

            // Trigger the onUserAfterLogin event
            $options['user']         = $user;
            $options['responseType'] = $response->type;

            // The user is successfully logged in. Run the after login events
            $event = new \Joomla\CMS\Event\User\AfterLoginEvent(
                'onUserAfterLogin',
                [
                    'options' => $options,
                    'subject' => (array) $response,
                ]
            );
            $dispatcher->dispatch($event->getName(), $event);

            return;
        }

        // If we are here the plugins marked a login failure. Trigger the onUserLoginFailure Event.
        $event = new \Joomla\CMS\Event\User\LoginFailureEvent(
            'onUserLoginFailure',
            [
                'options' => $options,
                'subject' => (array) $response,
            ]
        );
        $dispatcher->dispatch('onUserLoginFailure', $event);

        // Log the failure
        Log::add($response->error_message, Log::WARNING, 'jerror');

        // Throw an exception to let the caller know that the login failed
        throw new \RuntimeException($response->error_message);
    }

    /**
     * Returns a (blank) Joomla! authentication response
     *
     * @return  AuthenticationResponse
     *
     * @since   4.2.0
     */
    private function getAuthenticationResponseObject(): AuthenticationResponse
    {
        // Force the class auto-loader to load the JAuthentication class
        class_exists('Joomla\\CMS\\Authentication\\Authentication', true);

        return new AuthenticationResponse();
    }

    /**
     * Have Joomla! process a login failure
     *
     * @param   AuthenticationResponse   $response   The Joomla! auth response object
     *
     * @return  boolean
     *
     * @since   4.2.0
     */
    private function processLoginFailure(AuthenticationResponse $response): bool
    {
        // Import the user plugin group.
        PluginHelper::importPlugin('user');

        // Trigger onUserLoginFailure Event.
        Log::add('Calling onUserLoginFailure plugin event', Log::INFO, 'plg_system_webauthn');

        $eventClassName = self::getEventClassByEventName('onUserLoginFailure');
        $event          = new $eventClassName('onUserLoginFailure', [(array) $response]);
        $this->getApplication()->getDispatcher()->dispatch($event->getName(), $event);

        // If status is success, any error will have been raised by the user plugin
        $expectedStatus = Authentication::STATUS_SUCCESS;

        if ($response->status !== $expectedStatus) {
            Log::add('The login failure has been logged in Joomla\'s error log', Log::INFO, 'webauthn.system');

            // Everything logged in the 'jerror' category ends up being enqueued in the application message queue.
            Log::add($response->error_message, Log::WARNING, 'jerror');
        } else {
            $message = 'A login failure was caused by a third party user plugin but it did not return any' .
                'further information.';
            Log::add($message, Log::WARNING, 'webauthn.system');
        }

        return false;
    }

    /**
     * Validate the authenticator response sent to us by the browser.
     *
     * @param   User  $user  The user we are trying to log in.
     *
     * @return  string|null  The user handle or null
     *
     * @throws  \Exception
     * @since   4.2.0
     */
    private function getUserHandleFromResponse(User $user): ?string
    {
        // Retrieve data from the request and session
        $pubKeyCredentialSource = $this->authenticationHelper->validateAssertionResponse(
            $this->getApplication()->getInput()->getBase64('data', ''),
            $user
        );

        return $pubKeyCredentialSource ? $pubKeyCredentialSource->getUserHandle() : null;
    }
}

Filemanager

Name Type Size Permission Actions
AdditionalLoginButtons.php File 6.23 KB 0664
AjaxHandler.php File 6.88 KB 0664
AjaxHandlerChallenge.php File 3.17 KB 0664
AjaxHandlerCreate.php File 4.72 KB 0664
AjaxHandlerDelete.php File 2.25 KB 0664
AjaxHandlerInitCreate.php File 1.81 KB 0664
AjaxHandlerLogin.php File 12.52 KB 0664
AjaxHandlerSaveLabel.php File 2.51 KB 0664
EventReturnAware.php File 1.23 KB 0664
UserDeletion.php File 2.14 KB 0664
UserProfileFields.php File 7.26 KB 0664
Filemanager