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