diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2018-04-02 11:34:52 -0400 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2018-04-02 11:37:40 -0400 |
commit | 2764d5dcfa84d240c901c20ec6e194f72d82b78a (patch) | |
tree | 2db3da15bec088237b5b32f83de90c8cc8817e9b /src/backend/libpq/be-secure-common.c | |
parent | 7e0d64c7a57e28fbcf093b6da9310a38367c1d75 (diff) | |
download | postgresql-2764d5dcfa84d240c901c20ec6e194f72d82b78a.tar.gz postgresql-2764d5dcfa84d240c901c20ec6e194f72d82b78a.zip |
Make be-secure-common.c more consistent for future SSL implementations
Recent commit 8a3d9425 has introduced be-secure-common.c, which is aimed
at including backend-side APIs that can be used by any SSL
implementation. The purpose is similar to fe-secure-common.c for the
frontend-side APIs.
However, this has forgotten to include check_ssl_key_file_permissions()
in the move, which causes a double dependency between be-secure.c and
be-secure-openssl.c.
Refactor the code in a more logical way. This also puts into light an
API which is usable by future SSL implementations for permissions on SSL
key files.
Author: Michael Paquier <michael@paquier.xyz>
Diffstat (limited to 'src/backend/libpq/be-secure-common.c')
-rw-r--r-- | src/backend/libpq/be-secure-common.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/backend/libpq/be-secure-common.c b/src/backend/libpq/be-secure-common.c index d1740967f19..46f0b5f4a32 100644 --- a/src/backend/libpq/be-secure-common.c +++ b/src/backend/libpq/be-secure-common.c @@ -19,6 +19,9 @@ #include "postgres.h" +#include <sys/stat.h> +#include <unistd.h> + #include "libpq/libpq.h" #include "storage/fd.h" @@ -118,3 +121,74 @@ error: pfree(command.data); return len; } + + +/* + * Check permissions for SSL key files. + */ +bool +check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart) +{ + int loglevel = isServerStart ? FATAL : LOG; + struct stat buf; + + if (stat(ssl_key_file, &buf) != 0) + { + ereport(loglevel, + (errcode_for_file_access(), + errmsg("could not access private key file \"%s\": %m", + ssl_key_file))); + return false; + } + + if (!S_ISREG(buf.st_mode)) + { + ereport(loglevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("private key file \"%s\" is not a regular file", + ssl_key_file))); + return false; + } + + /* + * Refuse to load key files owned by users other than us or root. + * + * XXX surely we can check this on Windows somehow, too. + */ +#if !defined(WIN32) && !defined(__CYGWIN__) + if (buf.st_uid != geteuid() && buf.st_uid != 0) + { + ereport(loglevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("private key file \"%s\" must be owned by the database user or root", + ssl_key_file))); + return false; + } +#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. (See also the data directory + * permission check in postmaster.c) + */ +#if !defined(WIN32) && !defined(__CYGWIN__) + 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))) + { + ereport(loglevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("private key file \"%s\" has group or world access", + ssl_key_file), + errdetail("File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root."))); + return false; + } +#endif + + return true; +} |