On 2020/01/22 11:01, Fujii Masao wrote:
On 2020/01/22 0:12, Bruce Momjian wrote:
On Tue, Jan 21, 2020 at 02:42:07PM +0900, Fujii Masao wrote:
I have no strong opinion about the maximum length of password,
for now. But IMO it's worth committing that 0001 patch as the first step
for this problem.
Also IMO the more problematic thing is that psql silently truncates
the password specified in the prompt into 99B if its length is
more than 99B. I think that psql should emit a warning in this case
so that users can notice that.
I think we should be using a macro to define the maximum length, rather
than have 100 used in various places.
+1 as the first step for this issue. The patch that I mentioned
upthread actually does that.
Attached is the patch that Nathan proposed at [1] and I think that
it's worth applying. I'd like to add this to next CommitFest.
Thought?
[1]
https://www.postgresql.org/message-id/09512c4f-8cb9-4021-b455-ef4c4f0d5...@amazon.com
Regards,
--
Fujii Masao
NTT DATA CORPORATION
Advanced Platform Technology Group
Research and Development Headquarters
From ba8fb45bfad75ebba9b22bfaf397d2647a416f8e Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossa...@amazon.com>
Date: Fri, 12 Oct 2018 15:31:31 +0000
Subject: [PATCH v1 1/3] Refactor maximum password length enforced by client
utilities.
---
contrib/oid2name/oid2name.c | 2 +-
contrib/vacuumlo/vacuumlo.c | 2 +-
src/bin/initdb/initdb.c | 4 ++--
src/bin/pg_basebackup/streamutil.c | 2 +-
src/bin/pg_dump/pg_backup_db.c | 4 ++--
src/bin/pg_dump/pg_dumpall.c | 2 +-
src/bin/pgbench/pgbench.c | 2 +-
src/bin/psql/command.c | 6 +++---
src/bin/psql/startup.c | 2 +-
src/bin/scripts/common.c | 2 +-
src/bin/scripts/createuser.c | 4 ++--
src/common/saslprep.c | 4 ++--
src/include/postgres_fe.h | 11 +++++++++++
13 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c
index aa122ca0e9..08904ffd12 100644
--- a/contrib/oid2name/oid2name.c
+++ b/contrib/oid2name/oid2name.c
@@ -285,7 +285,7 @@ sql_conn(struct options *my_opts)
{
PGconn *conn;
bool have_password = false;
- char password[100];
+ char password[PROMPT_MAX_PASSWORD_LENGTH];
bool new_pass;
PGresult *res;
diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c
index 3075781abe..5acfa65289 100644
--- a/contrib/vacuumlo/vacuumlo.c
+++ b/contrib/vacuumlo/vacuumlo.c
@@ -70,7 +70,7 @@ vacuumlo(const char *database, const struct _param *param)
bool new_pass;
bool success = true;
static bool have_password = false;
- static char password[100];
+ static char password[PROMPT_MAX_PASSWORD_LENGTH];
/* Note: password can be carried over from a previous call */
if (param->pg_prompt == TRI_YES && !have_password)
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index ab5cb7f0c1..a9663531de 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1528,8 +1528,8 @@ setup_auth(FILE *cmdfd)
static void
get_su_pwd(void)
{
- char pwd1[100];
- char pwd2[100];
+ char pwd1[PROMPT_MAX_PASSWORD_LENGTH];
+ char pwd2[PROMPT_MAX_PASSWORD_LENGTH];
if (pwprompt)
{
diff --git a/src/bin/pg_basebackup/streamutil.c
b/src/bin/pg_basebackup/streamutil.c
index 52f1e559b7..8ecb412ab8 100644
--- a/src/bin/pg_basebackup/streamutil.c
+++ b/src/bin/pg_basebackup/streamutil.c
@@ -51,7 +51,7 @@ char *dbport = NULL;
char *dbname = NULL;
int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */
static bool have_password = false;
-static char password[100];
+static char password[PROMPT_MAX_PASSWORD_LENGTH];
PGconn *conn = NULL;
/*
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index 5e32ee8a5b..402ee3cff1 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -126,7 +126,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char
*requser)
const char *newdb;
const char *newuser;
char *password;
- char passbuf[100];
+ char passbuf[PROMPT_MAX_PASSWORD_LENGTH];
bool new_pass;
if (!reqdb)
@@ -246,7 +246,7 @@ ConnectDatabase(Archive *AHX,
{
ArchiveHandle *AH = (ArchiveHandle *) AHX;
char *password;
- char passbuf[100];
+ char passbuf[PROMPT_MAX_PASSWORD_LENGTH];
bool new_pass;
if (AH->connection)
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 5176626476..0521f8c700 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -1536,7 +1536,7 @@ connectDatabase(const char *dbname, const char
*connection_string,
const char **values = NULL;
PQconninfoOption *conn_opts = NULL;
static bool have_password = false;
- static char password[100];
+ static char password[PROMPT_MAX_PASSWORD_LENGTH];
if (prompt_password == TRI_YES && !have_password)
{
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 436764b9c9..097666169b 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -1179,7 +1179,7 @@ doConnect(void)
PGconn *conn;
bool new_pass;
static bool have_password = false;
- static char password[100];
+ static char password[PROMPT_MAX_PASSWORD_LENGTH];
/*
* Start the connection. Loop until we have a password if requested by
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 5b4d54a442..879fa1f494 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1790,8 +1790,8 @@ exec_command_password(PsqlScanState scan_state, bool
active_branch)
{
char *opt0 = psql_scan_slash_option(scan_state,
OT_SQLID, NULL, true);
- char pw1[100];
- char pw2[100];
+ char pw1[PROMPT_MAX_PASSWORD_LENGTH];
+ char pw2[PROMPT_MAX_PASSWORD_LENGTH];
simple_prompt("Enter new password: ", pw1, sizeof(pw1), false);
simple_prompt("Enter it again: ", pw2, sizeof(pw2), false);
@@ -2808,7 +2808,7 @@ copy_previous_query(PQExpBuffer query_buf, PQExpBuffer
previous_buf)
static char *
prompt_for_password(const char *username)
{
- char buf[100];
+ char buf[PROMPT_MAX_PASSWORD_LENGTH];
if (username == NULL || username[0] == '\0')
simple_prompt("Password: ", buf, sizeof(buf), false);
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index be57574cd3..dfc1377382 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -100,7 +100,7 @@ main(int argc, char *argv[])
struct adhoc_opts options;
int successResult;
bool have_password = false;
- char password[100];
+ char password[PROMPT_MAX_PASSWORD_LENGTH];
bool new_pass;
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql"));
diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c
index ba6120706d..0b31bf3672 100644
--- a/src/bin/scripts/common.c
+++ b/src/bin/scripts/common.c
@@ -73,7 +73,7 @@ connectDatabase(const char *dbname, const char *pghost,
PGconn *conn;
bool new_pass;
static bool have_password = false;
- static char password[100];
+ static char password[PROMPT_MAX_PASSWORD_LENGTH];
if (!allow_password_reuse)
have_password = false;
diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c
index 3420e62fdd..ced7386af8 100644
--- a/src/bin/scripts/createuser.c
+++ b/src/bin/scripts/createuser.c
@@ -66,7 +66,7 @@ main(int argc, char *argv[])
bool pwprompt = false;
char *newpassword = NULL;
char newuser_buf[128];
- char newpassword_buf[100];
+ char newpassword_buf[PROMPT_MAX_PASSWORD_LENGTH];
/* Tri-valued variables. */
enum trivalue createdb = TRI_DEFAULT,
@@ -201,7 +201,7 @@ main(int argc, char *argv[])
if (pwprompt)
{
- char pw2[100];
+ char pw2[PROMPT_MAX_PASSWORD_LENGTH];
simple_prompt("Enter password for new role: ",
newpassword_buf,
sizeof(newpassword_buf), false);
diff --git a/src/common/saslprep.c b/src/common/saslprep.c
index 4cf574fed8..1f90df250d 100644
--- a/src/common/saslprep.c
+++ b/src/common/saslprep.c
@@ -39,7 +39,7 @@
* Limit on how large password's we will try to process. A password
* larger than this will be treated the same as out-of-memory.
*/
-#define MAX_PASSWORD_LENGTH 1024
+#define SASLPREP_MAX_PASSWORD_LENGTH 1024
/*
* In backend, we will use palloc/pfree. In frontend, use malloc, and
@@ -1085,7 +1085,7 @@ pg_saslprep(const char *input, char **output)
*output = NULL;
/* Check that the password isn't stupendously long */
- if (strlen(input) > MAX_PASSWORD_LENGTH)
+ if (strlen(input) > SASLPREP_MAX_PASSWORD_LENGTH)
{
#ifndef FRONTEND
ereport(ERROR,
diff --git a/src/include/postgres_fe.h b/src/include/postgres_fe.h
index 14567953f2..0c9293f942 100644
--- a/src/include/postgres_fe.h
+++ b/src/include/postgres_fe.h
@@ -26,4 +26,15 @@
#include "common/fe_memutils.h"
+/*
+ * Limit on the length of passwords we will try to process. Note that this
does
+ * not restrict the creation of longer passwords via commands such as CREATE
+ * ROLE and ALTER ROLE. It merely restricts the length of passwords accepted
by
+ * client utility prompts (e.g. psql).
+ *
+ * One byte is reserved at the end for the '\0' byte, so the user-facing
maximum
+ * length is actually 99.
+ */
+#define PROMPT_MAX_PASSWORD_LENGTH 100
+
#endif /* POSTGRES_FE_H */
--
2.16.2