| @@ -64,34 +64,70 @@ | ||
| 64 | 64 | |
| 65 | 65 | /** |
| 66 | 66 | * Get key filename. |
| 67 | 67 | * |
| 68 | - * @param int $site_id site id. | |
| 68 | + * Returns the opaque HMAC-derived filename for the given site's encrypted | |
| 69 | + * private key. When called with $fullpath=true, also performs lazy migration: | |
| 70 | + * if the new opaque file does not yet exist but a legacy filename does, it | |
| 71 | + * is renamed in place. This covers the window between a plugin upgrade and | |
| 72 | + * the bulk migration on `mainwp_db_after_update`. | |
| 73 | + * | |
| 74 | + * @param int $site_id site id. | |
| 69 | 75 | * @param bool $fullpath full path. |
| 70 | 76 | * |
| 71 | 77 | * @return string |
| 72 | 78 | */ |
| 73 | 79 | public static function get_key_file( $site_id, $fullpath = false ) { |
| 74 | - $file = 'mainwp_priv_encrypt_keys_' . $site_id; | |
| 80 | + $file = MainWP_System_Utility::get_private_filename( 'pk', $site_id, 'priv_encrypt_keys' ); | |
| 75 | 81 | if ( $fullpath ) { |
| 76 | 82 | MainWP_Keys_Manager::init_keys_dir(); |
| 77 | - $key_dir = MainWP_Keys_Manager::get_keys_dir(); | |
| 78 | - return $key_dir . $file; | |
| 83 | + $key_dir = MainWP_Keys_Manager::get_keys_dir(); | |
| 84 | + $new_path = $key_dir . $file; | |
| 85 | + if ( ! file_exists( $new_path ) ) { | |
| 86 | + $legacy_path = $key_dir . static::legacy_key_filename( $site_id ); | |
| 87 | + if ( file_exists( $legacy_path ) ) { | |
| 88 | + if ( @rename( $legacy_path, $new_path ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors -- best-effort lazy migration. | |
| 89 | + return $new_path; | |
| 90 | + } | |
| 91 | + return $legacy_path; // rename failed; fall back to legacy until bulk migration runs. | |
| 92 | + } | |
| 93 | + } | |
| 94 | + return $new_path; | |
| 79 | 95 | } |
| 80 | 96 | return $file; |
| 81 | 97 | } |
| 82 | 98 | |
| 99 | + /** | |
| 100 | + * Legacy (predictable) key filename. | |
| 101 | + * | |
| 102 | + * Returns the pre-migration filename pattern for a site's encrypted private | |
| 103 | + * key. Used by lazy migration in get_key_file() and by the bulk migration | |
| 104 | + * on plugin upgrade to locate files that need renaming. New code should | |
| 105 | + * never write a file at this name. | |
| 106 | + * | |
| 107 | + * @param int $site_id site id. | |
| 108 | + * | |
| 109 | + * @return string Legacy filename. | |
| 110 | + */ | |
| 111 | + public static function legacy_key_filename( $site_id ) { | |
| 112 | + return 'mainwp_priv_encrypt_keys_' . $site_id; | |
| 113 | + } | |
| 83 | 114 | |
| 115 | + | |
| 84 | 116 | /** |
| 85 | 117 | * Remove key file. |
| 86 | 118 | * |
| 119 | + * Deletes both the new opaque filename and the legacy filename (if either | |
| 120 | + * exists) so that orphan legacy files left behind by an incomplete bulk | |
| 121 | + * migration are also cleaned up. | |
| 122 | + * | |
| 87 | 123 | * @param int $site_id site id. |
| 88 | 124 | * |
| 89 | 125 | * @return void |
| 90 | 126 | */ |
| 91 | 127 | public static function remove_key_file( $site_id ) { |
| 92 | - $file = static::get_key_file( $site_id ); | |
| 93 | - MainWP_Keys_Manager::instance()->delete_key_file( $file ); | |
| 128 | + MainWP_Keys_Manager::instance()->delete_key_file( static::get_key_file( $site_id ) ); | |
| 129 | + MainWP_Keys_Manager::instance()->delete_key_file( static::legacy_key_filename( $site_id ) ); | |
| 94 | 130 | } |
| 95 | 131 | |
| 96 | 132 | /** |
| 97 | 133 | * Encrypt data. |