Allow ssl_passphrase_command to prompt the terminal

Previously the command could not access the terminal for a passphrase.

Backpatch-through: master
This commit is contained in:
Bruce Momjian 2020-12-25 20:41:06 -05:00
parent 62afb42a7f
commit 300e430c76
4 changed files with 38 additions and 19 deletions

View File

@ -1452,18 +1452,18 @@ include_dir 'conf.d'
mechanism is used.
</para>
<para>
The command must print the passphrase to the standard output and exit
with code 0. In the parameter value, <literal>%p</literal> is
replaced by a prompt string. (Write <literal>%%</literal> for a
literal <literal>%</literal>.) Note that the prompt string will
probably contain whitespace, so be sure to quote adequately. A single
newline is stripped from the end of the output if present.
</para>
<para>
The command does not actually have to prompt the user for a
passphrase. It can read it from a file, obtain it from a keychain
facility, or similar. It is up to the user to make sure the chosen
mechanism is adequately secure.
The command must print the passphrase to the standard output
and exit with code 0. It can prompt from the terminal if
<option>--authprompt</option> is used. In the parameter value,
<literal>%R</literal> represents the file descriptor number opened
to the terminal that started the server. A file descriptor is only
available if enabled at server start. If <literal>%R</literal>
is used and no file descriptor is available, the server will not
start. Value <literal>%p</literal> is replaced by a pre-defined
prompt string. (Write <literal>%%</literal> for a literal
<literal>%</literal>.) Note that the prompt string will probably
contain whitespace, so be sure to quote its use adequately.
Newlines are stripped from the end of the output if present.
</para>
<para>
This parameter can only be set in the <filename>postgresql.conf</filename>
@ -1486,10 +1486,12 @@ include_dir 'conf.d'
parameter is off (the default), then
<varname>ssl_passphrase_command</varname> will be ignored during a
reload and the SSL configuration will not be reloaded if a passphrase
is needed. That setting is appropriate for a command that requires a
TTY for prompting, which might not be available when the server is
running. Setting this parameter to on might be appropriate if the
passphrase is obtained from a file, for example.
is needed. This setting is appropriate for a command that requires a
terminal for prompting, which will likely not be available when the server is
running. (<option>--authprompt</option> closes the terminal file
descriptor soon after server start.) Setting this parameter on
might be appropriate, for example, if the passphrase is obtained
from a file.
</para>
<para>
This parameter can only be set in the <filename>postgresql.conf</filename>

View File

@ -380,8 +380,9 @@ PostgreSQL documentation
<term><option>--authprompt</option></term>
<listitem>
<para>
Allows the <option>--cluster-key-command</option> command
to prompt for a passphrase or PIN.
Allows <option>ssl_passphrase_command</option> or
<option>cluster_key_command</option> to prompt for a passphrase
or PIN.
</para>
</listitem>
</varlistentry>

View File

@ -170,7 +170,9 @@ PostgreSQL documentation
<varlistentry>
<term><option>-R</option></term>
<term><option>--authprompt</option></term>
<listitem><para>allows prompting for a passphrase or PIN
<listitem><para>allows <option>ssl_passphrase_command</option> or
<option>cluster_key_command</option> to prompt for a passphrase
or PIN.
</para></listitem>
</varlistentry>

View File

@ -22,6 +22,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include "postmaster/postmaster.h"
#include "common/string.h"
#include "libpq/libpq.h"
#include "storage/fd.h"
@ -61,6 +62,19 @@ run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf,
appendStringInfoString(&command, prompt);
p++;
break;
case 'R':
{
char fd_str[20];
if (terminal_fd == -1)
ereport(ERROR,
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("ssl_passphrase_command referenced %%R, but -R not specified")));
p++;
snprintf(fd_str, sizeof(fd_str), "%d", terminal_fd);
appendStringInfoString(&command, fd_str);
break;
}
case '%':
appendStringInfoChar(&command, '%');
p++;