summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/runtime.sgml9
-rw-r--r--src/backend/libpq/be-secure-openssl.c29
2 files changed, 33 insertions, 5 deletions
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 65c7809332e..38f561886a1 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -2159,9 +2159,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
</para>
<para>
- If the private key is protected with a passphrase, the
- server will prompt for the passphrase and will not start until it has
- been entered.
+ The private key cannot be protected with a passphrase, as there is no
+ way to supply the passphrase to the server.
</para>
<para>
@@ -2315,8 +2314,8 @@ openssl req -new -text -out server.req
you enter the local host name as <quote>Common Name</>; the challenge
password can be left blank. The program will generate a key that is
passphrase protected; it will not accept a passphrase that is less
- than four characters long. To remove the passphrase (as you must if
- you want automatic start-up of the server), run the commands:
+ than four characters long. To remove the passphrase again (as you must),
+ next run the commands:
<programlisting>
openssl rsa -in privkey.pem -out server.key
rm privkey.pem
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 4a39d7f7467..45ad4120038 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -75,6 +75,7 @@ static DH *load_dh_file(int keylength);
static DH *load_dh_buffer(const char *, size_t);
static DH *generate_dh_parameters(int prime_len, int generator);
static DH *tmp_dh_cb(SSL *s, int is_export, int keylength);
+static int ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata);
static int verify_cb(int, X509_STORE_CTX *);
static void info_cb(const SSL *ssl, int type, int args);
static bool initialize_ecdh(SSL_CTX *context, bool failOnError);
@@ -204,6 +205,11 @@ be_tls_init(bool failOnError)
SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
/*
+ * Override OpenSSL's default handling of passphrase-protected files.
+ */
+ SSL_CTX_set_default_passwd_cb(context, ssl_passwd_cb);
+
+ /*
* Load and verify server's certificate and private key
*/
if (SSL_CTX_use_certificate_chain_file(context, ssl_cert_file) != 1)
@@ -1061,6 +1067,29 @@ tmp_dh_cb(SSL *s, int is_export, int keylength)
}
/*
+ * Passphrase collection callback
+ *
+ * If OpenSSL is told to use a passphrase-protected server key, by default
+ * it will issue a prompt on /dev/tty and try to read a key from there.
+ * That's completely no good for a postmaster SIGHUP cycle, not to mention
+ * SSL context reload in an EXEC_BACKEND postmaster child. So override it
+ * with this dummy function that just returns an empty passphrase,
+ * guaranteeing failure. Later we might think about collecting a passphrase
+ * at server start and feeding it to OpenSSL repeatedly, but we'd still
+ * need this callback for that.
+ */
+static int
+ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
+{
+ ereport(LOG,
+ (errcode(ERRCODE_CONFIG_FILE_ERROR),
+ errmsg("server's private key file requires a passphrase")));
+ Assert(size > 0);
+ buf[0] = '\0';
+ return 0;
+}
+
+/*
* Certificate verification callback
*
* This callback allows us to log intermediate problems during