mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Add ssl_passphrase_command setting
This allows specifying an external command for prompting for or otherwise obtaining passphrases for SSL key files. This is useful because in many cases there is no TTY easily available during service startup. Also add a setting ssl_passphrase_command_supports_reload, which allows supporting SSL configuration reload even if SSL files need passphrases. Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
This commit is contained in:
120
src/backend/libpq/be-secure-common.c
Normal file
120
src/backend/libpq/be-secure-common.c
Normal file
@ -0,0 +1,120 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* be-secure-common.c
|
||||
*
|
||||
* common implementation-independent SSL support code
|
||||
*
|
||||
* While be-secure.c contains the interfaces that the rest of the
|
||||
* communications code calls, this file contains support routines that are
|
||||
* used by the library-specific implementations such as be-secure-openssl.c.
|
||||
*
|
||||
* Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* src/backend/libpq/be-secure-common.c
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "libpq/libpq.h"
|
||||
#include "storage/fd.h"
|
||||
|
||||
/*
|
||||
* Run ssl_passphrase_command
|
||||
*
|
||||
* prompt will be substituted for %p. is_server_start determines the loglevel
|
||||
* of error messages.
|
||||
*
|
||||
* The result will be put in buffer buf, which is of size size. The return
|
||||
* value is the length of the actual result.
|
||||
*/
|
||||
int
|
||||
run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, int size)
|
||||
{
|
||||
int loglevel = is_server_start ? ERROR : LOG;
|
||||
StringInfoData command;
|
||||
char *p;
|
||||
FILE *fh;
|
||||
int pclose_rc;
|
||||
size_t len = 0;
|
||||
|
||||
Assert(prompt);
|
||||
Assert(size > 0);
|
||||
buf[0] = '\0';
|
||||
|
||||
initStringInfo(&command);
|
||||
|
||||
for (p = ssl_passphrase_command; *p; p++)
|
||||
{
|
||||
if (p[0] == '%')
|
||||
{
|
||||
switch (p[1])
|
||||
{
|
||||
case 'p':
|
||||
appendStringInfoString(&command, prompt);
|
||||
p++;
|
||||
break;
|
||||
case '%':
|
||||
appendStringInfoChar(&command, '%');
|
||||
p++;
|
||||
break;
|
||||
default:
|
||||
appendStringInfoChar(&command, p[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
appendStringInfoChar(&command, p[0]);
|
||||
}
|
||||
|
||||
fh = OpenPipeStream(command.data, "r");
|
||||
if (fh == NULL)
|
||||
{
|
||||
ereport(loglevel,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not execute command \"%s\": %m",
|
||||
command.data)));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!fgets(buf, size, fh))
|
||||
{
|
||||
if (ferror(fh))
|
||||
{
|
||||
ereport(loglevel,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not read from command \"%s\": %m",
|
||||
command.data)));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
pclose_rc = ClosePipeStream(fh);
|
||||
if (pclose_rc == -1)
|
||||
{
|
||||
ereport(loglevel,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not close pipe to external command: %m")));
|
||||
goto error;
|
||||
}
|
||||
else if (pclose_rc != 0)
|
||||
{
|
||||
ereport(loglevel,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("command \"%s\" failed",
|
||||
command.data),
|
||||
errdetail_internal("%s", wait_result_to_str(pclose_rc))));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* strip trailing newline */
|
||||
len = strlen(buf);
|
||||
if (buf[len - 1] == '\n')
|
||||
buf[len-- -1] = '\0';
|
||||
|
||||
error:
|
||||
pfree(command.data);
|
||||
return len;
|
||||
}
|
Reference in New Issue
Block a user