On 11/30/2016 06:52 AM, Michael Paquier wrote:
On Mon, Nov 28, 2016 at 2:01 PM, Michael Paquier
Looking at the latest patch at code-level, there is some refactoring
to introduce initialize_context(). But it is actually not necessary
(perhaps this is the remnant of a past version?) as be_tls_init() is
its only caller. This patch makes hard to look at the diffs, and it
makes future back-patching more complicated, so I would suggest
simplifying the patch as much as possible. You could use for example a
goto block for the error code path to free the context with
SSL_CTX_free(), and set up ssl_loaded_verify_locations once the CA is
loaded. The same applies to initialize_ecdh().
+ if (secure_initialize() != 0)
+ ereport(FATAL,
+ (errmsg("could not load ssl context")));
+ LoadedSSL = true;
In case of a failure, a LOG message would have been already generated,
so this duplicates the information. Worse, if log_min_messages is set
to a level higher than LOG, users *lose* information on what has
happened. I think that secure_initialize() should have an argument to
define elevel and that this routine should be in charge of generating
an error message. Having it return a status code is necessary, but you
could cast secure_initialize() with (void) to show that we don't care
about the status code in this case. There is no need to care about
freeing the new context when the FATAL code path is used as process
would just shut down.
Thanks, this is a really good suggestion which made the diff much
cleaner. I removed my new macro too now since I felt it mostly made the
code more cryptic just to gain a few lines of code.
config.sgml needs to be updated to reflect that the SSL parameters are
updated at server reload (mentioned already upthread, just
re-mentioning it to group all the comments in one place).
Thanks, fixed this.
As this patch could be really simplified this way, I am marking is as
returned with feedback.
I have attached a new version. The commitfest should technically have
been closed by now, so do what you like with the status. I can always
submit the patch to the next commitfest.
Andreas
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index b1c5289..5f80930 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -959,9 +959,8 @@ include_dir 'conf.d'
<para>
Enables <acronym>SSL</> connections. Please read
<xref linkend="ssl-tcp"> before using this. The default
- is <literal>off</>. This parameter can only be set at server
- start. <acronym>SSL</> communication is only possible with
- TCP/IP connections.
+ is <literal>off</>. <acronym>SSL</> communication is only
+ possible with TCP/IP connections.
</para>
</listitem>
</varlistentry>
@@ -979,7 +978,7 @@ include_dir 'conf.d'
and client certificate verification is not performed. (In previous
releases of PostgreSQL, the name of this file was hard-coded
as <filename>root.crt</filename>.) Relative paths are relative to the
- data directory. This parameter can only be set at server start.
+ data directory.
</para>
</listitem>
</varlistentry>
@@ -994,8 +993,7 @@ include_dir 'conf.d'
<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.
+ relative to the data directory.
</para>
</listitem>
</varlistentry>
@@ -1012,8 +1010,7 @@ include_dir 'conf.d'
revocation list (CRL). The default is empty, meaning no CRL file is
loaded. (In previous releases of PostgreSQL, the name of this file was
hard-coded as <filename>root.crl</filename>.) Relative paths are
- relative to the data directory. This parameter can only be set at
- server start.
+ relative to the data directory.
</para>
</listitem>
</varlistentry>
@@ -1028,8 +1025,7 @@ include_dir 'conf.d'
<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.
+ relative to the data directory.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 787cfce..5e78d81 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -2288,8 +2288,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
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.
+ are examined when reloading the configuration, or when spawning the backend
+ process on <systemitem class="osname">Windows</> systems.
</para>
</sect2>
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 668f217..ebd00de 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -77,12 +77,13 @@ static DH *generate_dh_parameters(int prime_len, int generator);
static DH *tmp_dh_cb(SSL *s, int is_export, int keylength);
static int verify_cb(int, X509_STORE_CTX *);
static void info_cb(const SSL *ssl, int type, int args);
-static void initialize_ecdh(void);
+static bool initialize_ecdh(SSL_CTX *context, bool failOnError);
static const char *SSLerrmessage(unsigned long ecode);
static char *X509_NAME_to_cstring(X509_NAME *name);
static SSL_CTX *SSL_context = NULL;
+static bool SSL_initialized = false;
/* ------------------------------------------------------------ */
/* Hardcoded values */
@@ -154,17 +155,19 @@ KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
/* Public interface */
/* ------------------------------------------------------------ */
+
/*
* Initialize global SSL context.
*/
-void
-be_tls_init(void)
+int
+be_tls_init(bool failOnError)
{
struct stat buf;
- STACK_OF(X509_NAME) *root_cert_list = NULL;
+ STACK_OF(X509_NAME) *root_cert_list = NULL;
+ SSL_CTX *context;
- if (!SSL_context)
+ if (!SSL_initialized)
{
#ifdef HAVE_OPENSSL_INIT_SSL
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
@@ -173,121 +176,153 @@ be_tls_init(void)
SSL_library_init();
SSL_load_error_strings();
#endif
+ SSL_initialized = true;
+ }
- /*
- * We use SSLv23_method() because it can negotiate use of the highest
- * mutually supported protocol version, while alternatives like
- * TLSv1_2_method() permit only one specific version. Note that we
- * don't actually allow SSL v2 or v3, only TLS protocols (see below).
- */
- SSL_context = SSL_CTX_new(SSLv23_method());
- if (!SSL_context)
- ereport(FATAL,
- (errmsg("could not create SSL context: %s",
- SSLerrmessage(ERR_get_error()))));
+ /*
+ * We use SSLv23_method() because it can negotiate use of the highest
+ * mutually supported protocol version, while alternatives like
+ * TLSv1_2_method() permit only one specific version. Note that we don't
+ * actually allow SSL v2 or v3, only TLS protocols (see below).
+ */
+ context = SSL_CTX_new(SSLv23_method());
+ if (!context)
+ {
+ ereport(failOnError ? FATAL : WARNING,
+ (errmsg("could not create SSL context: %s",
+ SSLerrmessage(ERR_get_error()))));
+ goto error;
+ }
- /*
- * Disable OpenSSL's moving-write-buffer sanity check, because it
- * causes unnecessary failures in nonblocking send cases.
- */
- SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+ /*
+ * Disable OpenSSL's moving-write-buffer sanity check, because it causes
+ * unnecessary failures in nonblocking send cases.
+ */
+ SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
- /*
- * Load and verify server's certificate and private key
- */
- if (SSL_CTX_use_certificate_chain_file(SSL_context,
- ssl_cert_file) != 1)
- ereport(FATAL,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("could not load server certificate file \"%s\": %s",
- ssl_cert_file, SSLerrmessage(ERR_get_error()))));
-
- if (stat(ssl_key_file, &buf) != 0)
- ereport(FATAL,
- (errcode_for_file_access(),
- errmsg("could not access private key file \"%s\": %m",
- ssl_key_file)));
-
- if (!S_ISREG(buf.st_mode))
- ereport(FATAL,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("private key file \"%s\" is not a regular file",
- ssl_key_file)));
+ /*
+ * Load and verify server's certificate and private key
+ */
+ if (SSL_CTX_use_certificate_chain_file(context, ssl_cert_file) != 1)
+ {
+ ereport(failOnError ? FATAL : WARNING,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("could not load server certificate file \"%s\": %s",
+ ssl_cert_file, SSLerrmessage(ERR_get_error()))));
+ goto error;
+ }
- /*
- * Refuse to load files owned by users other than us or root.
- *
- * XXX surely we can check this on Windows somehow, too.
- */
+ if (stat(ssl_key_file, &buf) != 0)
+ {
+ ereport(failOnError ? FATAL : WARNING,
+ (errcode_for_file_access(),
+ errmsg("could not access private key file \"%s\": %m",
+ ssl_key_file)));
+ goto error;
+ }
+
+ if (!S_ISREG(buf.st_mode))
+ {
+ ereport(failOnError ? FATAL : WARNING,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("private key file \"%s\" is not a regular file",
+ ssl_key_file)));
+ goto error;
+ }
+
+ /*
+ * Refuse to load files owned by users other than us or root.
+ *
+ * XXX surely we can check this on Windows somehow, too.
+ */
#if !defined(WIN32) && !defined(__CYGWIN__)
- if (buf.st_uid != geteuid() && buf.st_uid != 0)
- ereport(FATAL,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("private key file \"%s\" must be owned by the database user or root",
- ssl_key_file)));
+ if (buf.st_uid != geteuid() && buf.st_uid != 0)
+ {
+ ereport(failOnError ? FATAL : WARNING,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("private key file \"%s\" must be owned by the database user or root",
+ ssl_key_file)));
+ goto error;
+ }
#endif
- /*
- * Require no public access to key file. If the file is owned by us,
- * require mode 0600 or less. If owned by root, require 0640 or less
- * to allow read access through our gid, or a supplementary gid that
- * allows to read system-wide certificates.
- *
- * XXX temporarily suppress check when on Windows, because there may
- * not be proper support for Unix-y file permissions. Need to think
- * of a reasonable check to apply on Windows. (See also the data
- * directory permission check in postmaster.c)
- */
+ /*
+ * Require no public access to key file. If the file is owned by us,
+ * require mode 0600 or less. If owned by root, require 0640 or less
+ * to allow read access through our gid, or a supplementary gid that
+ * allows to read system-wide certificates.
+ *
+ * XXX temporarily suppress check when on Windows, because there may
+ * not be proper support for Unix-y file permissions. Need to think
+ * of a reasonable check to apply on Windows. (See also the data
+ * directory permission check in postmaster.c)
+ */
#if !defined(WIN32) && !defined(__CYGWIN__)
- if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) ||
- (buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)))
- ereport(FATAL,
- (errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("private key file \"%s\" has group or world access",
- ssl_key_file),
- errdetail("File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root.")));
+ if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) ||
+ (buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)))
+ {
+ ereport(failOnError ? FATAL : WARNING,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("private key file \"%s\" has group or world access",
+ ssl_key_file),
+ errdetail("File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root.")));
+ goto error;
+ }
#endif
- if (SSL_CTX_use_PrivateKey_file(SSL_context,
- ssl_key_file,
- SSL_FILETYPE_PEM) != 1)
- ereport(FATAL,
- (errmsg("could not load private key file \"%s\": %s",
- ssl_key_file, SSLerrmessage(ERR_get_error()))));
-
- if (SSL_CTX_check_private_key(SSL_context) != 1)
- ereport(FATAL,
- (errmsg("check of private key failed: %s",
- SSLerrmessage(ERR_get_error()))));
+ if (SSL_CTX_use_PrivateKey_file(context,
+ ssl_key_file,
+ SSL_FILETYPE_PEM) != 1)
+ {
+ ereport(failOnError ? FATAL : WARNING,
+ (errmsg("could not load private key file \"%s\": %s",
+ ssl_key_file, SSLerrmessage(ERR_get_error()))));
+ goto error;
+ }
+
+ if (SSL_CTX_check_private_key(context) != 1)
+ {
+ ereport(failOnError ? FATAL : WARNING,
+ (errmsg("check of private key failed: %s",
+ SSLerrmessage(ERR_get_error()))));
+ goto error;
}
/* set up ephemeral DH keys, and disallow SSL v2/v3 while at it */
- SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
- SSL_CTX_set_options(SSL_context,
+ SSL_CTX_set_tmp_dh_callback(context, tmp_dh_cb);
+ SSL_CTX_set_options(context,
SSL_OP_SINGLE_DH_USE |
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
/* set up ephemeral ECDH keys */
- initialize_ecdh();
+ if (!initialize_ecdh(context, failOnError))
+ goto error;
/* set up the allowed cipher list */
- if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
- elog(FATAL, "could not set the cipher list (no valid ciphers available)");
+ if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
+ {
+ ereport(failOnError ? FATAL : WARNING,
+ (errmsg("could not set the cipher list (no valid ciphers available)")));
+ goto error;
+ }
/* Let server choose order */
if (SSLPreferServerCiphers)
- SSL_CTX_set_options(SSL_context, SSL_OP_CIPHER_SERVER_PREFERENCE);
+ SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
/*
* Load CA store, so we can verify client certificates if needed.
*/
if (ssl_ca_file[0])
{
- if (SSL_CTX_load_verify_locations(SSL_context, ssl_ca_file, NULL) != 1 ||
+ if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
(root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
- ereport(FATAL,
+ {
+ ereport(failOnError ? FATAL : WARNING,
(errmsg("could not load root certificate file \"%s\": %s",
ssl_ca_file, SSLerrmessage(ERR_get_error()))));
+ goto error;
+ }
}
/*----------
@@ -297,7 +332,7 @@ be_tls_init(void)
*/
if (ssl_crl_file[0])
{
- X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);
+ X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
if (cvstore)
{
@@ -316,9 +351,12 @@ be_tls_init(void)
#endif
}
else
- ereport(FATAL,
+ {
+ ereport(failOnError ? FATAL : WARNING,
(errmsg("could not load SSL certificate revocation list file \"%s\": %s",
ssl_crl_file, SSLerrmessage(ERR_get_error()))));
+ goto error;
+ }
}
}
@@ -329,7 +367,7 @@ be_tls_init(void)
* presented. We might fail such connections later, depending on what
* we find in pg_hba.conf.
*/
- SSL_CTX_set_verify(SSL_context,
+ SSL_CTX_set_verify(context,
(SSL_VERIFY_PEER |
SSL_VERIFY_CLIENT_ONCE),
verify_cb);
@@ -342,8 +380,31 @@ be_tls_init(void)
* CertificateRequests. This lets a client with a keystore select the
* appropriate client certificate to send to us.
*/
- SSL_CTX_set_client_CA_list(SSL_context, root_cert_list);
+ SSL_CTX_set_client_CA_list(context, root_cert_list);
}
+ else
+ ssl_loaded_verify_locations = false;
+
+
+ SSL_CTX_free(SSL_context);
+ SSL_context = context;
+
+ return 0;
+
+error:
+ SSL_CTX_free(context); \
+
+ return -1;
+}
+
+/*
+ * Destroy global SSL context.
+ */
+void
+be_tls_destroy(void)
+{
+ SSL_CTX_free(SSL_context);
+ SSL_context = NULL;
}
/*
@@ -1034,8 +1095,8 @@ info_cb(const SSL *ssl, int type, int args)
}
}
-static void
-initialize_ecdh(void)
+static bool
+initialize_ecdh(SSL_CTX *context, bool failOnError)
{
#ifndef OPENSSL_NO_ECDH
EC_KEY *ecdh;
@@ -1043,18 +1104,26 @@ initialize_ecdh(void)
nid = OBJ_sn2nid(SSLECDHCurve);
if (!nid)
- ereport(FATAL,
+ {
+ ereport(failOnError ? FATAL : WARNING,
(errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
+ return false;
+ }
ecdh = EC_KEY_new_by_curve_name(nid);
if (!ecdh)
- ereport(FATAL,
+ {
+ ereport(failOnError ? FATAL : WARNING,
(errmsg("ECDH: could not create key")));
+ return false;
+ }
- SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_ECDH_USE);
- SSL_CTX_set_tmp_ecdh(SSL_context, ecdh);
+ SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
+ SSL_CTX_set_tmp_ecdh(context, ecdh);
EC_KEY_free(ecdh);
#endif
+
+ return true;
}
/*
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index b267507..bd45da4 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -64,15 +64,28 @@ bool SSLPreferServerCiphers;
/*
* Initialize global context
+ *
+ * Returns 0 if OK, -1 on failure.
*/
int
-secure_initialize(void)
+secure_initialize(bool failOnError)
{
#ifdef USE_SSL
- be_tls_init();
+ return be_tls_init(failOnError);
+#else
+ return 0;
#endif
+}
- return 0;
+/*
+ * Destroy global context
+ */
+void
+secure_destroy(void)
+{
+#ifdef USE_SSL
+ be_tls_destroy();
+#endif
}
/*
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 24add74..78b7c39 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -241,6 +241,9 @@ bool enable_bonjour = false;
char *bonjour_name;
bool restart_after_crash = true;
+/* Set when and if SSL has been initialized properly */
+static bool LoadedSSL = false;
+
/* PIDs of special child processes; 0 when not running */
static pid_t StartupPID = 0,
BgWriterPID = 0,
@@ -929,7 +932,10 @@ PostmasterMain(int argc, char *argv[])
*/
#ifdef USE_SSL
if (EnableSSL)
- secure_initialize();
+ {
+ (void) secure_initialize(true);
+ LoadedSSL = true;
+ }
#endif
/*
@@ -1958,7 +1964,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
#ifdef USE_SSL
/* No SSL when disabled or on Unix sockets */
- if (!EnableSSL || IS_AF_UNIX(port->laddr.addr.ss_family))
+ if (!LoadedSSL || IS_AF_UNIX(port->laddr.addr.ss_family))
SSLok = 'N';
else
SSLok = 'S'; /* Support for SSL */
@@ -2511,6 +2517,22 @@ SIGHUP_handler(SIGNAL_ARGS)
ereport(WARNING,
(errmsg("pg_ident.conf not reloaded")));
+#ifdef USE_SSL
+ if (EnableSSL)
+ {
+ if (secure_initialize(false) != 0)
+ ereport(WARNING,
+ (errmsg("ssl context not reloaded")));
+ else
+ LoadedSSL = true;
+ }
+ else
+ {
+ secure_destroy();
+ LoadedSSL = false;
+ }
+#endif
+
#ifdef EXEC_BACKEND
/* Update the starting-point file for future children */
write_nondefault_variables(PGC_SIGHUP);
@@ -4734,7 +4756,10 @@ SubPostmasterMain(int argc, char *argv[])
*/
#ifdef USE_SSL
if (EnableSSL)
- secure_initialize();
+ {
+ (void) secure_initialize(true);
+ LoadedSSL = true;
+ }
#endif
/*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 28ebcb6..8ae99cc 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -935,7 +935,7 @@ static struct config_bool ConfigureNamesBool[] =
NULL, NULL, NULL
},
{
- {"ssl", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ {"ssl", PGC_SIGHUP, CONN_AUTH_SECURITY,
gettext_noop("Enables SSL connections."),
NULL
},
@@ -944,7 +944,7 @@ static struct config_bool ConfigureNamesBool[] =
check_ssl, NULL, NULL
},
{
- {"ssl_prefer_server_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ {"ssl_prefer_server_ciphers", PGC_SIGHUP, CONN_AUTH_SECURITY,
gettext_noop("Give priority to server ciphersuite order."),
NULL
},
@@ -3435,7 +3435,7 @@ static struct config_string ConfigureNamesString[] =
},
{
- {"ssl_cert_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ {"ssl_cert_file", PGC_SIGHUP, CONN_AUTH_SECURITY,
gettext_noop("Location of the SSL server certificate file."),
NULL
},
@@ -3445,7 +3445,7 @@ static struct config_string ConfigureNamesString[] =
},
{
- {"ssl_key_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ {"ssl_key_file", PGC_SIGHUP, CONN_AUTH_SECURITY,
gettext_noop("Location of the SSL server private key file."),
NULL
},
@@ -3455,7 +3455,7 @@ static struct config_string ConfigureNamesString[] =
},
{
- {"ssl_ca_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ {"ssl_ca_file", PGC_SIGHUP, CONN_AUTH_SECURITY,
gettext_noop("Location of the SSL certificate authority file."),
NULL
},
@@ -3465,7 +3465,7 @@ static struct config_string ConfigureNamesString[] =
},
{
- {"ssl_crl_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ {"ssl_crl_file", PGC_SIGHUP, CONN_AUTH_SECURITY,
gettext_noop("Location of the SSL certificate revocation list file."),
NULL
},
@@ -3507,7 +3507,7 @@ static struct config_string ConfigureNamesString[] =
},
{
- {"ssl_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ {"ssl_ciphers", PGC_SIGHUP, CONN_AUTH_SECURITY,
gettext_noop("Sets the list of allowed SSL ciphers."),
NULL,
GUC_SUPERUSER_ONLY
@@ -3522,7 +3522,7 @@ static struct config_string ConfigureNamesString[] =
},
{
- {"ssl_ecdh_curve", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ {"ssl_ecdh_curve", PGC_SIGHUP, CONN_AUTH_SECURITY,
gettext_noop("Sets the curve to use for ECDH."),
NULL,
GUC_SUPERUSER_ONLY
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 0df1538..bd7308b 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -76,15 +76,14 @@
# - Security and Authentication -
#authentication_timeout = 1min # 1s-600s
-#ssl = off # (change requires restart)
+#ssl = off
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
- # (change requires restart)
-#ssl_prefer_server_ciphers = on # (change requires restart)
-#ssl_ecdh_curve = 'prime256v1' # (change requires restart)
-#ssl_cert_file = 'server.crt' # (change requires restart)
-#ssl_key_file = 'server.key' # (change requires restart)
-#ssl_ca_file = '' # (change requires restart)
-#ssl_crl_file = '' # (change requires restart)
+#ssl_prefer_server_ciphers = on
+#ssl_ecdh_curve = 'prime256v1'
+#ssl_cert_file = 'server.crt'
+#ssl_key_file = 'server.key'
+#ssl_ca_file = ''
+#ssl_crl_file = ''
#password_encryption = md5 # md5 or plain
#db_user_namespace = off
#row_security = on
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index b91eca5..26cd60b 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -200,7 +200,8 @@ typedef struct Port
* These functions are implemented by the glue code specific to each
* SSL implementation (e.g. be-secure-openssl.c)
*/
-extern void be_tls_init(void);
+extern int be_tls_init(bool failOnError);
+extern void be_tls_destroy(void);
extern int be_tls_open_server(Port *port);
extern void be_tls_close(Port *port);
extern ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor);
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index 5fac817..66ceb2b 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -81,7 +81,7 @@ extern char *ssl_key_file;
extern char *ssl_ca_file;
extern char *ssl_crl_file;
-extern int secure_initialize(void);
+extern int secure_initialize(bool failOnError);
extern bool secure_loaded_verify_locations(void);
extern void secure_destroy(void);
extern int secure_open_server(Port *port);
diff --git a/src/test/ssl/ServerSetup.pm b/src/test/ssl/ServerSetup.pm
index d312880..20eaf76 100644
--- a/src/test/ssl/ServerSetup.pm
+++ b/src/test/ssl/ServerSetup.pm
@@ -70,7 +70,11 @@ sub configure_test_server_for_ssl
close CONF;
-# Copy all server certificates and keys, and client root cert, to the data dir
+ # ssl configuration will be placed here
+ open SSLCONF, ">$pgdata/sslconfig.conf";
+ close SSLCONF;
+
+ # Copy all server certificates and keys, and client root cert, to the data dir
copy_files("ssl/server-*.crt", $pgdata);
copy_files("ssl/server-*.key", $pgdata);
chmod(0600, glob "$pgdata/server-*.key") or die $!;
@@ -78,25 +82,14 @@ sub configure_test_server_for_ssl
copy_files("ssl/root_ca.crt", $pgdata);
copy_files("ssl/root+client.crl", $pgdata);
- # Only accept SSL connections from localhost. Our tests don't depend on this
- # but seems best to keep it as narrow as possible for security reasons.
- #
- # When connecting to certdb, also check the client certificate.
- open HBA, ">$pgdata/pg_hba.conf";
- print HBA
-"# TYPE DATABASE USER ADDRESS METHOD\n";
- print HBA
-"hostssl trustdb ssltestuser $serverhost/32 trust\n";
- print HBA
-"hostssl trustdb ssltestuser ::1/128 trust\n";
- print HBA
-"hostssl certdb ssltestuser $serverhost/32 cert\n";
- print HBA
-"hostssl certdb ssltestuser ::1/128 cert\n";
- close HBA;
+ # Stop and restart server to load new listen_addresses.
+ $node->restart;
+
+ # Change pg_hba after restart because hostssl requires ssl=on
+ configure_hba_for_ssl($node, $serverhost);
}
-# Change the configuration to use given server cert file, and restart
+# Change the configuration to use given server cert file, and reload
# the server so that the configuration takes effect.
sub switch_server_cert
{
@@ -105,7 +98,7 @@ sub switch_server_cert
my $cafile = $_[2] || "root+client_ca";
my $pgdata = $node->data_dir;
- diag "Restarting server with certfile \"$certfile\" and cafile \"$cafile\"...";
+ diag "Reloading server with certfile \"$certfile\" and cafile \"$cafile\"...";
open SSLCONF, ">$pgdata/sslconfig.conf";
print SSLCONF "ssl=on\n";
@@ -115,6 +108,29 @@ sub switch_server_cert
print SSLCONF "ssl_crl_file='root+client.crl'\n";
close SSLCONF;
- # Stop and restart server to reload the new config.
- $node->restart;
+ $node->reload;
+}
+
+sub configure_hba_for_ssl
+{
+ my $node = $_[0];
+ my $serverhost = $_[1];
+ my $pgdata = $node->data_dir;
+
+ # Only accept SSL connections from localhost. Our tests don't depend on this
+ # but seems best to keep it as narrow as possible for security reasons.
+ #
+ # When connecting to certdb, also check the client certificate.
+ open HBA, ">$pgdata/pg_hba.conf";
+ print HBA
+"# TYPE DATABASE USER ADDRESS METHOD\n";
+ print HBA
+"hostssl trustdb ssltestuser $serverhost/32 trust\n";
+ print HBA
+"hostssl trustdb ssltestuser ::1/128 trust\n";
+ print HBA
+"hostssl certdb ssltestuser $serverhost/32 cert\n";
+ print HBA
+"hostssl certdb ssltestuser ::1/128 cert\n";
+ close HBA;
}
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers