http
2 weeks ago
integrations
2 weeks ago
mfa
2 weeks ago
mfa-flow
2 weeks ago
AdminNoticesController.php
2 weeks ago
Ajax.php
2 weeks ago
CloudApp.php
2 weeks ago
Config.php
2 weeks ago
Helpers.php
2 weeks ago
LimitLoginAttempts.php
2 weeks ago
LoginFlowTransientStore.php
2 weeks ago
MfaConstants.php
2 weeks ago
Shortcodes.php
2 weeks ago
MfaConstants.php
122 lines
| 1 | <?php |
| 2 | |
| 3 | namespace LLAR\Core; |
| 4 | |
| 5 | if ( ! defined( 'ABSPATH' ) ) { |
| 6 | exit; |
| 7 | } |
| 8 | |
| 9 | /** |
| 10 | * MFA Constants |
| 11 | * Facade for MFA constants defined in limit-login-attempts-reloaded.php (LLA_MFA_*). |
| 12 | */ |
| 13 | class MfaConstants { |
| 14 | /** @var int Length of each rescue code (characters) */ |
| 15 | const CODE_LENGTH = LLA_MFA_CODE_LENGTH; |
| 16 | |
| 17 | /** @var int Number of rescue codes to generate */ |
| 18 | const CODE_COUNT = LLA_MFA_CODE_COUNT; |
| 19 | |
| 20 | /** @var int Length of new rescue link token (base62). */ |
| 21 | const RESCUE_TOKEN_LENGTH = LLA_MFA_RESCUE_TOKEN_LENGTH; |
| 22 | |
| 23 | /** @var int Rescue link transient TTL in seconds (default: LLA_MFA_RESCUE_LINK_TTL, typically 10 years). One-time use is enforced by consuming the payload, not by this TTL expiring first. */ |
| 24 | const RESCUE_LINK_TTL = LLA_MFA_RESCUE_LINK_TTL; |
| 25 | |
| 26 | /** |
| 27 | * Show mfa-recovery-links-expired notice when max rescue transient expiry is within this many seconds |
| 28 | * (e.g. 5 days). If LLA_MFA_RESCUE_LINK_TTL is very long, the "missing payload" branch is the main |
| 29 | * practical case for regeneration; the near-expiry branch matters late in the TTL window. |
| 30 | */ |
| 31 | const RESCUE_NOTICE_THRESHOLD = LLA_MFA_RESCUE_NOTICE_THRESHOLD; |
| 32 | |
| 33 | /** @var string Transient key for cached MAX(transient_timeout) query used by the admin notice (avoid repeated LIKE scans on wp_options). */ |
| 34 | const RESCUE_MAX_EXPIRY_CACHE_KEY = 'llar_mfa_rescue_max_expiry_v1'; |
| 35 | |
| 36 | /** @var int Cache TTL in seconds for RESCUE_MAX_EXPIRY_CACHE_KEY. */ |
| 37 | const RESCUE_MAX_EXPIRY_CACHE_TTL = 120; |
| 38 | |
| 39 | /** @var int MFA temporary disable duration in seconds (1 hour) */ |
| 40 | const MFA_DISABLE_DURATION = LLA_MFA_DISABLE_DURATION; |
| 41 | |
| 42 | /** @var int Rate limiting period for rescue attempts (1 hour). @deprecated Use RESCUE_USE_COOLDOWN for rescue endpoint. */ |
| 43 | const RATE_LIMIT_PERIOD = LLA_MFA_RATE_LIMIT_PERIOD; |
| 44 | |
| 45 | /** |
| 46 | * @var int Kept for wp-config / backward compatibility. Global post-success rescue cooldown was removed; |
| 47 | * protection is one-time transients and per-code used flags. |
| 48 | */ |
| 49 | const RESCUE_USE_COOLDOWN = LLA_MFA_RESCUE_USE_COOLDOWN; |
| 50 | |
| 51 | /** @var string Transient key prefix for rescue codes */ |
| 52 | const TRANSIENT_RESCUE_PREFIX = LLA_MFA_TRANSIENT_RESCUE_PREFIX; |
| 53 | |
| 54 | /** |
| 55 | * @var string Transient name reserved in wp-config; no longer set by the plugin (legacy global cooldown removed). |
| 56 | */ |
| 57 | const TRANSIENT_RESCUE_LAST_USE = LLA_MFA_TRANSIENT_RESCUE_LAST_USE; |
| 58 | |
| 59 | /** @var string Transient key for MFA temporary disable */ |
| 60 | const TRANSIENT_MFA_DISABLED = LLA_MFA_TRANSIENT_MFA_DISABLED; |
| 61 | |
| 62 | /** @var string Transient key for MFA checkbox state */ |
| 63 | const TRANSIENT_CHECKBOX_STATE = LLA_MFA_TRANSIENT_CHECKBOX_STATE; |
| 64 | |
| 65 | /** @var int Checkbox state TTL in seconds (5 minutes) */ |
| 66 | const CHECKBOX_STATE_TTL = LLA_MFA_CHECKBOX_STATE_TTL; |
| 67 | |
| 68 | /** @var int Max PDF/rescue HTML generations per user per period (rate limit) */ |
| 69 | const PDF_RATE_LIMIT_MAX = LLA_MFA_PDF_RATE_LIMIT_MAX; |
| 70 | |
| 71 | /** @var int PDF generation rate limit period in seconds (1 minute) */ |
| 72 | const PDF_RATE_LIMIT_PERIOD = LLA_MFA_PDF_RATE_LIMIT_PERIOD; |
| 73 | |
| 74 | /** @var string WordPress wp_salt() scheme used as fallback when AUTH_SALT/NONCE_SALT are not defined */ |
| 75 | const WP_SALT_SCHEME_FALLBACK = LLA_MFA_WP_SALT_SCHEME_FALLBACK; |
| 76 | |
| 77 | /** @var string Block reason: SSL/HTTPS required */ |
| 78 | const MFA_BLOCK_REASON_SSL = LLA_MFA_BLOCK_REASON_SSL; |
| 79 | |
| 80 | /** @var string Block reason: deterministic salt required for rate limiting */ |
| 81 | const MFA_BLOCK_REASON_SALT = LLA_MFA_BLOCK_REASON_SALT; |
| 82 | |
| 83 | /** @var string Block reason: OpenSSL required for secure rescue links */ |
| 84 | const MFA_BLOCK_REASON_OPENSSL = LLA_MFA_BLOCK_REASON_OPENSSL; |
| 85 | |
| 86 | /** |
| 87 | * Whether OpenSSL is available for secure rescue code encryption. |
| 88 | * MFA must not be enabled without OpenSSL; no base64 fallback. |
| 89 | * |
| 90 | * @return bool True if openssl_encrypt and openssl_decrypt are available |
| 91 | */ |
| 92 | public static function is_openssl_available() { |
| 93 | static $available = null; |
| 94 | if ( null === $available ) { |
| 95 | $available = function_exists( 'openssl_encrypt' ) && function_exists( 'openssl_decrypt' ); |
| 96 | } |
| 97 | return $available; |
| 98 | } |
| 99 | |
| 100 | /** |
| 101 | * Return deterministic salt for rate limiting, or null if unavailable. |
| 102 | * Chain: AUTH_SALT -> NONCE_SALT -> wp_salt( WP_SALT_SCHEME_FALLBACK ). |
| 103 | * |
| 104 | * @return string|null Salt string or null if none available |
| 105 | */ |
| 106 | public static function get_rate_limit_salt() { |
| 107 | if ( defined( 'AUTH_SALT' ) && AUTH_SALT ) { |
| 108 | return AUTH_SALT; |
| 109 | } |
| 110 | if ( defined( 'NONCE_SALT' ) && NONCE_SALT ) { |
| 111 | return NONCE_SALT; |
| 112 | } |
| 113 | if ( function_exists( 'wp_salt' ) ) { |
| 114 | $salt = wp_salt( self::WP_SALT_SCHEME_FALLBACK ); |
| 115 | if ( is_string( $salt ) && '' !== $salt ) { |
| 116 | return $salt; |
| 117 | } |
| 118 | } |
| 119 | return null; |
| 120 | } |
| 121 | } |
| 122 |