Skip to content

Commit 67a472d

Browse files
committed
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary limits on password length, but after awhile a better idea emerged: let's just get rid of those fixed limits. recv_password_packet() has an arbitrary limit on the packet size, which we don't really need, so just drop it. (Note that this doesn't really affect anything for MD5 or SCRAM password verification, since those will hash the user's password to something shorter anyway. It does matter for auth methods that require a cleartext password.) Likewise remove the arbitrary error condition in pg_saslprep(). The remaining limits are mostly in client-side code that prompts for passwords. To improve those, refactor simple_prompt() so that it allocates its own result buffer that can be made as big as necessary. Actually, it proves best to make a separate routine pg_get_line() that has essentially the semantics of fgets(), except that it allocates a suitable result buffer and hence will never return a truncated line. (pg_get_line has a lot of potential applications to replace randomly-sized fgets buffers elsewhere, but I'll leave that for another patch.) I built pg_get_line() atop stringinfo.c, which requires moving that code to src/common/; but that seems fine since it was a poor fit for src/port/ anyway. This patch is mostly mine, but it owes a good deal to Nathan Bossart who pressed for a solution to the password length problem and created a predecessor patch. Also thanks to Peter Eisentraut and Stephen Frost for ideas and discussion. Discussion: https://postgr.es/m/[email protected]
1 parent be4b0c0 commit 67a472d

File tree

21 files changed

+221
-167
lines changed

21 files changed

+221
-167
lines changed

contrib/oid2name/oid2name.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "catalog/pg_class_d.h"
1313
#include "common/connect.h"
1414
#include "common/logging.h"
15+
#include "common/string.h"
1516
#include "getopt_long.h"
1617
#include "libpq-fe.h"
1718
#include "pg_getopt.h"
@@ -293,8 +294,7 @@ PGconn *
293294
sql_conn(struct options *my_opts)
294295
{
295296
PGconn *conn;
296-
bool have_password = false;
297-
char password[100];
297+
char *password = NULL;
298298
bool new_pass;
299299
PGresult *res;
300300

@@ -316,7 +316,7 @@ sql_conn(struct options *my_opts)
316316
keywords[2] = "user";
317317
values[2] = my_opts->username;
318318
keywords[3] = "password";
319-
values[3] = have_password ? password : NULL;
319+
values[3] = password;
320320
keywords[4] = "dbname";
321321
values[4] = my_opts->dbname;
322322
keywords[5] = "fallback_application_name";
@@ -336,11 +336,10 @@ sql_conn(struct options *my_opts)
336336

337337
if (PQstatus(conn) == CONNECTION_BAD &&
338338
PQconnectionNeedsPassword(conn) &&
339-
!have_password)
339+
!password)
340340
{
341341
PQfinish(conn);
342-
simple_prompt("Password: ", password, sizeof(password), false);
343-
have_password = true;
342+
password = simple_prompt("Password: ", false);
344343
new_pass = true;
345344
}
346345
} while (new_pass);

contrib/vacuumlo/vacuumlo.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "catalog/pg_class_d.h"
2525
#include "common/connect.h"
2626
#include "common/logging.h"
27+
#include "common/string.h"
2728
#include "getopt_long.h"
2829
#include "libpq-fe.h"
2930
#include "pg_getopt.h"
@@ -69,15 +70,11 @@ vacuumlo(const char *database, const struct _param *param)
6970
int i;
7071
bool new_pass;
7172
bool success = true;
72-
static bool have_password = false;
73-
static char password[100];
73+
static char *password = NULL;
7474

7575
/* Note: password can be carried over from a previous call */
76-
if (param->pg_prompt == TRI_YES && !have_password)
77-
{
78-
simple_prompt("Password: ", password, sizeof(password), false);
79-
have_password = true;
80-
}
76+
if (param->pg_prompt == TRI_YES && !password)
77+
password = simple_prompt("Password: ", false);
8178

8279
/*
8380
* Start the connection. Loop until we have a password if requested by
@@ -97,7 +94,7 @@ vacuumlo(const char *database, const struct _param *param)
9794
keywords[2] = "user";
9895
values[2] = param->pg_user;
9996
keywords[3] = "password";
100-
values[3] = have_password ? password : NULL;
97+
values[3] = password;
10198
keywords[4] = "dbname";
10299
values[4] = database;
103100
keywords[5] = "fallback_application_name";
@@ -115,12 +112,11 @@ vacuumlo(const char *database, const struct _param *param)
115112

116113
if (PQstatus(conn) == CONNECTION_BAD &&
117114
PQconnectionNeedsPassword(conn) &&
118-
!have_password &&
115+
!password &&
119116
param->pg_prompt != TRI_NO)
120117
{
121118
PQfinish(conn);
122-
simple_prompt("Password: ", password, sizeof(password), false);
123-
have_password = true;
119+
password = simple_prompt("Password: ", false);
124120
new_pass = true;
125121
}
126122
} while (new_pass);

src/backend/libpq/auth.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ recv_password_packet(Port *port)
698698
}
699699

700700
initStringInfo(&buf);
701-
if (pq_getmessage(&buf, 1000)) /* receive password */
701+
if (pq_getmessage(&buf, 0)) /* receive password */
702702
{
703703
/* EOF - pq_getmessage already logged a suitable message */
704704
pfree(buf.data);

src/bin/initdb/initdb.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include "common/file_utils.h"
6868
#include "common/logging.h"
6969
#include "common/restricted_token.h"
70+
#include "common/string.h"
7071
#include "common/username.h"
7172
#include "fe_utils/string_utils.h"
7273
#include "getaddrinfo.h"
@@ -1481,23 +1482,25 @@ setup_auth(FILE *cmdfd)
14811482
static void
14821483
get_su_pwd(void)
14831484
{
1484-
char pwd1[100];
1485-
char pwd2[100];
1485+
char *pwd1;
14861486

14871487
if (pwprompt)
14881488
{
14891489
/*
14901490
* Read password from terminal
14911491
*/
1492+
char *pwd2;
1493+
14921494
printf("\n");
14931495
fflush(stdout);
1494-
simple_prompt("Enter new superuser password: ", pwd1, sizeof(pwd1), false);
1495-
simple_prompt("Enter it again: ", pwd2, sizeof(pwd2), false);
1496+
pwd1 = simple_prompt("Enter new superuser password: ", false);
1497+
pwd2 = simple_prompt("Enter it again: ", false);
14961498
if (strcmp(pwd1, pwd2) != 0)
14971499
{
14981500
fprintf(stderr, _("Passwords didn't match.\n"));
14991501
exit(1);
15001502
}
1503+
free(pwd2);
15011504
}
15021505
else
15031506
{
@@ -1510,15 +1513,15 @@ get_su_pwd(void)
15101513
* for now.
15111514
*/
15121515
FILE *pwf = fopen(pwfilename, "r");
1513-
int i;
15141516

15151517
if (!pwf)
15161518
{
15171519
pg_log_error("could not open file \"%s\" for reading: %m",
15181520
pwfilename);
15191521
exit(1);
15201522
}
1521-
if (!fgets(pwd1, sizeof(pwd1), pwf))
1523+
pwd1 = pg_get_line(pwf);
1524+
if (!pwd1)
15221525
{
15231526
if (ferror(pwf))
15241527
pg_log_error("could not read password from file \"%s\": %m",
@@ -1530,12 +1533,10 @@ get_su_pwd(void)
15301533
}
15311534
fclose(pwf);
15321535

1533-
i = strlen(pwd1);
1534-
while (i > 0 && (pwd1[i - 1] == '\r' || pwd1[i - 1] == '\n'))
1535-
pwd1[--i] = '\0';
1536+
(void) pg_strip_crlf(pwd1);
15361537
}
15371538

1538-
superuser_password = pg_strdup(pwd1);
1539+
superuser_password = pwd1;
15391540
}
15401541

15411542
/*

src/bin/pg_basebackup/streamutil.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "common/fe_memutils.h"
2323
#include "common/file_perm.h"
2424
#include "common/logging.h"
25+
#include "common/string.h"
2526
#include "datatype/timestamp.h"
2627
#include "port/pg_bswap.h"
2728
#include "pqexpbuffer.h"
@@ -49,8 +50,7 @@ char *dbuser = NULL;
4950
char *dbport = NULL;
5051
char *dbname = NULL;
5152
int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */
52-
static bool have_password = false;
53-
static char password[100];
53+
static char *password = NULL;
5454
PGconn *conn = NULL;
5555

5656
/*
@@ -150,20 +150,21 @@ GetConnection(void)
150150
}
151151

152152
/* If -W was given, force prompt for password, but only the first time */
153-
need_password = (dbgetpassword == 1 && !have_password);
153+
need_password = (dbgetpassword == 1 && !password);
154154

155155
do
156156
{
157157
/* Get a new password if appropriate */
158158
if (need_password)
159159
{
160-
simple_prompt("Password: ", password, sizeof(password), false);
161-
have_password = true;
160+
if (password)
161+
free(password);
162+
password = simple_prompt("Password: ", false);
162163
need_password = false;
163164
}
164165

165166
/* Use (or reuse, on a subsequent connection) password if we have it */
166-
if (have_password)
167+
if (password)
167168
{
168169
keywords[i] = "password";
169170
values[i] = password;

src/bin/pg_dump/pg_backup_db.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#endif
1919

2020
#include "common/connect.h"
21+
#include "common/string.h"
2122
#include "dumputils.h"
2223
#include "fe_utils/string_utils.h"
2324
#include "parallel.h"
@@ -122,7 +123,6 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
122123
const char *newdb;
123124
const char *newuser;
124125
char *password;
125-
char passbuf[100];
126126
bool new_pass;
127127

128128
if (!reqdb)
@@ -141,10 +141,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
141141
password = AH->savedPassword;
142142

143143
if (AH->promptPassword == TRI_YES && password == NULL)
144-
{
145-
simple_prompt("Password: ", passbuf, sizeof(passbuf), false);
146-
password = passbuf;
147-
}
144+
password = simple_prompt("Password: ", false);
148145

149146
initPQExpBuffer(&connstr);
150147
appendPQExpBufferStr(&connstr, "dbname=");
@@ -191,8 +188,9 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
191188

192189
if (AH->promptPassword != TRI_NO)
193190
{
194-
simple_prompt("Password: ", passbuf, sizeof(passbuf), false);
195-
password = passbuf;
191+
if (password && password != AH->savedPassword)
192+
free(password);
193+
password = simple_prompt("Password: ", false);
196194
}
197195
else
198196
fatal("connection needs password");
@@ -201,6 +199,9 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
201199
}
202200
} while (new_pass);
203201

202+
if (password && password != AH->savedPassword)
203+
free(password);
204+
204205
/*
205206
* We want to remember connection's actual password, whether or not we got
206207
* it by prompting. So we don't just store the password variable.
@@ -242,7 +243,6 @@ ConnectDatabase(Archive *AHX,
242243
{
243244
ArchiveHandle *AH = (ArchiveHandle *) AHX;
244245
char *password;
245-
char passbuf[100];
246246
bool new_pass;
247247

248248
if (AH->connection)
@@ -251,10 +251,8 @@ ConnectDatabase(Archive *AHX,
251251
password = AH->savedPassword;
252252

253253
if (prompt_password == TRI_YES && password == NULL)
254-
{
255-
simple_prompt("Password: ", passbuf, sizeof(passbuf), false);
256-
password = passbuf;
257-
}
254+
password = simple_prompt("Password: ", false);
255+
258256
AH->promptPassword = prompt_password;
259257

260258
/*
@@ -293,8 +291,7 @@ ConnectDatabase(Archive *AHX,
293291
prompt_password != TRI_NO)
294292
{
295293
PQfinish(AH->connection);
296-
simple_prompt("Password: ", passbuf, sizeof(passbuf), false);
297-
password = passbuf;
294+
password = simple_prompt("Password: ", false);
298295
new_pass = true;
299296
}
300297
} while (new_pass);
@@ -309,6 +306,9 @@ ConnectDatabase(Archive *AHX,
309306
PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH,
310307
ALWAYS_SECURE_SEARCH_PATH_SQL));
311308

309+
if (password && password != AH->savedPassword)
310+
free(password);
311+
312312
/*
313313
* We want to remember connection's actual password, whether or not we got
314314
* it by prompting. So we don't just store the password variable.

src/bin/pg_dump/pg_dumpall.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "common/connect.h"
2222
#include "common/file_utils.h"
2323
#include "common/logging.h"
24+
#include "common/string.h"
2425
#include "dumputils.h"
2526
#include "fe_utils/string_utils.h"
2627
#include "getopt_long.h"
@@ -1643,14 +1644,10 @@ connectDatabase(const char *dbname, const char *connection_string,
16431644
const char **keywords = NULL;
16441645
const char **values = NULL;
16451646
PQconninfoOption *conn_opts = NULL;
1646-
static bool have_password = false;
1647-
static char password[100];
1647+
static char *password = NULL;
16481648

1649-
if (prompt_password == TRI_YES && !have_password)
1650-
{
1651-
simple_prompt("Password: ", password, sizeof(password), false);
1652-
have_password = true;
1653-
}
1649+
if (prompt_password == TRI_YES && !password)
1650+
password = simple_prompt("Password: ", false);
16541651

16551652
/*
16561653
* Start the connection. Loop until we have a password if requested by
@@ -1730,7 +1727,7 @@ connectDatabase(const char *dbname, const char *connection_string,
17301727
values[i] = pguser;
17311728
i++;
17321729
}
1733-
if (have_password)
1730+
if (password)
17341731
{
17351732
keywords[i] = "password";
17361733
values[i] = password;
@@ -1757,12 +1754,11 @@ connectDatabase(const char *dbname, const char *connection_string,
17571754

17581755
if (PQstatus(conn) == CONNECTION_BAD &&
17591756
PQconnectionNeedsPassword(conn) &&
1760-
!have_password &&
1757+
!password &&
17611758
prompt_password != TRI_NO)
17621759
{
17631760
PQfinish(conn);
1764-
simple_prompt("Password: ", password, sizeof(password), false);
1765-
have_password = true;
1761+
password = simple_prompt("Password: ", false);
17661762
new_pass = true;
17671763
}
17681764
} while (new_pass);

src/bin/pgbench/pgbench.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959

6060
#include "common/int.h"
6161
#include "common/logging.h"
62+
#include "common/string.h"
6263
#include "fe_utils/cancel.h"
6364
#include "fe_utils/conditional.h"
6465
#include "getopt_long.h"
@@ -1174,8 +1175,7 @@ doConnect(void)
11741175
{
11751176
PGconn *conn;
11761177
bool new_pass;
1177-
static bool have_password = false;
1178-
static char password[100];
1178+
static char *password = NULL;
11791179

11801180
/*
11811181
* Start the connection. Loop until we have a password if requested by
@@ -1195,7 +1195,7 @@ doConnect(void)
11951195
keywords[2] = "user";
11961196
values[2] = login;
11971197
keywords[3] = "password";
1198-
values[3] = have_password ? password : NULL;
1198+
values[3] = password;
11991199
keywords[4] = "dbname";
12001200
values[4] = dbName;
12011201
keywords[5] = "fallback_application_name";
@@ -1215,11 +1215,10 @@ doConnect(void)
12151215

12161216
if (PQstatus(conn) == CONNECTION_BAD &&
12171217
PQconnectionNeedsPassword(conn) &&
1218-
!have_password)
1218+
!password)
12191219
{
12201220
PQfinish(conn);
1221-
simple_prompt("Password: ", password, sizeof(password), false);
1222-
have_password = true;
1221+
password = simple_prompt("Password: ", false);
12231222
new_pass = true;
12241223
}
12251224
} while (new_pass);

0 commit comments

Comments
 (0)