client-key-perm-002.patch
text/plain
Filename: client-key-perm-002.patch
Type: text/plain
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/libpq/be-secure-common.c | 6 | 0 |
| src/interfaces/libpq/fe-secure-openssl.c | 28 | 2 |
diff --git a/src/backend/libpq/be-secure-common.c b/src/backend/libpq/be-secure-common.c
index a212308666..c6e4329653 100644
--- a/src/backend/libpq/be-secure-common.c
+++ b/src/backend/libpq/be-secure-common.c
@@ -155,6 +155,9 @@ check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)
/*
* Refuse to load key files owned by users other than us or root.
*
+ * Note that a similar check is performed in initialize_SSL() so any changes
+ * here may need to be made there as well.
+ *
* XXX surely we can check this on Windows somehow, too.
*/
#if !defined(WIN32) && !defined(__CYGWIN__)
@@ -174,6 +177,9 @@ check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)
* allow read access through our gid, or a supplementary gid that allows
* to read system-wide certificates.
*
+ * Note that a similar check is performed in initialize_SSL() so any changes
+ * here may need to be made there as well.
+ *
* 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. (See also the data directory
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index a90d891c6c..d581ff6ca5 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1240,11 +1240,37 @@ initialize_SSL(PGconn *conn)
fnbuf);
return -1;
}
+
+ /*
+ * Refuse to load key files owned by users other than us or root and
+ * require no public access to the 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
+ * us to read system-wide certificates.
+ *
+ * Note that similar checks are performed in
+ * check_ssl_key_file_permissions() so any changes here may need to be
+ * made there as well.
+ *
+ * Ideally we would do similar checks on Windows but it is not clear how
+ * that would work since unix-style permissions may not be available. See
+ * also the data directory permissions checks in checkDataDir().
+ */
#ifndef WIN32
- if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
+ 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;
+ }
+
+ if (!S_ISREG(buf.st_mode) ||
+ (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;
}