@@ -52,7 +52,8 @@ static int my_SSL_set_fd(Port *port, int fd);
5252
5353static DH * load_dh_file (char * filename , bool isServerStart );
5454static DH * load_dh_buffer (const char * , size_t );
55- static int ssl_passwd_cb (char * buf , int size , int rwflag , void * userdata );
55+ static int ssl_external_passwd_cb (char * buf , int size , int rwflag , void * userdata );
56+ static int dummy_ssl_passwd_cb (char * buf , int size , int rwflag , void * userdata );
5657static int verify_cb (int , X509_STORE_CTX * );
5758static void info_cb (const SSL * ssl , int type , int args );
5859static bool initialize_dh (SSL_CTX * context , bool isServerStart );
@@ -63,7 +64,8 @@ static char *X509_NAME_to_cstring(X509_NAME *name);
6364
6465static SSL_CTX * SSL_context = NULL ;
6566static bool SSL_initialized = false;
66- static bool ssl_passwd_cb_called = false;
67+ static bool dummy_ssl_passwd_cb_called = false;
68+ static bool ssl_is_server_start ;
6769
6870
6971/* ------------------------------------------------------------ */
@@ -111,14 +113,28 @@ be_tls_init(bool isServerStart)
111113 SSL_CTX_set_mode (context , SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER );
112114
113115 /*
114- * If reloading, override OpenSSL's default handling of
115- * passphrase-protected files, because we don't want to prompt for a
116- * passphrase in an already-running server. (Not that the default
117- * handling is very desirable during server start either, but some people
118- * insist we need to keep it.)
116+ * Set password callback
119117 */
120- if (!isServerStart )
121- SSL_CTX_set_default_passwd_cb (context , ssl_passwd_cb );
118+ if (isServerStart )
119+ {
120+ if (ssl_passphrase_command [0 ])
121+ SSL_CTX_set_default_passwd_cb (context , ssl_external_passwd_cb );
122+ }
123+ else
124+ {
125+ if (ssl_passphrase_command [0 ] && ssl_passphrase_command_supports_reload )
126+ SSL_CTX_set_default_passwd_cb (context , ssl_external_passwd_cb );
127+ else
128+ /*
129+ * If reloading and no external command is configured, override
130+ * OpenSSL's default handling of passphrase-protected files,
131+ * because we don't want to prompt for a passphrase in an
132+ * already-running server.
133+ */
134+ SSL_CTX_set_default_passwd_cb (context , dummy_ssl_passwd_cb );
135+ }
136+ /* used by the callback */
137+ ssl_is_server_start = isServerStart ;
122138
123139 /*
124140 * Load and verify server's certificate and private key
@@ -138,13 +154,13 @@ be_tls_init(bool isServerStart)
138154 /*
139155 * OK, try to load the private key file.
140156 */
141- ssl_passwd_cb_called = false;
157+ dummy_ssl_passwd_cb_called = false;
142158
143159 if (SSL_CTX_use_PrivateKey_file (context ,
144160 ssl_key_file ,
145161 SSL_FILETYPE_PEM ) != 1 )
146162 {
147- if (ssl_passwd_cb_called )
163+ if (dummy_ssl_passwd_cb_called )
148164 ereport (isServerStart ? FATAL : LOG ,
149165 (errcode (ERRCODE_CONFIG_FILE_ERROR ),
150166 errmsg ("private key file \"%s\" cannot be reloaded because it requires a passphrase" ,
@@ -839,7 +855,21 @@ load_dh_buffer(const char *buffer, size_t len)
839855}
840856
841857/*
842- * Passphrase collection callback
858+ * Passphrase collection callback using ssl_passphrase_command
859+ */
860+ static int
861+ ssl_external_passwd_cb (char * buf , int size , int rwflag , void * userdata )
862+ {
863+ /* same prompt as OpenSSL uses internally */
864+ const char * prompt = "Enter PEM pass phrase:" ;
865+
866+ Assert (rwflag == 0 );
867+
868+ return run_ssl_passphrase_command (prompt , ssl_is_server_start , buf , size );
869+ }
870+
871+ /*
872+ * Dummy passphrase callback
843873 *
844874 * If OpenSSL is told to use a passphrase-protected server key, by default
845875 * it will issue a prompt on /dev/tty and try to read a key from there.
@@ -848,10 +878,10 @@ load_dh_buffer(const char *buffer, size_t len)
848878 * function that just returns an empty passphrase, guaranteeing failure.
849879 */
850880static int
851- ssl_passwd_cb (char * buf , int size , int rwflag , void * userdata )
881+ dummy_ssl_passwd_cb (char * buf , int size , int rwflag , void * userdata )
852882{
853883 /* Set flag to change the error message we'll report */
854- ssl_passwd_cb_called = true;
884+ dummy_ssl_passwd_cb_called = true;
855885 /* And return empty string */
856886 Assert (size > 0 );
857887 buf [0 ] = '\0' ;
0 commit comments