Thread: psql cannot read client SSL private key from a pipe

psql cannot read client SSL private key from a pipe

From
Tony Finch
Date:
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@dotat.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"),
 


Re: psql cannot read client SSL private key from a pipe

From
Andreas Karlsson
Date:
On 12/21/2017 06:40 PM, Tony Finch wrote:
> 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)

Hm, this does sound like a useful feature. Not sure if it counts as a 
bug though, so the hackers list is probably more suited for this patch.

> 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.

I do not know why this check was added in the first place so I am not 
entirely sure what the right behavior should be. Maybe it would be 
enough with an S_ISDIR() check.

Andreas