From 90a275318216bad4d5fb01618ba29fbf68fccad4 Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Mon, 22 Jun 2026 13:24:04 +0900 Subject: [PATCH v1] Warn on password auth with MD5-encrypted passwords Commit bc60ee860 added a connection warning after successful MD5 authentication, but only for the md5 authentication method. A role with an MD5-encrypted password can also authenticate via the password method, which left that path without the same deprecation warning. Emit the MD5 deprecation connection warning after successful password authentication as well, when the stored password is MD5-encrypted. --- doc/src/sgml/config.sgml | 3 ++- src/backend/libpq/auth.c | 33 +++++++++++++++++++++++ src/backend/libpq/crypt.c | 22 --------------- src/test/authentication/t/001_password.pl | 10 +++++++ 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index fa566c9e553..c7663226778 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1206,7 +1206,8 @@ include_dir 'conf.d' Controls whether a WARNING about MD5 password - deprecation is produced upon successful MD5 password authentication or + deprecation is produced upon successful authentication using an + MD5-encrypted password or when a CREATE ROLE or ALTER ROLE statement sets an MD5-encrypted password. The default value is on. diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 2af5615e54a..12bf153d66f 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -48,6 +48,8 @@ static void auth_failed(Port *port, int elevel, int status, const char *logdetail); static char *recv_password_packet(Port *port); +static bool md5_password_warning_enabled(void); +static void queue_md5_password_warning(void); /*---------------------------------------------------------------- @@ -795,6 +797,7 @@ CheckPasswordAuth(Port *port, const char **logdetail) char *passwd; int result; char *shadow_pass; + bool md5_password = false; sendAuthRequest(port, AUTH_REQ_PASSWORD, NULL, 0); @@ -807,6 +810,7 @@ CheckPasswordAuth(Port *port, const char **logdetail) { result = plain_crypt_verify(port->user_name, shadow_pass, passwd, logdetail); + md5_password = (get_password_type(shadow_pass) == PASSWORD_TYPE_MD5); } else result = STATUS_ERROR; @@ -816,7 +820,11 @@ CheckPasswordAuth(Port *port, const char **logdetail) pfree(passwd); if (result == STATUS_OK) + { + if (md5_password) + queue_md5_password_warning(); set_authn_id(port, port->user_name); + } return result; } @@ -913,9 +921,34 @@ CheckMD5Auth(Port *port, char *shadow_pass, const char **logdetail) pfree(passwd); + if (result == STATUS_OK) + queue_md5_password_warning(); + return result; } +static bool +md5_password_warning_enabled(void) +{ + return md5_password_warnings; +} + +static void +queue_md5_password_warning(void) +{ + MemoryContext oldcontext; + char *warning; + char *detail; + + oldcontext = MemoryContextSwitchTo(TopMemoryContext); + + warning = pstrdup(_("authenticated with an MD5-encrypted password")); + detail = pstrdup(_("MD5 password support is deprecated and will be removed in a future release of PostgreSQL.")); + StoreConnectionWarning(warning, detail, md5_password_warning_enabled); + + MemoryContextSwitchTo(oldcontext); +} + /*---------------------------------------------------------------- * GSSAPI authentication system diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index 28857773d9c..e8e840db6b9 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -32,8 +32,6 @@ int password_expiration_warning_threshold = 604800; /* Enables deprecation warnings for MD5 passwords. */ bool md5_password_warnings = true; -static bool md5_password_warning_enabled(void); - /* * Fetch stored password for a user, for authentication. * @@ -297,21 +295,7 @@ md5_crypt_verify(const char *role, const char *shadow_pass, if (strlen(client_pass) == strlen(crypt_pwd) && timingsafe_bcmp(client_pass, crypt_pwd, strlen(crypt_pwd)) == 0) - { - MemoryContext oldcontext; - char *warning; - char *detail; - retval = STATUS_OK; - - oldcontext = MemoryContextSwitchTo(TopMemoryContext); - - warning = pstrdup(_("authenticated with an MD5-encrypted password")); - detail = pstrdup(_("MD5 password support is deprecated and will be removed in a future release of PostgreSQL.")); - StoreConnectionWarning(warning, detail, md5_password_warning_enabled); - - MemoryContextSwitchTo(oldcontext); - } else { *logdetail = psprintf(_("Password does not match for user \"%s\"."), @@ -322,12 +306,6 @@ md5_crypt_verify(const char *role, const char *shadow_pass, return retval; } -static bool -md5_password_warning_enabled(void) -{ - return md5_password_warnings; -} - /* * Check given password for given user, and return STATUS_OK or STATUS_ERROR. * diff --git a/src/test/authentication/t/001_password.pl b/src/test/authentication/t/001_password.pl index fca78fc4d6a..ac67935c258 100644 --- a/src/test/authentication/t/001_password.pl +++ b/src/test/authentication/t/001_password.pl @@ -385,9 +385,19 @@ SKIP: { skip "MD5 not supported" unless $md5_works; test_conn($node, 'user=md5_role', 'password', 0, + expected_stderr => qr/authenticated with an MD5-encrypted password/, log_like => [qr/connection authenticated: identity="md5_role" method=password/] ); + + $node->connect_ok( + 'user=md5_role_no_warnings', + 'password with warnings disabled', + sql => 'SHOW md5_password_warnings', + expected_stdout => qr/^off$/, + log_like => [ + qr/connection authenticated: identity="md5_role_no_warnings" method=password/ + ]); } # require_auth succeeds here with a plaintext password. -- 2.53.0