On mån, 2012-01-02 at 06:32 +0200, Peter Eisentraut wrote:
> I think I would like to have a set of GUC parameters to control the
> location of the server-side SSL files.

Here is the patch for this.

One thing that is perhaps worth thinking about:  Currently, we just
ignore missing root.crt and root.crl files.  With this patch, we still
do this, even if the user has given a specific nondefault location.
That seems a bit odd, but I can't think of a simple way to do it better.
diff --git i/doc/src/sgml/config.sgml w/doc/src/sgml/config.sgml
index 0cc3296..519715f 100644
--- i/doc/src/sgml/config.sgml
+++ w/doc/src/sgml/config.sgml
@@ -668,6 +668,66 @@ SET ENABLE_SEQSCAN TO OFF;
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-ssl-ca-file" xreflabel="ssl_ca_file">
+      <term><varname>ssl_ca_file</varname> (<type>string</type>)</term>
+      <indexterm>
+       <primary><varname>ssl_ca_file</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Specifies the name of the file containing the SSL server certificate
+        authority.  The default is <filename>root.crt</filename>.  Relative
+        paths are relative to the data directory.  This parameter can only be
+        set at server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-ssl-cert-file" xreflabel="ssl_cert_file">
+      <term><varname>ssl_cert_file</varname> (<type>string</type>)</term>
+      <indexterm>
+       <primary><varname>ssl_cert_file</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Specifies the name of the file containing the SSL server certificate.
+        The default is <filename>server.crt</filename>.  Relative paths are
+        relative to the data directory.  This parameter can only be set at
+        server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-ssl-crl-file" xreflabel="ssl_crl_file">
+      <term><varname>ssl_crl_file</varname> (<type>string</type>)</term>
+      <indexterm>
+       <primary><varname>ssl_crl_file</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Specifies the name of the file containing the SSL server certificate
+        revocation list.  The default is <filename>root.crl</filename>.
+        Relative paths are relative to the data directory.  This parameter can
+        only be set at server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry id="guc-ssl-key-file" xreflabel="ssl_key_file">
+      <term><varname>ssl_key_file</varname> (<type>string</type>)</term>
+      <indexterm>
+       <primary><varname>ssl_key_file</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Specifies the name of the file containing the SSL server private key.
+        The default is <filename>server.key</filename>.  Relative paths are
+        relative to the data directory.  This parameter can only be set at
+        server start.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-ssl-renegotiation-limit" xreflabel="ssl_renegotiation_limit">
       <term><varname>ssl_renegotiation_limit</varname> (<type>integer</type>)</term>
       <indexterm>
diff --git i/doc/src/sgml/runtime.sgml w/doc/src/sgml/runtime.sgml
index 1c3a9c8..a855279 100644
--- i/doc/src/sgml/runtime.sgml
+++ w/doc/src/sgml/runtime.sgml
@@ -1831,10 +1831,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
    SSL certificates and make sure that clients check the server's certificate.
    To do that, the server
    must be configured to accept only <literal>hostssl</> connections (<xref
-   linkend="auth-pg-hba-conf">) and have SSL
-   <filename>server.key</filename> (key) and
-   <filename>server.crt</filename> (certificate) files (<xref
-   linkend="ssl-tcp">). The TCP client must connect using
+   linkend="auth-pg-hba-conf">) and have SSL key and certificate files
+   (<xref linkend="ssl-tcp">). The TCP client must connect using
    <literal>sslmode=verify-ca</> or
    <literal>verify-full</> and have the appropriate root certificate
    file installed (<xref linkend="libpq-connect">).
@@ -2053,10 +2051,12 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
   </note>
 
   <para>
-   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.
+   To start in <acronym>SSL</> mode, files containing the server certificate
+   and private key must exist.  By default, these files are expected to be
+   named <filename>server.crt</> and <filename>server.key</>, respectively, in
+   the server's data directory, but other names and locations can be specified
+   using the configuration parameters <xref linkend="guc-ssl-cert-file">
+   and <xref linkend="guc-ssl-key-file">.
    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>.
@@ -2144,27 +2144,27 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
     <tbody>
 
      <row>
-      <entry><filename>$PGDATA/server.crt</></entry>
+      <entry><xref linkend="guc-ssl-cert-file"> (<filename>$PGDATA/server.crt</>)</entry>
       <entry>server certificate</entry>
       <entry>sent to client to indicate server's identity</entry>
      </row>
 
      <row>
-      <entry><filename>$PGDATA/server.key</></entry>
+      <entry><xref linkend="guc-ssl-key-file"> (<filename>$PGDATA/server.key</>)</entry>
       <entry>server private key</entry>
       <entry>proves server certificate was sent by the owner; does not indicate
       certificate owner is trustworthy</entry>
      </row>
 
      <row>
-      <entry><filename>$PGDATA/root.crt</></entry>
+      <entry><xref linkend="guc-ssl-ca-file"> (<filename>$PGDATA/root.crt</>)</entry>
       <entry>trusted certificate authorities</entry>
       <entry>checks that client certificate is
       signed by a trusted certificate authority</entry>
      </row>
 
      <row>
-      <entry><filename>$PGDATA/root.crl</></entry>
+      <entry><xref linkend="guc-ssl-crl-file"> (<filename>$PGDATA/root.crl</>)</entry>
       <entry>certificates revoked by certificate authorities</entry>
       <entry>client certificate must not be on this list</entry>
      </row>
@@ -2176,6 +2176,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
    <para>
     The files <filename>server.key</>, <filename>server.crt</>,
     <filename>root.crt</filename>, and <filename>root.crl</filename>
+    (or their configured alternative names)
     are only examined during server start; so you must restart
     the server for changes in them to take effect.
    </para>
diff --git i/src/backend/libpq/be-secure.c w/src/backend/libpq/be-secure.c
index e35df73..1e34e56 100644
--- i/src/backend/libpq/be-secure.c
+++ w/src/backend/libpq/be-secure.c
@@ -77,10 +77,10 @@
 
 #ifdef USE_SSL
 
-#define ROOT_CERT_FILE			"root.crt"
-#define ROOT_CRL_FILE			"root.crl"
-#define SERVER_CERT_FILE		"server.crt"
-#define SERVER_PRIVATE_KEY_FILE "server.key"
+char *ssl_cert_file;
+char *ssl_key_file;
+char *ssl_ca_file;
+char *ssl_crl_file;
 
 static DH  *load_dh_file(int keylength);
 static DH  *load_dh_buffer(const char *, size_t);
@@ -746,17 +746,17 @@ initialize_SSL(void)
 		 * Load and verify server's certificate and private key
 		 */
 		if (SSL_CTX_use_certificate_chain_file(SSL_context,
-											   SERVER_CERT_FILE) != 1)
+											   ssl_cert_file) != 1)
 			ereport(FATAL,
 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
 				  errmsg("could not load server certificate file \"%s\": %s",
-						 SERVER_CERT_FILE, SSLerrmessage())));
+						 ssl_cert_file, SSLerrmessage())));
 
-		if (stat(SERVER_PRIVATE_KEY_FILE, &buf) != 0)
+		if (stat(ssl_key_file, &buf) != 0)
 			ereport(FATAL,
 					(errcode_for_file_access(),
 					 errmsg("could not access private key file \"%s\": %m",
-							SERVER_PRIVATE_KEY_FILE)));
+							ssl_key_file)));
 
 		/*
 		 * Require no public access to key file.
@@ -771,16 +771,16 @@ initialize_SSL(void)
 			ereport(FATAL,
 					(errcode(ERRCODE_CONFIG_FILE_ERROR),
 				  errmsg("private key file \"%s\" has group or world access",
-						 SERVER_PRIVATE_KEY_FILE),
+						 ssl_key_file),
 				   errdetail("Permissions should be u=rw (0600) or less.")));
 #endif
 
 		if (SSL_CTX_use_PrivateKey_file(SSL_context,
-										SERVER_PRIVATE_KEY_FILE,
+										ssl_key_file,
 										SSL_FILETYPE_PEM) != 1)
 			ereport(FATAL,
 					(errmsg("could not load private key file \"%s\": %s",
-							SERVER_PRIVATE_KEY_FILE, SSLerrmessage())));
+							ssl_key_file, SSLerrmessage())));
 
 		if (SSL_CTX_check_private_key(SSL_context) != 1)
 			ereport(FATAL,
@@ -802,7 +802,7 @@ initialize_SSL(void)
 	 */
 	ssl_loaded_verify_locations = false;
 
-	if (access(ROOT_CERT_FILE, R_OK) != 0)
+	if (access(ssl_ca_file, R_OK) != 0)
 	{
 		/*
 		 * If root certificate file simply not found, don't log an error here,
@@ -813,10 +813,10 @@ initialize_SSL(void)
 		if (errno != ENOENT)
 			ereport(FATAL,
 				 (errmsg("could not access root certificate file \"%s\": %m",
-						 ROOT_CERT_FILE)));
+						 ssl_ca_file)));
 	}
-	else if (SSL_CTX_load_verify_locations(SSL_context, ROOT_CERT_FILE, NULL) != 1 ||
-		  (root_cert_list = SSL_load_client_CA_file(ROOT_CERT_FILE)) == NULL)
+	else if (SSL_CTX_load_verify_locations(SSL_context, ssl_ca_file, NULL) != 1 ||
+		  (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
 	{
 		/*
 		 * File was there, but we could not load it. This means the file is
@@ -824,7 +824,7 @@ initialize_SSL(void)
 		 */
 		ereport(FATAL,
 				(errmsg("could not load root certificate file \"%s\": %s",
-						ROOT_CERT_FILE, SSLerrmessage())));
+						ssl_ca_file, SSLerrmessage())));
 	}
 	else
 	{
@@ -838,7 +838,7 @@ initialize_SSL(void)
 		if (cvstore)
 		{
 			/* Set the flags to check against the complete CRL chain */
-			if (X509_STORE_load_locations(cvstore, ROOT_CRL_FILE, NULL) == 1)
+			if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
 			{
 				/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
 #ifdef X509_V_FLAG_CRL_CHECK
@@ -847,7 +847,7 @@ initialize_SSL(void)
 #else
 				ereport(LOG,
 				(errmsg("SSL certificate revocation list file \"%s\" ignored",
-						ROOT_CRL_FILE),
+						ssl_crl_file),
 				 errdetail("SSL library does not support certificate revocation lists.")));
 #endif
 			}
@@ -856,7 +856,7 @@ initialize_SSL(void)
 				/* Not fatal - we do not require CRL */
 				ereport(LOG,
 						(errmsg("SSL certificate revocation list file \"%s\" not found, skipping: %s",
-								ROOT_CRL_FILE, SSLerrmessage()),
+								ssl_crl_file, SSLerrmessage()),
 						 errdetail("Certificates will not be checked against revocation list.")));
 			}
 
diff --git i/src/backend/utils/misc/guc.c w/src/backend/utils/misc/guc.c
index 5c910dd..11006ea 100644
--- i/src/backend/utils/misc/guc.c
+++ w/src/backend/utils/misc/guc.c
@@ -39,6 +39,7 @@
 #include "funcapi.h"
 #include "libpq/auth.h"
 #include "libpq/be-fsstubs.h"
+#include "libpq/libpq.h"
 #include "libpq/pqformat.h"
 #include "miscadmin.h"
 #include "optimizer/cost.h"
@@ -2961,6 +2962,46 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
+		{"ssl_cert_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+			gettext_noop("Location of the SSL server certificate file."),
+			NULL
+		},
+		&ssl_cert_file,
+		"server.crt",
+		NULL, NULL, NULL
+	},
+
+	{
+		{"ssl_key_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+			gettext_noop("Location of the SSL server private key file."),
+			NULL
+		},
+		&ssl_key_file,
+		"server.key",
+		NULL, NULL, NULL
+	},
+
+	{
+		{"ssl_ca_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+			gettext_noop("Location of the SSL certificate authority file."),
+			NULL
+		},
+		&ssl_ca_file,
+		"root.crt",
+		NULL, NULL, NULL
+	},
+
+	{
+		{"ssl_crl_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+			gettext_noop("Location of the SSL certificate revocation list file."),
+			NULL
+		},
+		&ssl_crl_file,
+		"root.crl",
+		NULL, NULL, NULL
+	},
+
+	{
 		{"stats_temp_directory", PGC_SIGHUP, STATS_COLLECTOR,
 			gettext_noop("Writes temporary statistics files to the specified directory."),
 			NULL,
diff --git i/src/backend/utils/misc/postgresql.conf.sample w/src/backend/utils/misc/postgresql.conf.sample
index 315db46..658c293 100644
--- i/src/backend/utils/misc/postgresql.conf.sample
+++ w/src/backend/utils/misc/postgresql.conf.sample
@@ -81,6 +81,10 @@
 #ssl_ciphers = 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH'	# allowed SSL ciphers
 					# (change requires restart)
 #ssl_renegotiation_limit = 512MB	# amount of data between renegotiations
+#ssl_cert_file = 'server.crt'		# (change requires restart)
+#ssl_key_file = 'server.key'		# (change requires restart)
+#ssl_ca_file = 'root.crt'		# (change requires restart)
+#ssl_crl_file = 'root.crl'		# (change requires restart)
 #password_encryption = on
 #db_user_namespace = off
 
diff --git i/src/include/libpq/libpq.h w/src/include/libpq/libpq.h
index a4ef7b3..7083cd8 100644
--- i/src/include/libpq/libpq.h
+++ w/src/include/libpq/libpq.h
@@ -70,6 +70,11 @@ extern void pq_endcopyout(bool errorAbort);
 /*
  * prototypes for functions in be-secure.c
  */
+extern char *ssl_cert_file;
+extern char *ssl_key_file;
+extern char *ssl_ca_file;
+extern char *ssl_crl_file;
+
 extern int	secure_initialize(void);
 extern bool secure_loaded_verify_locations(void);
 extern void secure_destroy(void);
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to