On 11/11/2016 07:40 PM, Andreas Karlsson wrote:
Hi,

Here is a new version of the patch with the only differences;

1) The SSL tests have been changed to use reload rather than restart

2) Rebased on master

And here with a fix to a comment.

Andreas

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..8449a53 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -77,12 +77,14 @@ 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 SSL_CTX *initialize_context(void);
+static bool initialize_ecdh(SSL_CTX *context);
 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						*/
@@ -157,14 +159,12 @@ KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
 /*
  *	Initialize global SSL context.
  */
-void
+int
 be_tls_init(void)
 {
-	struct stat buf;
+	SSL_CTX *context;
 
-	STACK_OF(X509_NAME) *root_cert_list = NULL;
-
-	if (!SSL_context)
+	if (!SSL_initialized)
 	{
 #ifdef HAVE_OPENSSL_INIT_SSL
 		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
@@ -173,177 +173,29 @@ be_tls_init(void)
 		SSL_library_init();
 		SSL_load_error_strings();
 #endif
-
-		/*
-		 * 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()))));
-
-		/*
-		 * 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);
-
-		/*
-		 * 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)));
-
-		/*
-		 * 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)));
-#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)
-		 */
-#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.")));
-#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()))));
+		SSL_initialized = true;
 	}
 
-	/* 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_OP_SINGLE_DH_USE |
-						SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
-
-	/* set up ephemeral ECDH keys */
-	initialize_ecdh();
-
-	/* 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)");
-
-	/* Let server choose order */
-	if (SSLPreferServerCiphers)
-		SSL_CTX_set_options(SSL_context, SSL_OP_CIPHER_SERVER_PREFERENCE);
-
-	/*
-	 * Load CA store, so we can verify client certificates if needed.
-	 */
-	if (ssl_ca_file[0])
+	if ((context = initialize_context()) != NULL)
 	{
-		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)
-			ereport(FATAL,
-					(errmsg("could not load root certificate file \"%s\": %s",
-							ssl_ca_file, SSLerrmessage(ERR_get_error()))));
-	}
-
-	/*----------
-	 * Load the Certificate Revocation List (CRL).
-	 * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
-	 *----------
-	 */
-	if (ssl_crl_file[0])
-	{
-		X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);
-
-		if (cvstore)
-		{
-			/* Set the flags to check against the complete CRL chain */
-			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
-				X509_STORE_set_flags(cvstore,
-						  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
-#else
-				ereport(LOG,
-				(errmsg("SSL certificate revocation list file \"%s\" ignored",
-						ssl_crl_file),
-				 errdetail("SSL library does not support certificate revocation lists.")));
-#endif
-			}
-			else
-				ereport(FATAL,
-						(errmsg("could not load SSL certificate revocation list file \"%s\": %s",
-							 ssl_crl_file, SSLerrmessage(ERR_get_error()))));
-		}
+		SSL_CTX_free(SSL_context);
+		SSL_context = context;
+		/* Set flag to remember if CA store is successfully loaded */
+		ssl_loaded_verify_locations = ssl_ca_file[0] != '\0';
+		return 0;
 	}
 
-	if (ssl_ca_file[0])
-	{
-		/*
-		 * Always ask for SSL client cert, but don't fail if it's not
-		 * presented.  We might fail such connections later, depending on what
-		 * we find in pg_hba.conf.
-		 */
-		SSL_CTX_set_verify(SSL_context,
-						   (SSL_VERIFY_PEER |
-							SSL_VERIFY_CLIENT_ONCE),
-						   verify_cb);
-
-		/* Set flag to remember CA store is successfully loaded */
-		ssl_loaded_verify_locations = true;
+	return -1;
+}
 
-		/*
-		 * Tell OpenSSL to send the list of root certs we trust to clients in
-		 * 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);
-	}
+/*
+ *	Destroy global SSL context.
+ */
+void
+be_tls_destroy(void)
+{
+	SSL_CTX_free(SSL_context);
+	SSL_context = NULL;
 }
 
 /*
@@ -1034,8 +886,194 @@ info_cb(const SSL *ssl, int type, int args)
 	}
 }
 
-static void
-initialize_ecdh(void)
+#define INIT_CONTEXT_ERROR(error) do { \
+	ereport(LOG, error); \
+	SSL_CTX_free(context); \
+	return NULL; \
+} while (0)
+
+static SSL_CTX *
+initialize_context(void)
+{
+	struct stat 			buf;
+	STACK_OF(X509_NAME)	   *root_cert_list = NULL;
+	SSL_CTX				   *context;
+
+	/*
+	 * 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)
+		INIT_CONTEXT_ERROR(
+				(errmsg("could not create SSL context: %s",
+						SSLerrmessage(ERR_get_error()))));
+
+	/*
+	 * 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(context, ssl_cert_file) != 1)
+		INIT_CONTEXT_ERROR(
+				(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)
+		INIT_CONTEXT_ERROR(
+				(errcode_for_file_access(),
+				 errmsg("could not access private key file \"%s\": %m",
+						ssl_key_file)));
+
+	if (!S_ISREG(buf.st_mode))
+		INIT_CONTEXT_ERROR(
+				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+				 errmsg("private key file \"%s\" is not a regular file",
+						ssl_key_file)));
+
+	/*
+	 * 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)
+		INIT_CONTEXT_ERROR(
+				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+				 errmsg("private key file \"%s\" must be owned by the database user or root",
+						ssl_key_file)));
+#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)
+	 */
+#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)))
+		INIT_CONTEXT_ERROR(
+				(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.")));
+#endif
+
+	if (SSL_CTX_use_PrivateKey_file(context,
+									ssl_key_file,
+									SSL_FILETYPE_PEM) != 1)
+		INIT_CONTEXT_ERROR(
+				(errmsg("could not load private key file \"%s\": %s",
+						ssl_key_file, SSLerrmessage(ERR_get_error()))));
+
+	if (SSL_CTX_check_private_key(context) != 1)
+		INIT_CONTEXT_ERROR(
+				(errmsg("check of private key failed: %s",
+						SSLerrmessage(ERR_get_error()))));
+
+	/* set up ephemeral DH keys, and disallow SSL v2/v3 while at it */
+	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 */
+	if (!initialize_ecdh(context))
+	{
+		SSL_CTX_free(context);
+		return NULL;
+	}
+
+	/* set up the allowed cipher list */
+	if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
+		INIT_CONTEXT_ERROR((errmsg("could not set the cipher list (no valid ciphers available)")));
+
+	/* Let server choose order */
+	if (SSLPreferServerCiphers)
+		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(context, ssl_ca_file, NULL) != 1 ||
+			(root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
+			INIT_CONTEXT_ERROR(
+					(errmsg("could not load root certificate file \"%s\": %s",
+							ssl_ca_file, SSLerrmessage(ERR_get_error()))));
+	}
+
+	/*----------
+	 * Load the Certificate Revocation List (CRL).
+	 * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
+	 *----------
+	 */
+	if (ssl_crl_file[0])
+	{
+		X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
+
+		if (cvstore)
+		{
+			/* Set the flags to check against the complete CRL chain */
+			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
+				X509_STORE_set_flags(cvstore,
+						  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
+#else
+				ereport(LOG,
+				(errmsg("SSL certificate revocation list file \"%s\" ignored",
+						ssl_crl_file),
+				 errdetail("SSL library does not support certificate revocation lists.")));
+#endif
+			}
+			else
+				INIT_CONTEXT_ERROR(
+						(errmsg("could not load SSL certificate revocation list file \"%s\": %s",
+							 ssl_crl_file, SSLerrmessage(ERR_get_error()))));
+		}
+	}
+
+	if (ssl_ca_file[0])
+	{
+		/*
+		 * Always ask for SSL client cert, but don't fail if it's not
+		 * presented.  We might fail such connections later, depending on what
+		 * we find in pg_hba.conf.
+		 */
+		SSL_CTX_set_verify(context,
+						   (SSL_VERIFY_PEER |
+							SSL_VERIFY_CLIENT_ONCE),
+						   verify_cb);
+
+		/*
+		 * Tell OpenSSL to send the list of root certs we trust to clients in
+		 * CertificateRequests.  This lets a client with a keystore select the
+		 * appropriate client certificate to send to us.
+		 */
+		SSL_CTX_set_client_CA_list(context, root_cert_list);
+	}
+
+	return context;
+}
+
+static bool
+initialize_ecdh(SSL_CTX *context)
 {
 #ifndef OPENSSL_NO_ECDH
 	EC_KEY	   *ecdh;
@@ -1043,18 +1081,26 @@ initialize_ecdh(void)
 
 	nid = OBJ_sn2nid(SSLECDHCurve);
 	if (!nid)
-		ereport(FATAL,
+	{
+		ereport(LOG,
 				(errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
+		return false;
+	}
 
 	ecdh = EC_KEY_new_by_curve_name(nid);
 	if (!ecdh)
-		ereport(FATAL,
+	{
+		ereport(LOG,
 				(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..7d7faa6 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)
 {
 #ifdef USE_SSL
-	be_tls_init();
+	return be_tls_init();
+#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..aeb0fe6 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,12 @@ PostmasterMain(int argc, char *argv[])
 	 */
 #ifdef USE_SSL
 	if (EnableSSL)
-		secure_initialize();
+	{
+		if (secure_initialize() != 0)
+			ereport(FATAL,
+					(errmsg("could not load ssl context")));
+		LoadedSSL = true;
+	}
 #endif
 
 	/*
@@ -1958,7 +1966,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 +2519,22 @@ SIGHUP_handler(SIGNAL_ARGS)
 			ereport(WARNING,
 					(errmsg("pg_ident.conf not reloaded")));
 
+#ifdef USE_SSL
+		if (EnableSSL)
+		{
+			if (secure_initialize() != 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 +4758,12 @@ SubPostmasterMain(int argc, char *argv[])
 		 */
 #ifdef USE_SSL
 		if (EnableSSL)
-			secure_initialize();
+		{
+			if (secure_initialize() != 0)
+				ereport(FATAL,
+						(errmsg("could not load ssl context")));
+			LoadedSSL = true;
+		}
 #endif
 
 		/*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 3c695c1..4c02e62 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
 		},
@@ -3437,7 +3437,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
 		},
@@ -3447,7 +3447,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
 		},
@@ -3457,7 +3457,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
 		},
@@ -3467,7 +3467,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
 		},
@@ -3509,7 +3509,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
@@ -3524,7 +3524,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 7c2daa5..f71218d 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..9d835e3 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(void);
+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/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

Reply via email to