From 20bf7b2b0afcb53608ec37005ee7f831132925d2 Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 4 May 2017 12:28:25 +0300 Subject: [PATCH] Fix PQencryptPasswordConn to work with older server versions. password_encryption was a boolean before version 10, so cope with "on" and "off". Also, change the behavior with "plain", to treat it the same as "md5". We're discussing removing the password_encryption='plain' option from the server altogether, which will make this the only reasonable choice, but even if we kept it, it seems best to never send the password in cleartext. --- doc/src/sgml/libpq.sgml | 4 +++- src/interfaces/libpq/fe-auth.c | 21 ++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 4f60b203fbc..c2b7abc603e 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -5902,7 +5902,9 @@ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, are the cleartext password, and the SQL name of the user it is for. algorithm specifies the encryption algorithm to use to encrypt the password. Currently supported algorithms are - md5, scram-sha-256 and plain. + md5 and scram-sha-256 (on and + off are also accepted as aliases for md5, for + compatibility with older server versions). Note that support for scram-sha-256 was introduced in PostgreSQL version 10, and will not work correctly with older server versions. If algorithm is NULL, this function will query diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c index daa7cc95858..54acd0f6bf8 100644 --- a/src/interfaces/libpq/fe-auth.c +++ b/src/interfaces/libpq/fe-auth.c @@ -1168,7 +1168,7 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, { PQclear(res); printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("password_encryption value too long\n")); + libpq_gettext("password_encryption value too long\n")); return NULL; } strcpy(algobuf, val); @@ -1177,8 +1177,19 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, algorithm = algobuf; } - /* Ok, now we know what algorithm to use */ + /* + * Also accept "on" and "off" as aliases for "md5", because + * password_encryption was a boolean before PostgreSQL 10. We refuse to + * send the password in plaintext even if it was "off". + */ + if (strcmp(algorithm, "on") == 0 || + strcmp(algorithm, "off") == 0 || + strcmp(algorithm, "plain") == 0) + algorithm = "md5"; + /* + * Ok, now we know what algorithm to use + */ if (strcmp(algorithm, "scram-sha-256") == 0) { crypt_pwd = pg_fe_scram_build_verifier(passwd); @@ -1195,14 +1206,10 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, } } } - else if (strcmp(algorithm, "plain") == 0) - { - crypt_pwd = strdup(passwd); - } else { printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("unknown password encryption algorithm\n")); + libpq_gettext("unknown password encryption algorithm\n")); return NULL; }