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 Please take a look. 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..97257bc 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,22 +82,11 @@ 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 @@ -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