]> granicus.if.org Git - postgresql/commitdiff
Use error message wordings for permissions checks on .pgpass and SSL private
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 31 Mar 2008 02:43:14 +0000 (02:43 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 31 Mar 2008 02:43:14 +0000 (02:43 +0000)
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.

doc/src/sgml/libpq.sgml
doc/src/sgml/runtime.sgml
src/backend/libpq/be-secure.c
src/backend/postmaster/postmaster.c
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-secure.c

index 9e63c9164187bd5c1e3e44c77500d648e44d9bbb..2f1a248ca768c42360910e2fb320a67bd8e07f43 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.256 2008/03/06 15:37:56 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.257 2008/03/31 02:43:14 tgl Exp $ -->
 
 <chapter id="libpq">
  <title><application>libpq</application> - C Library</title>
@@ -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>
index 7d89be32fb192229d043714efa300308f3327e8f..1c799d8965b60d60e49474a31d8b1e74ecec0c3e 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.410 2008/03/21 14:23:37 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.411 2008/03/31 02:43:14 tgl Exp $ -->
 
 <chapter Id="runtime">
  <title>Operating System Environment</title>
@@ -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>
index 923ad6bcb3daea346d3f9d8661df7d85c3eabdc9..d03694717620969f89a975a8694f7c6f99f7c3fa 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.83 2008/01/01 19:45:49 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.84 2008/03/31 02:43:14 tgl Exp $
  *
  *       Since the server static private key ($DataDir/server.key)
  *       will normally be stored unencrypted so that the database
@@ -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,
index 7a83e075b1898826bf2321a3de5eb0af64f948cd..7c6692b2a5dfd5a7ed5e587f2d497148a7dfe6b2 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.553 2008/03/09 04:56:28 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.554 2008/03/31 02:43:14 tgl Exp $
  *
  * NOTES
  *
@@ -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.
         *
index 90f9d4334ee40a6600d1b7c96d1aebdaf83fa084..dd6c988790bee1d64c67b650c80803c625341f39 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.356 2008/01/29 02:06:30 tgl Exp $
+ *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.357 2008/03/31 02:43:14 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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;
        }
index 3b1f4cee60c1f24675bc1ea6a5a7b66640aaf3ee..4414baba4a82d03d281ef67bf17a2261a0a3a2d8 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.103 2008/02/16 21:03:30 momjian Exp $
+ *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.104 2008/03/31 02:43:14 tgl Exp $
  *
  * NOTES
  *       [ Most of these notes are wrong/obsolete, but perhaps not all ]
@@ -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;