Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6667d9a

Browse files
committed
Re-allow SSL passphrase prompt at server start, but not thereafter.
Leave OpenSSL's default passphrase collection callback in place duringthe first call of secure_initialize() in server startup. Although thatdoesn't work terribly well in daemon contexts, some people feel we shouldnot break it for anyone who was successfully using it before. We stillblock passphrase demands during SIGHUP, meaning that you can't adjust SSLconfiguration on-the-fly if you used a passphrase, but this is no worsethan what it was before commitde41869. And we block passphrase demandsduring EXEC_BACKEND reloads; that behavior wasn't useful either, but atleast now it's documented.Tweak some related log messages for more readability, and avoid issuingessentially duplicate messages about reload failure caused by a passphrase.Discussion:https://postgr.es/m/29982.1483412575@sss.pgh.pa.us
1 parent0fad355 commit6667d9a

File tree

6 files changed

+72
-53
lines changed

6 files changed

+72
-53
lines changed

‎doc/src/sgml/runtime.sgml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,8 +2159,13 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
21592159
</para>
21602160

21612161
<para>
2162-
The private key cannot be protected with a passphrase, as there is no
2163-
way to supply the passphrase to the server.
2162+
If the private key is protected with a passphrase, the
2163+
server will prompt for the passphrase and will not start until it has
2164+
been entered.
2165+
Using a passphrase also disables the ability to change the server's SSL
2166+
configuration without a server restart.
2167+
Furthermore, passphrase-protected private keys cannot be used at all
2168+
on Windows.
21642169
</para>
21652170

21662171
<para>
@@ -2293,9 +2298,9 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
22932298
<para>
22942299
If an error in these files is detected at server start, the server will
22952300
refuse to start. But if an error is detected during a configuration
2296-
reload, the files are ignored and the oldvalues continue to be used.
2297-
On <systemitem class="osname">Windows</> systems, if an error in these
2298-
files is detected at backend start, that backend will be unable to
2301+
reload, the files are ignored and the oldSSL configuration continues to
2302+
be used.On <systemitem class="osname">Windows</> systems, if an error in
2303+
thesefiles is detected at backend start, that backend will be unable to
22992304
establish an SSL connection. In all these cases, the error condition is
23002305
reported in the server log.
23012306
</para>
@@ -2314,8 +2319,8 @@ openssl req -new -text -out server.req
23142319
you enter the local host name as <quote>Common Name</>; the challenge
23152320
password can be left blank. The program will generate a key that is
23162321
passphrase protected; it will not accept a passphrase that is less
2317-
than four characters long. To remove the passphrase again (as you must),
2318-
next run the commands:
2322+
than four characters long. To remove the passphrase again (as you must
2323+
if you want automatic start-up of the server),next run the commands:
23192324
<programlisting>
23202325
openssl rsa -in privkey.pem -out server.key
23212326
rm privkey.pem

‎src/backend/libpq/be-secure-openssl.c

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,14 @@ static DH *tmp_dh_cb(SSL *s, int is_export, int keylength);
7878
staticintssl_passwd_cb(char*buf,intsize,intrwflag,void*userdata);
7979
staticintverify_cb(int,X509_STORE_CTX*);
8080
staticvoidinfo_cb(constSSL*ssl,inttype,intargs);
81-
staticboolinitialize_ecdh(SSL_CTX*context,boolfailOnError);
81+
staticboolinitialize_ecdh(SSL_CTX*context,boolisServerStart);
8282
staticconstchar*SSLerrmessage(unsigned longecode);
8383

8484
staticchar*X509_NAME_to_cstring(X509_NAME*name);
8585

8686
staticSSL_CTX*SSL_context=NULL;
8787
staticboolSSL_initialized= false;
88+
staticboolssl_passwd_cb_called= false;
8889

8990
/* ------------------------------------------------------------ */
9091
/* Hardcoded values*/
@@ -159,12 +160,12 @@ KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
159160
/*
160161
*Initialize global SSL context.
161162
*
162-
* IffailOnError is true, report any errors as FATAL (so we don't return).
163-
* Otherwise, log errors at LOG level and return -1 to indicate trouble.
164-
* Returns 0 if OK.
163+
* IfisServerStart is true, report any errors as FATAL (so we don't return).
164+
* Otherwise, log errors at LOG level and return -1 to indicate trouble,
165+
*preserving the old SSL state if any.Returns 0 if OK.
165166
*/
166167
int
167-
be_tls_init(boolfailOnError)
168+
be_tls_init(boolisServerStart)
168169
{
169170
STACK_OF(X509_NAME)*root_cert_list=NULL;
170171
SSL_CTX*context;
@@ -192,7 +193,7 @@ be_tls_init(bool failOnError)
192193
context=SSL_CTX_new(SSLv23_method());
193194
if (!context)
194195
{
195-
ereport(failOnError ?FATAL :LOG,
196+
ereport(isServerStart ?FATAL :LOG,
196197
(errmsg("could not create SSL context: %s",
197198
SSLerrmessage(ERR_get_error()))));
198199
gotoerror;
@@ -205,16 +206,21 @@ be_tls_init(bool failOnError)
205206
SSL_CTX_set_mode(context,SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
206207

207208
/*
208-
* Override OpenSSL's default handling of passphrase-protected files.
209+
* If reloading, override OpenSSL's default handling of
210+
* passphrase-protected files, because we don't want to prompt for a
211+
* passphrase in an already-running server. (Not that the default
212+
* handling is very desirable during server start either, but some people
213+
* insist we need to keep it.)
209214
*/
210-
SSL_CTX_set_default_passwd_cb(context,ssl_passwd_cb);
215+
if (!isServerStart)
216+
SSL_CTX_set_default_passwd_cb(context,ssl_passwd_cb);
211217

212218
/*
213219
* Load and verify server's certificate and private key
214220
*/
215221
if (SSL_CTX_use_certificate_chain_file(context,ssl_cert_file)!=1)
216222
{
217-
ereport(failOnError ?FATAL :LOG,
223+
ereport(isServerStart ?FATAL :LOG,
218224
(errcode(ERRCODE_CONFIG_FILE_ERROR),
219225
errmsg("could not load server certificate file \"%s\": %s",
220226
ssl_cert_file,SSLerrmessage(ERR_get_error()))));
@@ -223,7 +229,7 @@ be_tls_init(bool failOnError)
223229

224230
if (stat(ssl_key_file,&buf)!=0)
225231
{
226-
ereport(failOnError ?FATAL :LOG,
232+
ereport(isServerStart ?FATAL :LOG,
227233
(errcode_for_file_access(),
228234
errmsg("could not access private key file \"%s\": %m",
229235
ssl_key_file)));
@@ -232,22 +238,22 @@ be_tls_init(bool failOnError)
232238

233239
if (!S_ISREG(buf.st_mode))
234240
{
235-
ereport(failOnError ?FATAL :LOG,
241+
ereport(isServerStart ?FATAL :LOG,
236242
(errcode(ERRCODE_CONFIG_FILE_ERROR),
237243
errmsg("private key file \"%s\" is not a regular file",
238244
ssl_key_file)));
239245
gotoerror;
240246
}
241247

242248
/*
243-
* Refuse to load files owned by users other than us or root.
249+
* Refuse to loadkeyfiles owned by users other than us or root.
244250
*
245251
* XXX surely we can check this on Windows somehow, too.
246252
*/
247253
#if !defined(WIN32)&& !defined(__CYGWIN__)
248254
if (buf.st_uid!=geteuid()&&buf.st_uid!=0)
249255
{
250-
ereport(failOnError ?FATAL :LOG,
256+
ereport(isServerStart ?FATAL :LOG,
251257
(errcode(ERRCODE_CONFIG_FILE_ERROR),
252258
errmsg("private key file \"%s\" must be owned by the database user or root",
253259
ssl_key_file)));
@@ -270,7 +276,7 @@ be_tls_init(bool failOnError)
270276
if ((buf.st_uid==geteuid()&&buf.st_mode& (S_IRWXG |S_IRWXO))||
271277
(buf.st_uid==0&&buf.st_mode& (S_IWGRP |S_IXGRP |S_IRWXO)))
272278
{
273-
ereport(failOnError ?FATAL :LOG,
279+
ereport(isServerStart ?FATAL :LOG,
274280
(errcode(ERRCODE_CONFIG_FILE_ERROR),
275281
errmsg("private key file \"%s\" has group or world access",
276282
ssl_key_file),
@@ -279,20 +285,31 @@ be_tls_init(bool failOnError)
279285
}
280286
#endif
281287

288+
/*
289+
* OK, try to load the private key file.
290+
*/
291+
ssl_passwd_cb_called= false;
292+
282293
if (SSL_CTX_use_PrivateKey_file(context,
283294
ssl_key_file,
284295
SSL_FILETYPE_PEM)!=1)
285296
{
286-
ereport(failOnError ?FATAL :LOG,
287-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
288-
errmsg("could not load private key file \"%s\": %s",
289-
ssl_key_file,SSLerrmessage(ERR_get_error()))));
297+
if (ssl_passwd_cb_called)
298+
ereport(isServerStart ?FATAL :LOG,
299+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
300+
errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
301+
ssl_key_file)));
302+
else
303+
ereport(isServerStart ?FATAL :LOG,
304+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
305+
errmsg("could not load private key file \"%s\": %s",
306+
ssl_key_file,SSLerrmessage(ERR_get_error()))));
290307
gotoerror;
291308
}
292309

293310
if (SSL_CTX_check_private_key(context)!=1)
294311
{
295-
ereport(failOnError ?FATAL :LOG,
312+
ereport(isServerStart ?FATAL :LOG,
296313
(errcode(ERRCODE_CONFIG_FILE_ERROR),
297314
errmsg("check of private key failed: %s",
298315
SSLerrmessage(ERR_get_error()))));
@@ -306,13 +323,13 @@ be_tls_init(bool failOnError)
306323
SSL_OP_NO_SSLv2 |SSL_OP_NO_SSLv3);
307324

308325
/* set up ephemeral ECDH keys */
309-
if (!initialize_ecdh(context,failOnError))
326+
if (!initialize_ecdh(context,isServerStart))
310327
gotoerror;
311328

312329
/* set up the allowed cipher list */
313330
if (SSL_CTX_set_cipher_list(context,SSLCipherSuites)!=1)
314331
{
315-
ereport(failOnError ?FATAL :LOG,
332+
ereport(isServerStart ?FATAL :LOG,
316333
(errcode(ERRCODE_CONFIG_FILE_ERROR),
317334
errmsg("could not set the cipher list (no valid ciphers available)")));
318335
gotoerror;
@@ -330,7 +347,7 @@ be_tls_init(bool failOnError)
330347
if (SSL_CTX_load_verify_locations(context,ssl_ca_file,NULL)!=1||
331348
(root_cert_list=SSL_load_client_CA_file(ssl_ca_file))==NULL)
332349
{
333-
ereport(failOnError ?FATAL :LOG,
350+
ereport(isServerStart ?FATAL :LOG,
334351
(errcode(ERRCODE_CONFIG_FILE_ERROR),
335352
errmsg("could not load root certificate file \"%s\": %s",
336353
ssl_ca_file,SSLerrmessage(ERR_get_error()))));
@@ -366,7 +383,7 @@ be_tls_init(bool failOnError)
366383
}
367384
else
368385
{
369-
ereport(failOnError ?FATAL :LOG,
386+
ereport(isServerStart ?FATAL :LOG,
370387
(errcode(ERRCODE_CONFIG_FILE_ERROR),
371388
errmsg("could not load SSL certificate revocation list file \"%s\": %s",
372389
ssl_crl_file,SSLerrmessage(ERR_get_error()))));
@@ -1071,19 +1088,16 @@ tmp_dh_cb(SSL *s, int is_export, int keylength)
10711088
*
10721089
* If OpenSSL is told to use a passphrase-protected server key, by default
10731090
* it will issue a prompt on /dev/tty and try to read a key from there.
1074-
* That's completely no good for a postmaster SIGHUP cycle, not to mention
1075-
* SSL context reload in an EXEC_BACKEND postmaster child. So override it
1076-
* with this dummy function that just returns an empty passphrase,
1077-
* guaranteeing failure. Later we might think about collecting a passphrase
1078-
* at server start and feeding it to OpenSSL repeatedly, but we'd still
1079-
* need this callback for that.
1091+
* That's no good during a postmaster SIGHUP cycle, not to mention SSL context
1092+
* reload in an EXEC_BACKEND postmaster child. So override it with this dummy
1093+
* function that just returns an empty passphrase, guaranteeing failure.
10801094
*/
10811095
staticint
10821096
ssl_passwd_cb(char*buf,intsize,intrwflag,void*userdata)
10831097
{
1084-
ereport(LOG,
1085-
(errcode(ERRCODE_CONFIG_FILE_ERROR),
1086-
errmsg("server's private key file requires a passphrase")));
1098+
/* Set flag to change the error message we'll report */
1099+
ssl_passwd_cb_called= true;
1100+
/* And return empty string */
10871101
Assert(size>0);
10881102
buf[0]='\0';
10891103
return0;
@@ -1151,7 +1165,7 @@ info_cb(const SSL *ssl, int type, int args)
11511165
}
11521166

11531167
staticbool
1154-
initialize_ecdh(SSL_CTX*context,boolfailOnError)
1168+
initialize_ecdh(SSL_CTX*context,boolisServerStart)
11551169
{
11561170
#ifndefOPENSSL_NO_ECDH
11571171
EC_KEY*ecdh;
@@ -1160,7 +1174,7 @@ initialize_ecdh(SSL_CTX *context, bool failOnError)
11601174
nid=OBJ_sn2nid(SSLECDHCurve);
11611175
if (!nid)
11621176
{
1163-
ereport(failOnError ?FATAL :LOG,
1177+
ereport(isServerStart ?FATAL :LOG,
11641178
(errcode(ERRCODE_CONFIG_FILE_ERROR),
11651179
errmsg("ECDH: unrecognized curve name: %s",SSLECDHCurve)));
11661180
return false;
@@ -1169,7 +1183,7 @@ initialize_ecdh(SSL_CTX *context, bool failOnError)
11691183
ecdh=EC_KEY_new_by_curve_name(nid);
11701184
if (!ecdh)
11711185
{
1172-
ereport(failOnError ?FATAL :LOG,
1186+
ereport(isServerStart ?FATAL :LOG,
11731187
(errcode(ERRCODE_CONFIG_FILE_ERROR),
11741188
errmsg("ECDH: could not create key")));
11751189
return false;

‎src/backend/libpq/be-secure.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,15 @@ boolSSLPreferServerCiphers;
6565
/*
6666
*Initialize global context.
6767
*
68-
* IffailOnError is true, report any errors as FATAL (so we don't return).
69-
* Otherwise, log errors at LOG level and return -1 to indicate trouble.
70-
* Returns 0 if OK.
68+
* IfisServerStart is true, report any errors as FATAL (so we don't return).
69+
* Otherwise, log errors at LOG level and return -1 to indicate trouble,
70+
*preserving the old SSL state if any.Returns 0 if OK.
7171
*/
7272
int
73-
secure_initialize(boolfailOnError)
73+
secure_initialize(boolisServerStart)
7474
{
7575
#ifdefUSE_SSL
76-
returnbe_tls_init(failOnError);
76+
returnbe_tls_init(isServerStart);
7777
#else
7878
return0;
7979
#endif

‎src/backend/postmaster/postmaster.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2507,11 +2507,11 @@ SIGHUP_handler(SIGNAL_ARGS)
25072507
/* Reload authentication config files too */
25082508
if (!load_hba())
25092509
ereport(LOG,
2510-
(errmsg("pg_hba.conf not reloaded")));
2510+
(errmsg("pg_hba.confwasnot reloaded")));
25112511

25122512
if (!load_ident())
25132513
ereport(LOG,
2514-
(errmsg("pg_ident.conf not reloaded")));
2514+
(errmsg("pg_ident.confwasnot reloaded")));
25152515

25162516
#ifdefUSE_SSL
25172517
/* Reload SSL configuration as well */
@@ -2521,7 +2521,7 @@ SIGHUP_handler(SIGNAL_ARGS)
25212521
LoadedSSL= true;
25222522
else
25232523
ereport(LOG,
2524-
(errmsg("SSLcontext not reloaded")));
2524+
(errmsg("SSLconfiguration was not reloaded")));
25252525
}
25262526
else
25272527
{
@@ -4772,7 +4772,7 @@ SubPostmasterMain(int argc, char *argv[])
47724772
LoadedSSL= true;
47734773
else
47744774
ereport(LOG,
4775-
(errmsg("SSLcontext could not bereloaded in child process")));
4775+
(errmsg("SSLconfiguration could not beloaded in child process")));
47764776
}
47774777
#endif
47784778

‎src/include/libpq/libpq-be.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ typedef struct Port
199199
* These functions are implemented by the glue code specific to each
200200
* SSL implementation (e.g. be-secure-openssl.c)
201201
*/
202-
externintbe_tls_init(boolfailOnError);
202+
externintbe_tls_init(boolisServerStart);
203203
externvoidbe_tls_destroy(void);
204204
externintbe_tls_open_server(Port*port);
205205
externvoidbe_tls_close(Port*port);

‎src/include/libpq/libpq.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ extern char *ssl_key_file;
8181
externchar*ssl_ca_file;
8282
externchar*ssl_crl_file;
8383

84-
externintsecure_initialize(boolfailOnError);
84+
externintsecure_initialize(boolisServerStart);
8585
externboolsecure_loaded_verify_locations(void);
8686
externvoidsecure_destroy(void);
8787
externintsecure_open_server(Port*port);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp