diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 3a7cc8f774..285e772170 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -1234,11 +1234,38 @@ initialize_SSL(PGconn *conn) fnbuf); return -1; } + + /* + * Refuse to load key files owned by users other than us or root. + * + * XXX surely we can check this on Windows somehow, too. + */ +#ifndef WIN32 + if (buf.st_uid != geteuid() && buf.st_uid != 0) + { + appendPQExpBuffer(&conn->errorMessage, + libpq_gettext("private key file \"%s\" must be owned by the current user or root\n"), + fnbuf); + return -1; + } +#endif + + /* + * Require no public access to key file. If the file is owned by us, + * require mode 0600 or less. If owned by root, require 0640 or less to + * allow read access through our gid, or a supplementary gid that allows + * to read system-wide certificates. + * + * XXX temporarily suppress check when on Windows, because there may not + * be proper support for Unix-y file permissions. Need to think of a + * reasonable check to apply on Windows. + */ #ifndef WIN32 - if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO)) + if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) || + (buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO))) { appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"), + libpq_gettext("private key file \"%s\" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root.\n"), fnbuf); return -1; }