psql cannot read client SSL private key from a pipe

From: Tony Finch <dot(at)dotat(dot)at>
To: pgsql-bugs(at)postgresql(dot)org
Subject: psql cannot read client SSL private key from a pipe
Date: 2017-12-21 17:40:08
Message-ID: alpine.DEB.2.11.1712211724420.19157@grey.csi.cam.ac.uk
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

PostgreSQL version: 10.1
OS: Debian Stretch 9.3

I would like to be able to pass my SSL private key to psql via a pipe.
This is so that I can use the gpg agent to decrypt my key without retyping
my passphrase each time. (There isn't an agent for OpenSSL's own key
decryption routines.) For example,

$ psql 'host=db1 port=5432 sslmode=verify-full user=postgres \
sslcert=postgres.crt sslkey='<(gpg -d postgres.pem.asc)

This fails because libpq complains:

psql: private key file "/dev/fd/63" has group or world access; permissions should be u=rw (0600) or less

because it makes an explicit S_ISREG() check on the key file.

I think it would be better to remove the check - with the patch below I
can log in using the command quoted above.

Alternatively you could only exclude S_ISDIR() and S_ISBLK() - the other
cases allow getting keys from interesting placesq.

There is a similarly problematic check for password files which I have
also removed below. On the backend side, there is no check for the file
type of the server private key, so the patch below makes the front-end
checks match the backend better.

Tony.
--
f.anthony.n.finch <dot(at)dotat(dot)at> http://dotat.at/ - I xn--zr8h punycode
Humber, Thames: Variable 3 or 4. Smooth or slight. Occasional rain, fog
patches. Moderate or good, occasionally very poor.

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 2839fee..bbf79d9 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -6401,14 +6401,6 @@ passwordFromFile(char *hostname, char *port, char *dbname,
return NULL;

#ifndef WIN32
- if (!S_ISREG(stat_buf.st_mode))
- {
- fprintf(stderr,
- libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
- pgpassfile);
- return NULL;
- }
-
/* If password file is insecure, alert the user and ignore it. */
if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
{
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 2f29820..0bb9491 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1235,7 +1235,7 @@ initialize_SSL(PGconn *conn)
return -1;
}
#ifndef WIN32
- if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
+ if (buf.st_mode & (S_IRWXG | S_IRWXO))
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Todd A. Cook 2017-12-21 17:43:18 Re: BUG #14990: hashint4() <> hashint8() for small negative values, causing hash joins to fail
Previous Message Tom Lane 2017-12-21 17:31:44 Re: BUG #14990: hashint4() <> hashint8() for small negative values, causing hash joins to fail