From 04d6d5ca99ebfd1cebb8ce06618fb3811fc1a8aa Mon Sep 17 00:00:00 2001 From: Charles Date: Thu, 9 Jan 2020 10:55:03 +0100 Subject: phpmyadmin working --- .../src/Exceptions/Contracts/Google2FA.php | 7 + .../IncompatibleWithGoogleAuthenticator.php | 7 + .../src/Exceptions/Contracts/InvalidCharacters.php | 7 + .../src/Exceptions/Contracts/SecretKeyTooShort.php | 7 + .../src/Exceptions/Google2FAException.php | 10 + ...ncompatibleWithGoogleAuthenticatorException.php | 12 + .../src/Exceptions/InvalidCharactersException.php | 12 + .../src/Exceptions/SecretKeyTooShortException.php | 12 + .../vendor/pragmarx/google2fa/src/Google2FA.php | 418 +++++++++++++++++++++ .../pragmarx/google2fa/src/Support/Base32.php | 202 ++++++++++ .../pragmarx/google2fa/src/Support/Constants.php | 21 ++ .../pragmarx/google2fa/src/Support/QRCode.php | 28 ++ .../vendor/pragmarx/google2fa/src/Support/Url.php | 22 ++ 13 files changed, 765 insertions(+) create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/Contracts/Google2FA.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/Contracts/IncompatibleWithGoogleAuthenticator.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/Contracts/InvalidCharacters.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/Contracts/SecretKeyTooShort.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/Google2FAException.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/IncompatibleWithGoogleAuthenticatorException.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/InvalidCharactersException.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/SecretKeyTooShortException.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Google2FA.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/Base32.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/Constants.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/QRCode.php create mode 100644 srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/Url.php (limited to 'srcs/phpmyadmin/vendor/pragmarx/google2fa/src') diff --git a/srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/Contracts/Google2FA.php b/srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/Contracts/Google2FA.php new file mode 100644 index 0000000..b9d5c15 --- /dev/null +++ b/srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Exceptions/Contracts/Google2FA.php @@ -0,0 +1,7 @@ +getWindow($window); + $startingTimestamp++ + ) { + if ( + hash_equals($this->oathHotp($secret, $startingTimestamp), $key) + ) { + return $oldTimestamp === Constants::ARGUMENT_NOT_SET + ? true + : $startingTimestamp; + } + } + + return false; + } + + /** + * Generate a digit secret key in base32 format. + * + * @param int $length + * @param string $prefix + * + * @throws Exceptions\InvalidCharactersException + * @throws Exceptions\IncompatibleWithGoogleAuthenticatorException + * + * @return string + */ + public function generateSecretKey($length = 16, $prefix = '') + { + return $this->generateBase32RandomKey($length, $prefix); + } + + /** + * Get the current one time password for a key. + * + * @param $secret + * + * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException + * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException + * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException + * + * @return string + */ + public function getCurrentOtp($secret) + { + return $this->oathHotp($secret, $this->getTimestamp()); + } + + /** + * Get key regeneration. + * + * @return mixed + */ + public function getKeyRegeneration() + { + return $this->keyRegeneration; + } + + /** + * Get OTP length. + * + * @return mixed + */ + public function getOneTimePasswordLength() + { + return $this->oneTimePasswordLength; + } + + /** + * Get secret. + * + * @param string|null $secret + * + * @return mixed + */ + public function getSecret($secret = null) + { + return is_null($secret) ? $this->secret : $secret; + } + + /** + * Returns the current Unix Timestamp divided by the $keyRegeneration + * period. + * + * @return int + **/ + public function getTimestamp() + { + return (int) floor(microtime(true) / $this->keyRegeneration); + } + + /** + * Get the OTP window. + * + * @param null|int $window + * + * @return mixed + */ + public function getWindow($window = null) + { + return is_null($window) ? $this->window : $window; + } + + /** + * Make a window based starting timestamp. + * + * @param $window + * @param $timestamp + * @param $oldTimestamp + * + * @return mixed + */ + private function makeStartingTimestamp($window, $timestamp, $oldTimestamp) + { + return $oldTimestamp === Constants::ARGUMENT_NOT_SET + ? $timestamp - $this->getWindow($window) + : max($timestamp - $this->getWindow($window), $oldTimestamp + 1); + } + + /** + * Get/use a starting timestamp for key verification. + * + * @param string|int|null $timestamp + * + * @return int + */ + protected function makeTimestamp($timestamp = null) + { + if (is_null($timestamp)) { + return $this->getTimestamp(); + } + + return (int) $timestamp; + } + + /** + * Takes the secret key and the timestamp and returns the one time + * password. + * + * @param string $secret - Secret key in binary form. + * @param int $counter - Timestamp as returned by getTimestamp. + * + * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException + * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException + * @throws Exceptions\IncompatibleWithGoogleAuthenticatorException + * + * @return string + */ + public function oathHotp($secret, $counter) + { + $secret = $this->base32Decode($this->getSecret($secret)); + + if (strlen($secret) < 8) { + throw new SecretKeyTooShortException(); + } + + // Counter must be 64-bit int + $bin_counter = pack('N*', 0, $counter); + + $hash = hash_hmac('sha1', $bin_counter, $secret, true); + + return str_pad( + $this->oathTruncate($hash), + $this->getOneTimePasswordLength(), + '0', + STR_PAD_LEFT + ); + } + + /** + * Extracts the OTP from the SHA1 hash. + * + * @param string $hash + * + * @return int + **/ + public function oathTruncate($hash) + { + $offset = ord($hash[19]) & 0xf; + + $temp = unpack('N', substr($hash, $offset, 4)); + + return substr( + $temp[1] & 0x7fffffff, + -$this->getOneTimePasswordLength() + ); + } + + /** + * Remove invalid chars from a base 32 string. + * + * @param $string + * + * @return mixed + */ + public function removeInvalidChars($string) + { + return preg_replace( + '/[^' . Constants::VALID_FOR_B32 . ']/', + '', + $string + ); + } + + /** + * Setter for the enforce Google Authenticator compatibility property. + * + * @param mixed $enforceGoogleAuthenticatorCompatibility + * + * @return $this + */ + public function setEnforceGoogleAuthenticatorCompatibility( + $enforceGoogleAuthenticatorCompatibility + ) { + $this->enforceGoogleAuthenticatorCompatibility = $enforceGoogleAuthenticatorCompatibility; + + return $this; + } + + /** + * Set key regeneration. + * + * @param mixed $keyRegeneration + */ + public function setKeyRegeneration($keyRegeneration) + { + $this->keyRegeneration = $keyRegeneration; + } + + /** + * Set OTP length. + * + * @param mixed $oneTimePasswordLength + */ + public function setOneTimePasswordLength($oneTimePasswordLength) + { + $this->oneTimePasswordLength = $oneTimePasswordLength; + } + + /** + * Set secret. + * + * @param mixed $secret + */ + public function setSecret($secret) + { + $this->secret = $secret; + } + + /** + * Set the OTP window. + * + * @param mixed $window + */ + public function setWindow($window) + { + $this->window = $window; + } + + /** + * Verifies a user inputted key against the current timestamp. Checks $window + * keys either side of the timestamp. + * + * @param string $key - User specified key + * @param null|string $secret + * @param null|int $window + * @param null|int $timestamp + * @param null|string|int $oldTimestamp + * + * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException + * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException + * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException + * + * @return bool|int + */ + public function verify( + $key, + $secret = null, + $window = null, + $timestamp = null, + $oldTimestamp = Constants::ARGUMENT_NOT_SET + ) { + return $this->verifyKey( + $secret, + $key, + $window, + $timestamp, + $oldTimestamp + ); + } + + /** + * Verifies a user inputted key against the current timestamp. Checks $window + * keys either side of the timestamp. + * + * @param string $secret + * @param string $key - User specified key + * @param null|int $window + * @param null|int $timestamp + * @param null|string|int $oldTimestamp + * + * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException + * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException + * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException + * + * @return bool|int + */ + public function verifyKey( + $secret, + $key, + $window = null, + $timestamp = null, + $oldTimestamp = Constants::ARGUMENT_NOT_SET + ) { + $timestamp = $this->makeTimestamp($timestamp); + + return $this->findValidOTP( + $secret, + $key, + $window, + $this->makeStartingTimestamp($window, $timestamp, $oldTimestamp), + $timestamp, + $oldTimestamp + ); + } + + /** + * Verifies a user inputted key against the current timestamp. Checks $window + * keys either side of the timestamp, but ensures that the given key is newer than + * the given oldTimestamp. Useful if you need to ensure that a single key cannot + * be used twice. + * + * @param string $secret + * @param string $key - User specified key + * @param int $oldTimestamp - The timestamp from the last verified key + * @param int|null $window + * @param int|null $timestamp + * + * @throws \PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException + * @throws \PragmaRX\Google2FA\Exceptions\InvalidCharactersException + * @throws \PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException + * + * @return bool|int - false (not verified) or the timestamp of the verified key + */ + public function verifyKeyNewer( + $secret, + $key, + $oldTimestamp, + $window = null, + $timestamp = null + ) { + return $this->verifyKey( + $secret, + $key, + $window, + $timestamp, + $oldTimestamp + ); + } +} diff --git a/srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/Base32.php b/srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/Base32.php new file mode 100644 index 0000000..ce5cbb6 --- /dev/null +++ b/srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/Base32.php @@ -0,0 +1,202 @@ +toBase32($prefix) : ''; + + $secret = $this->strPadBase32($secret, $length); + + $this->validateSecret($secret); + + return $secret; + } + + /** + * Decodes a base32 string into a binary string. + * + * @param string $b32 + * + * @throws InvalidCharactersException + * @throws IncompatibleWithGoogleAuthenticatorException + * + * @return int + */ + public function base32Decode($b32) + { + $b32 = strtoupper($b32); + + $this->validateSecret($b32); + + return ParagonieBase32::decodeUpper($b32); + } + + /** + * Check if the string length is power of two. + * + * @param $b32 + * @return bool + */ + protected function isCharCountNotAPowerOfTwo($b32): bool + { + return (strlen($b32) & (strlen($b32) - 1)) !== 0; + } + + /** + * Pad string with random base 32 chars. + * + * @param $string + * @param $length + * + * @throws \Exception + * + * @return string + */ + private function strPadBase32($string, $length) + { + for ($i = 0; $i < $length; $i++) { + $string .= substr( + Constants::VALID_FOR_B32_SCRAMBLED, + $this->getRandomNumber(), + 1 + ); + } + + return $string; + } + + /** + * Encode a string to Base32. + * + * @param $string + * + * @return mixed + */ + public function toBase32($string) + { + $encoded = ParagonieBase32::encodeUpper($string); + + return str_replace('=', '', $encoded); + } + + /** + * Get a random number. + * + * @param $from + * @param $to + * + * @throws \Exception + * + * @return int + */ + protected function getRandomNumber($from = 0, $to = 31) + { + return random_int($from, $to); + } + + /** + * Validate the secret. + * + * @param $b32 + * + * @throws IncompatibleWithGoogleAuthenticatorException + * @throws InvalidCharactersException + */ + protected function validateSecret($b32) + { + $this->checkForValidCharacters($b32); + + $this->checkGoogleAuthenticatorCompatibility($b32); + + $this->checkIsBigEnough($b32); + } + + /** + * Check if the secret key is compatible with Google Authenticator. + * + * @param $b32 + * + * @throws IncompatibleWithGoogleAuthenticatorException + */ + protected function checkGoogleAuthenticatorCompatibility($b32) + { + if ( + $this->enforceGoogleAuthenticatorCompatibility && + $this->isCharCountNotAPowerOfTwo($b32) // Google Authenticator requires it to be a power of 2 base32 length string + ) { + throw new IncompatibleWithGoogleAuthenticatorException(); + } + } + + /** + * Check if all secret key characters are valid. + * + * @param $b32 + * + * @throws InvalidCharactersException + */ + protected function checkForValidCharacters($b32) + { + if ( + preg_replace('/[^' . Constants::VALID_FOR_B32 . ']/', '', $b32) !== + $b32 + ) { + throw new InvalidCharactersException(); + } + } + + /** + * Check if secret key length is big enough + * + * @param $b32 + * + * @throws InvalidCharactersException + */ + protected function checkIsBigEnough($b32) + { + // Minimum = 128 bits + // Recommended = 160 bits + // Compatible with Google Authenticator = 256 bits + + if ( + $this->charCountBits($b32) < 128 + ) { + throw new SecretKeyTooShortException(); + } + } +} diff --git a/srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/Constants.php b/srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/Constants.php new file mode 100644 index 0000000..ba37e62 --- /dev/null +++ b/srcs/phpmyadmin/vendor/pragmarx/google2fa/src/Support/Constants.php @@ -0,0 +1,21 @@ +