summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2008-03-31 02:43:14 +0000
committerTom Lane2008-03-31 02:43:14 +0000
commit49ba65bb2e41c0e739cdccf4b6ae8b57f92ca175 (patch)
tree4092146a9fc694d9b53b767271d108fa28c1965b
parent91813267b2763ea11020f62e7f9603a7b5335100 (diff)
Use error message wordings for permissions checks on .pgpass and SSL private
key files that are similar to the one for the postmaster's data directory permissions check. (I chose to standardize on that one since it's the most heavily used and presumably best-wordsmithed by now.) Also eliminate explicit tests on file ownership in these places, since the ensuing read attempt must fail anyway if it's wrong, and there seems no value in issuing the same error message for distinct problems. (But I left in the explicit ownership test in postmaster.c, since it had its own error message anyway.) Also be more specific in the documentation's descriptions of these checks. Per a gripe from Kevin Hunter.
-rw-r--r--doc/src/sgml/libpq.sgml10
-rw-r--r--doc/src/sgml/runtime.sgml13
-rw-r--r--src/backend/libpq/be-secure.c9
-rw-r--r--src/backend/postmaster/postmaster.c7
-rw-r--r--src/interfaces/libpq/fe-connect.c5
-rw-r--r--src/interfaces/libpq/fe-secure.c7
6 files changed, 33 insertions, 18 deletions
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index fe9f187f3f..921e0629cc 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -5223,11 +5223,13 @@ defaultNoticeProcessor(void *arg, const char *message)
authorities (<acronym>CA</acronym>) trusted by the server. A matching
private key file <filename>~/.postgresql/postgresql.key</> must also
be present, unless the secret key for the certificate is stored in a
- hardware token, as specified by <envar>PGSSLKEY</envar>. (On Microsoft
- Windows these files are named
+ hardware token, as specified by <envar>PGSSLKEY</envar>. The private
+ key file must not allow any access to world or group; achieve this by the
+ command <command>chmod 0600 ~/.postgresql/postgresql.key</command>.
+ On Microsoft Windows these files are named
<filename>%APPDATA%\postgresql\postgresql.crt</filename> and
- <filename>%APPDATA%\postgresql\postgresql.key</filename>.) The private
- key file must not be world-readable.
+ <filename>%APPDATA%\postgresql\postgresql.key</filename>, and there
+ is no special permissions check since the directory is presumed secure.
</para>
<para>
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 81d274b541..a64c6f148a 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1632,7 +1632,11 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
To start in <acronym>SSL</> mode, the files <filename>server.crt</>
and <filename>server.key</> must exist in the server's data directory.
These files should contain the server certificate and private key,
- respectively. If the private key is protected with a passphrase, the
+ respectively.
+ On Unix systems, the permissions on <filename>server.key</filename> must
+ disallow any access to world or group; achieve this by the command
+ <command>chmod 0600 server.key</command>.
+ If the private key is protected with a passphrase, the
server will prompt for the passphrase and will not start until it has
been entered.
</para>
@@ -1731,10 +1735,15 @@ rm privkey.pem
Enter the old passphrase to unlock the existing key. Now do:
<programlisting>
openssl req -x509 -in server.req -text -key server.key -out server.crt
-chmod og-rwx server.key
</programlisting>
to turn the certificate into a self-signed certificate and to copy
the key and certificate to where the server will look for them.
+ Finally do
+<programlisting>
+chmod og-rwx server.key
+</programlisting>
+ because the server will reject the file if its permissions are more
+ liberal than this.
For more details on how to create your server private key and
certificate, refer to the <productname>OpenSSL</> documentation.
</para>
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index 629c303385..8dc7be2701 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -735,7 +735,7 @@ initialize_SSL(void)
errmsg("could not load server certificate file \"%s\": %s",
SERVER_CERT_FILE, SSLerrmessage())));
- if (stat(SERVER_PRIVATE_KEY_FILE, &buf) == -1)
+ if (stat(SERVER_PRIVATE_KEY_FILE, &buf) != 0)
ereport(FATAL,
(errcode_for_file_access(),
errmsg("could not access private key file \"%s\": %m",
@@ -750,13 +750,12 @@ initialize_SSL(void)
* directory permission check in postmaster.c)
*/
#if !defined(WIN32) && !defined(__CYGWIN__)
- if (!S_ISREG(buf.st_mode) || (buf.st_mode & (S_IRWXG | S_IRWXO)) ||
- buf.st_uid != geteuid())
+ if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
ereport(FATAL,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("unsafe permissions on private key file \"%s\"",
+ errmsg("private key file \"%s\" has group or world access",
SERVER_PRIVATE_KEY_FILE),
- errdetail("File must be owned by the database user and must have no permissions for \"group\" or \"other\".")));
+ errdetail("Permissions should be u=rw (0600) or less.")));
#endif
if (!SSL_CTX_use_PrivateKey_file(SSL_context,
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index bb4a04962a..90c4a0cec1 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1053,6 +1053,13 @@ checkDataDir(void)
DataDir)));
}
+ /* eventual chdir would fail anyway, but let's test ... */
+ if (!S_ISDIR(stat_buf.st_mode))
+ ereport(FATAL,
+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+ errmsg("specified data directory \"%s\" is not a directory",
+ DataDir)));
+
/*
* Check that the directory belongs to my userid; if not, reject.
*
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 27d4a200a4..375f7084b6 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -3718,11 +3718,10 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
}
/* If password file cannot be opened, ignore it. */
- if (stat(pgpassfile, &stat_buf) == -1)
+ if (stat(pgpassfile, &stat_buf) != 0)
return NULL;
#ifndef WIN32
-
if (!S_ISREG(stat_buf.st_mode))
{
fprintf(stderr,
@@ -3735,7 +3734,7 @@ PasswordFromFile(char *hostname, char *port, char *dbname, char *username)
if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
{
fprintf(stderr,
- libpq_gettext("WARNING: password file \"%s\" has world or group read access; permission should be u=rw (0600)\n"),
+ libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
pgpassfile);
return NULL;
}
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 59db386d93..9e6ad64e62 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -703,7 +703,7 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
{
/* read the user key from file */
snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
- if (stat(fnbuf, &buf) == -1)
+ if (stat(fnbuf, &buf) != 0)
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("certificate present, but not private key file \"%s\"\n"),
@@ -712,11 +712,10 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
return 0;
}
#ifndef WIN32
- if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
- buf.st_uid != geteuid())
+ if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
{
printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("private key file \"%s\" has wrong permissions\n"),
+ libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
fnbuf);
ERR_pop_to_mark();
return 0;