1/*-------------------------------------------------------------------------
5 * common implementation-independent SSL support code
7 * While be-secure.c contains the interfaces that the rest of the
8 * communications code calls, this file contains support routines that are
9 * used by the library-specific implementations such as be-secure-openssl.c.
11 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
12 * Portions Copyright (c) 1994, Regents of the University of California
15 * src/backend/libpq/be-secure-common.c
17 *-------------------------------------------------------------------------
31 * Run ssl_passphrase_command
33 * prompt will be substituted for %p. is_server_start determines the loglevel
36 * The result will be put in buffer buf, which is of size size. The return
37 * value is the length of the actual result.
42 int loglevel = is_server_start ?
ERROR :
LOG;
59 errmsg(
"could not execute command \"%s\": %m",
64 if (!fgets(
buf, size, fh))
71 errmsg(
"could not read from command \"%s\": %m",
83 errmsg(
"could not close pipe to external command: %m")));
86 else if (pclose_rc != 0)
94 errmsg(
"command \"%s\" failed",
101 /* strip trailing newline and carriage return */
111 * Check permissions for SSL key files.
116 int loglevel = isServerStart ?
FATAL :
LOG;
123 errmsg(
"could not access private key file \"%s\": %m",
128 /* Key file must be a regular file */
132 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
133 errmsg(
"private key file \"%s\" is not a regular file",
139 * Refuse to load key files owned by users other than us or root, and
140 * require no public access to the key file. If the file is owned by us,
141 * require mode 0600 or less. If owned by root, require 0640 or less to
142 * allow read access through either our gid or a supplementary gid that
143 * allows us to read system-wide certificates.
145 * Note that roughly similar checks are performed in
146 * src/interfaces/libpq/fe-secure-openssl.c so any changes here may need
147 * to be made there as well. The environment is different though; this
148 * code can assume that we're not running as root.
150 * Ideally we would do similar permissions checks on Windows, but it is
151 * not clear how that would work since Unix-style permissions may not be
154#if !defined(WIN32) && !defined(__CYGWIN__)
155 if (
buf.st_uid != geteuid() &&
buf.st_uid != 0)
158 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
159 errmsg(
"private key file \"%s\" must be owned by the database user or root",
168 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
169 errmsg(
"private key file \"%s\" has group or world access",
171 errdetail(
"File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root.")));
bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)
int run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, int size)
char * ssl_passphrase_command
int errdetail_internal(const char *fmt,...)
int errcode_for_file_access(void)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
FILE * OpenPipeStream(const char *command, const char *mode)
int ClosePipeStream(FILE *file)
Assert(PointerIsAligned(start, uint64))
void pfree(void *pointer)
char * replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...)
void explicit_bzero(void *buf, size_t len)
int pg_strip_crlf(char *str)
char * wait_result_to_str(int exitstatus)