Application.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. /**
  3. * Second authentication factor handling
  4. */
  5. declare(strict_types=1);
  6. namespace PhpMyAdmin\Plugins\TwoFactor;
  7. use BaconQrCode\Renderer\Image\SvgImageBackEnd;
  8. use PhpMyAdmin\Plugins\TwoFactorPlugin;
  9. use PhpMyAdmin\TwoFactor;
  10. use PragmaRX\Google2FA\Exceptions\IncompatibleWithGoogleAuthenticatorException;
  11. use PragmaRX\Google2FA\Exceptions\InvalidCharactersException;
  12. use PragmaRX\Google2FA\Exceptions\SecretKeyTooShortException;
  13. use PragmaRX\Google2FAQRCode\Google2FA;
  14. use function extension_loaded;
  15. /**
  16. * HOTP and TOTP based two-factor authentication
  17. *
  18. * Also known as Google, Authy, or OTP
  19. */
  20. class Application extends TwoFactorPlugin
  21. {
  22. /** @var string */
  23. public static $id = 'application';
  24. /** @var Google2FA */
  25. protected $google2fa;
  26. /**
  27. * Creates object
  28. *
  29. * @param TwoFactor $twofactor TwoFactor instance
  30. */
  31. public function __construct(TwoFactor $twofactor)
  32. {
  33. parent::__construct($twofactor);
  34. if (extension_loaded('imagick')) {
  35. $this->google2fa = new Google2FA();
  36. } else {
  37. $this->google2fa = new Google2FA(new SvgImageBackEnd());
  38. }
  39. $this->google2fa->setWindow(8);
  40. if (isset($this->twofactor->config['settings']['secret'])) {
  41. return;
  42. }
  43. $this->twofactor->config['settings']['secret'] = '';
  44. }
  45. public function getGoogle2fa(): Google2FA
  46. {
  47. return $this->google2fa;
  48. }
  49. /**
  50. * Checks authentication, returns true on success
  51. *
  52. * @return bool
  53. *
  54. * @throws IncompatibleWithGoogleAuthenticatorException
  55. * @throws InvalidCharactersException
  56. * @throws SecretKeyTooShortException
  57. */
  58. public function check()
  59. {
  60. $this->provided = false;
  61. if (! isset($_POST['2fa_code'])) {
  62. return false;
  63. }
  64. $this->provided = true;
  65. return $this->google2fa->verifyKey(
  66. $this->twofactor->config['settings']['secret'],
  67. $_POST['2fa_code']
  68. );
  69. }
  70. /**
  71. * Renders user interface to enter two-factor authentication
  72. *
  73. * @return string HTML code
  74. */
  75. public function render()
  76. {
  77. return $this->template->render('login/twofactor/application');
  78. }
  79. /**
  80. * Renders user interface to configure two-factor authentication
  81. *
  82. * @return string HTML code
  83. */
  84. public function setup()
  85. {
  86. $secret = $this->twofactor->config['settings']['secret'];
  87. $inlineUrl = $this->google2fa->getQRCodeInline(
  88. 'phpMyAdmin (' . $this->getAppId(false) . ')',
  89. $this->twofactor->user,
  90. $secret
  91. );
  92. return $this->template->render('login/twofactor/application_configure', [
  93. 'image' => $inlineUrl,
  94. 'secret' => $secret,
  95. 'has_imagick' => extension_loaded('imagick'),
  96. ]);
  97. }
  98. /**
  99. * Performs backend configuration
  100. *
  101. * @return bool
  102. *
  103. * @throws IncompatibleWithGoogleAuthenticatorException
  104. * @throws InvalidCharactersException
  105. * @throws SecretKeyTooShortException
  106. */
  107. public function configure()
  108. {
  109. if (! isset($_SESSION['2fa_application_key'])) {
  110. $_SESSION['2fa_application_key'] = $this->google2fa->generateSecretKey();
  111. }
  112. $this->twofactor->config['settings']['secret'] = $_SESSION['2fa_application_key'];
  113. $result = $this->check();
  114. if ($result) {
  115. unset($_SESSION['2fa_application_key']);
  116. }
  117. return $result;
  118. }
  119. /**
  120. * Get user visible name
  121. *
  122. * @return string
  123. */
  124. public static function getName()
  125. {
  126. return __('Authentication Application (2FA)');
  127. }
  128. /**
  129. * Get user visible description
  130. *
  131. * @return string
  132. */
  133. public static function getDescription()
  134. {
  135. return __(
  136. 'Provides authentication using HOTP and TOTP applications such as FreeOTP, Google Authenticator or Authy.'
  137. );
  138. }
  139. }