diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/libpq/be-secure.c | 107 | ||||
-rw-r--r-- | src/backend/libpq/hba.c | 2 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 41 | ||||
-rw-r--r-- | src/backend/utils/misc/postgresql.conf.sample | 4 | ||||
-rw-r--r-- | src/include/libpq/libpq.h | 5 |
5 files changed, 95 insertions, 64 deletions
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c index e35df730953..f0a38c238a4 100644 --- a/src/backend/libpq/be-secure.c +++ b/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, @@ -797,48 +797,30 @@ initialize_SSL(void) elog(FATAL, "could not set the cipher list (no valid ciphers available)"); /* - * Attempt to load CA store, so we can verify client certificates if - * needed. + * Load CA store, so we can verify client certificates if needed. */ - ssl_loaded_verify_locations = false; - - if (access(ROOT_CERT_FILE, R_OK) != 0) + if (ssl_ca_file[0]) { - /* - * If root certificate file simply not found, don't log an error here, - * because it's quite likely the user isn't planning on using client - * certificates. If we can't access it for other reasons, it is an - * error. - */ - if (errno != ENOENT) + 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 access root certificate file \"%s\": %m", - ROOT_CERT_FILE))); + (errmsg("could not load root certificate file \"%s\": %s", + ssl_ca_file, SSLerrmessage()))); } - 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) - { - /* - * File was there, but we could not load it. This means the file is - * somehow broken, and we cannot do verification at all - so fail. - */ - ereport(FATAL, - (errmsg("could not load root certificate file \"%s\": %s", - ROOT_CERT_FILE, SSLerrmessage()))); - } - else + + /*---------- + * Load the Certificate Revocation List (CRL). + * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html + *---------- + */ + if (ssl_crl_file[0]) { - /*---------- - * Load the Certificate Revocation List (CRL) if file exists. - * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html - *---------- - */ 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, 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,32 +829,31 @@ 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 } else - { - /* Not fatal - we do not require CRL */ - ereport(LOG, - (errmsg("SSL certificate revocation list file \"%s\" not found, skipping: %s", - ROOT_CRL_FILE, SSLerrmessage()), - errdetail("Certificates will not be checked against revocation list."))); - } + ereport(FATAL, + (errmsg("could not load SSL certificate revocation list file \"%s\": %s", + ssl_crl_file, SSLerrmessage()))); + } + } - /* - * 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); + 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; - } + /* Set flag to remember CA store is successfully loaded */ + ssl_loaded_verify_locations = true; /* * Tell OpenSSL to send the list of root certs we trust to clients in diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 1dadafc7048..a83b52ea290 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -1417,7 +1417,7 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int line_num) ereport(LOG, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("client certificates can only be checked if a root certificate store is available"), - errhint("Make sure the root.crt file is present and readable."), + errhint("Make sure the configuration parameter \"ssl_ca_file\" is set."), errcontext("line %d of configuration file \"%s\"", line_num, HbaFileName))); return false; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 7df5292f951..84b330c6d39 100644 --- a/src/backend/utils/misc/guc.c +++ b/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, + "", + 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, + "", + NULL, NULL, NULL + }, + + { {"stats_temp_directory", PGC_SIGHUP, STATS_COLLECTOR, gettext_noop("Writes temporary statistics files to the specified directory."), NULL, diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 400c52bf9d7..96da086b0f4 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/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 = '' # (change requires restart) +#ssl_crl_file = '' # (change requires restart) #password_encryption = on #db_user_namespace = off diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index a4ef7b3e094..7083cd866b6 100644 --- a/src/include/libpq/libpq.h +++ b/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); |