Don't require pqGetHomeDirectory to succeed if the user has specified
authorMagnus Hagander <magnus@hagander.net>
Wed, 7 Jan 2009 12:02:46 +0000 (12:02 +0000)
committerMagnus Hagander <magnus@hagander.net>
Wed, 7 Jan 2009 12:02:46 +0000 (12:02 +0000)
hardcoded paths for SSL rootcert/crl/clientcert/key.

As noted by Andrew Chernow

src/interfaces/libpq/fe-secure.c

index 530b3de1899a15027ced09c137118ed5c042fe9f..49ece63b49244692fff25a4a73049fca8b8aa620 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.115 2009/01/01 17:24:03 momjian Exp $
+ *   $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.116 2009/01/07 12:02:46 mha Exp $
  *
  * NOTES
  *
@@ -560,11 +560,18 @@ client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
    PGconn     *conn = (PGconn *) SSL_get_app_data(ssl);
    char        sebuf[256];
 
-   if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
+   /*
+    * If conn->sslcert  or conn->sslkey is not set, we don't need the home
+    * directory to find the required files.
+    */
+   if (!conn->sslcert || !conn->sslkey)
    {
-       printfPQExpBuffer(&conn->errorMessage,
-                         libpq_gettext("could not get user information\n"));
-       return 0;
+       if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
+       {
+           printfPQExpBuffer(&conn->errorMessage,
+                             libpq_gettext("cannot find home directory to locate client certificate files"));
+           return 0;
+       }
    }
 
    /* read the user certificate */
@@ -964,76 +971,85 @@ initialize_SSL(PGconn *conn)
     * If sslverify is set to anything other than "none", perform certificate
     * verification. If set to "cn" we will also do further verifications after
     * the connection has been completed.
+    *
+    * If we are going to look for either root certificate or CRL in the home directory,
+    * we need pqGetHomeDirectory() to succeed. In other cases, we don't need to
+    * get the home directory explicitly.
     */
-
-   /* Set up to verify server cert, if root.crt is present */
-   if (pqGetHomeDirectory(homedir, sizeof(homedir)))
+   if (!conn->sslrootcert || !conn->sslcrl)
    {
-       if (conn->sslrootcert)
-           strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
-       else
-           snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
-
-       if (stat(fnbuf, &buf) == 0)
+       if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
        {
-           X509_STORE *cvstore;
-
-           if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL))
+           if (strcmp(conn->sslverify, "none") != 0)
            {
-               char       *err = SSLerrmessage();
-
                printfPQExpBuffer(&conn->errorMessage,
-                                 libpq_gettext("could not read root certificate file \"%s\": %s\n"),
-                                 fnbuf, err);
-               SSLerrfree(err);
+                                 libpq_gettext("cannot find home directory to locate root certificate file"));
                return -1;
            }
+       }
+   }
+   else
+   {
+       homedir[0] = '\0';
+   }
 
-           if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
-           {
-               if (conn->sslcrl)
-                   strncpy(fnbuf, conn->sslcrl, sizeof(fnbuf));
-               else
-                   snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
 
-               /* setting the flags to check against the complete CRL chain */
-               if (X509_STORE_load_locations(cvstore, fnbuf, NULL) != 0)
-/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
-#ifdef X509_V_FLAG_CRL_CHECK
-                   X509_STORE_set_flags(cvstore,
-                         X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
-               /* if not found, silently ignore;  we do not require CRL */
-#else
-               {
-                   char       *err = SSLerrmessage();
 
-                   printfPQExpBuffer(&conn->errorMessage,
-                                     libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"),
-                                     fnbuf);
-                   SSLerrfree(err);
-                   return -1;
-               }
-#endif
-           }
+   if (conn->sslrootcert)
+       strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
+   else
+       snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
+
+   if (stat(fnbuf, &buf) == 0)
+   {
+       X509_STORE *cvstore;
+
+       if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL))
+       {
+           char       *err = SSLerrmessage();
 
-           SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb);
+           printfPQExpBuffer(&conn->errorMessage,
+                             libpq_gettext("could not read root certificate file \"%s\": %s\n"),
+                             fnbuf, err);
+           SSLerrfree(err);
+           return -1;
        }
-       else
+
+       if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
        {
-           if (strcmp(conn->sslverify, "none") != 0)
+           if (conn->sslcrl)
+               strncpy(fnbuf, conn->sslcrl, sizeof(fnbuf));
+           else
+               snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
+
+           /* setting the flags to check against the complete CRL chain */
+           if (X509_STORE_load_locations(cvstore, fnbuf, NULL) != 0)
+/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
+#ifdef X509_V_FLAG_CRL_CHECK
+               X509_STORE_set_flags(cvstore,
+                     X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
+           /* if not found, silently ignore;  we do not require CRL */
+#else
            {
+               char       *err = SSLerrmessage();
+
                printfPQExpBuffer(&conn->errorMessage,
-                                 libpq_gettext("root certificate file (%s) not found"), fnbuf);
+                                 libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"),
+                                 fnbuf);
+               SSLerrfree(err);
                return -1;
            }
+#endif
        }
-   }
+
+       SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb);
+   } /* root certificate exists */
    else
    {
        if (strcmp(conn->sslverify, "none") != 0)
        {
            printfPQExpBuffer(&conn->errorMessage,
-                             libpq_gettext("cannot find home directory to locate root certificate file"));
+                             libpq_gettext("root certificate file (%s) not found"), fnbuf);
            return -1;
        }
    }