diff --git a/sql/auth/sha2_password.cc b/sql/auth/sha2_password.cc index d87a4c859eff..2f9941438d83 100644 --- a/sql/auth/sha2_password.cc +++ b/sql/auth/sha2_password.cc @@ -33,8 +33,10 @@ #include #include #include // from_chars -#include /* std::setfill(), std::setw() */ -#include /* For debugging */ +#include +#include /* std::setfill(), std::setw() */ +#include /* For debugging */ +#include #include #include #include @@ -103,11 +105,43 @@ bool caching_sha2_enforce_storage_format = false; class THD; struct SYS_VAR; +extern sha2_password::Caching_sha2_password *g_caching_sha2_password; + +class Caching_sha2_password_state { + public: + bool begin() { + std::lock_guard lock(mutex); + if (shutting_down || g_caching_sha2_password == nullptr) return false; + ++active_calls; + return true; + } + + void end() { + std::lock_guard lock(mutex); + assert(active_calls > 0); + if (--active_calls == 0) cv.notify_all(); + } + + void start_shutdown() { + std::unique_lock lock(mutex); + shutting_down = true; + cv.wait(lock, [&] { return active_calls == 0; }); + } + + private: + std::mutex mutex; + std::condition_variable cv; + size_t active_calls = 0; + bool shutting_down = false; +}; + char *caching_sha2_rsa_private_key_path; char *caching_sha2_rsa_public_key_path; bool caching_sha2_auto_generate_rsa_keys = true; Rsa_authentication_keys *g_caching_sha2_rsa_keys = nullptr; +int caching_sha2_digest_rounds = 0; +static Caching_sha2_password_state g_caching_sha2_password_state; static bool init_event_tracking_authentication(); static bool deinit_event_tracking_authentication(); @@ -1100,6 +1134,9 @@ static char perform_full_authentication = '\4'; static int caching_sha2_password_authenticate(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) { DBUG_TRACE; + if (!g_caching_sha2_password_state.begin()) return CR_ERROR; + auto cleanup_guard = + create_scope_guard([&] { g_caching_sha2_password_state.end(); }); uchar *pkt; int pkt_len; char scramble[SCRAMBLE_LENGTH + 1]; @@ -1326,6 +1363,9 @@ static int caching_sha2_password_authenticate(MYSQL_PLUGIN_VIO *vio, int caching_sha2_password_generate(char *outbuf, unsigned int *buflen, const char *inbuf, unsigned int inbuflen) { DBUG_TRACE; + if (!g_caching_sha2_password_state.begin()) return 1; + auto cleanup_guard = + create_scope_guard([&] { g_caching_sha2_password_state.end(); }); const std::string source(inbuf, inbuflen); std::string serialized_string; @@ -1372,6 +1412,9 @@ int caching_sha2_password_generate(char *outbuf, unsigned int *buflen, static int caching_sha2_password_validate(char *const inbuf, unsigned int buflen) { DBUG_TRACE; + if (!g_caching_sha2_password_state.begin()) return 1; + auto cleanup_guard = + create_scope_guard([&] { g_caching_sha2_password_state.end(); }); const std::string serialized_string(inbuf, buflen); if (g_caching_sha2_password->validate_hash(serialized_string)) return 1; return 0; @@ -1433,6 +1476,9 @@ static int caching_sha2_authentication_init(MYSQL_PLUGIN plugin_ref) { static int caching_sha2_authentication_deinit(void *arg [[maybe_unused]]) { DBUG_TRACE; + + g_caching_sha2_password_state.start_shutdown(); + if (g_caching_sha2_password) { delete g_caching_sha2_password; g_caching_sha2_password = nullptr; @@ -1461,6 +1507,12 @@ static int compare_caching_sha2_password_with_hash( const char *hash, unsigned long hash_length, const char *cleartext, unsigned long cleartext_length, int *is_error) { DBUG_TRACE; + if (!g_caching_sha2_password_state.begin()) { + *is_error = 1; + return -1; + } + auto cleanup_guard = + create_scope_guard([&] { g_caching_sha2_password_state.end(); }); const std::string_view stored(hash, hash_length); const std::string plaintext_password(cleartext, cleartext_length); @@ -1700,6 +1752,10 @@ bool Event_tracking_authentication_implementation::callback( If status is set to true, it indicates an error. In which case, don't touch the cache. */ + if (!g_caching_sha2_password_state.begin()) return false; + auto cleanup_guard = + create_scope_guard([&] { g_caching_sha2_password_state.end(); }); + if (data->status) return false; switch (data->event_subclass) { case EVENT_TRACKING_AUTHENTICATION_FLUSH: