Files
carpseeds.pl/wp-content/plugins/akeebabackupwp/app/Solo/Application/UserAuthenticationGoogle.php
2024-07-15 11:28:08 +02:00

134 lines
3.5 KiB
PHP

<?php
/**
* @package solo
* @copyright Copyright (c)2014-2022 Nicholas K. Dionysopoulos / Akeeba Ltd
* @license GNU General Public License version 3, or later
*/
namespace Solo\Application;
use Awf\Encrypt\Totp;
class UserAuthenticationGoogle extends UserAuthenticationOtep
{
/**
* Is this user authenticated by this object? The $params array contains at least one key, 'password'.
*
* @param array $params The parameters used in the authentication process
*
* @return boolean True if the user is authenticated (or this plugin doesn't apply), false otherwise
*/
public function onAuthentication($params = array())
{
$result = true;
$userParams = $this->user->getParameters();
if ($userParams->get('tfa.method', 'none') == 'google')
{
$result = false;
$secret = isset($params['secret']) ? $params['secret'] : '';
if (!empty($secret))
{
$result = $this->validateGoogleOTP($secret);
if (!$result)
{
$result = $this->validateOtep($secret);
}
}
}
return $result;
}
public function onTfaSave($tfaParams)
{
$tfaMethod = isset($tfaParams['method']) ? $tfaParams['method'] : '';
if ($tfaMethod == 'google')
{
// The Google Authenticator key set by the user in the form
$newKey = isset($tfaParams['google']) ? $tfaParams['google'] : '';
// The Google Authenticator key in the user object
$oldKey = $this->user->getParameters()->get('tfa.google', '');
// The Google Authenticator generated secret code given in the form
$secret = isset($tfaParams['secret']) ? $tfaParams['secret'] : '';
// What was the old TFA method?
$oldTfaMethod = $this->user->getParameters()->get('tfa.method');
if (($oldTfaMethod == 'google') && ($newKey == $oldKey))
{
// We had already set up Google Authenticator and the code is unchanged. No change performed here.
return true;
}
else
{
// Safe fallback until we can verify the new yubikey
$this->user->getParameters()->set('tfa', null);
$this->user->getParameters()->set('tfa.method', 'none');
if (!empty($secret) && $this->validateGoogleOTP($secret, $newKey))
{
$this->user->getParameters()->set('tfa.method', 'google');
$this->user->getParameters()->set('tfa.google', $newKey);
}
}
}
return true;
}
/**
* Validates a Google Authenticator key
*
* @param string $otp The OTP generated by Google Authenticator
* @param string $key The TOTP key (base32 encoded)
*
* @return boolean True if it's a valid OTP
*/
public function validateGoogleOTP($otp, $key = null)
{
// Create a new TOTP class with Google Authenticator compatible settings
$totp = new Totp(30, 6, 10);
// Get the key if none is defined
if (empty($key))
{
$key = $this->user->getParameters()->get('tfa.google', '');
}
// Check the code
$code = $totp->getCode($key);
$check = $code == $otp;
/*
* If the check fails, test the previous 30 second slot. This allow the
* user to enter the security code when it's becoming red in Google
* Authenticator app (reaching the end of its 30 second lifetime)
*/
if (!$check)
{
$time = time() - 30;
$code = $totp->getCode($key, $time);
$check = $code == $otp;
}
/*
* If the check fails, test the next 30 second slot. This allows some
* time drift between the authentication device and the server
*/
if (!$check)
{
$time = time() + 30;
$code = $totp->getCode($key, $time);
$check = $code == $otp;
}
return $check;
}
}