diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 65c7809332e3c6a54bcef0c354df770a22d02a74..38f561886a1efa09bec8a7a1ef4b3b5b36250637 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 4a39d7f74672c8d49c1b71e71e47c13cc131aebe..45ad41200384cc37c4ec9abe541bc094b0650f19 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); @@ -203,6 +204,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 */ @@ -1060,6 +1066,29 @@ tmp_dh_cb(SSL *s, int is_export, int keylength) return r; } +/* + * 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 *