PostgreSQL Source Code  git master
be-secure-common.c File Reference
#include "postgres.h"
#include <sys/stat.h>
#include <unistd.h>
#include "common/percentrepl.h"
#include "common/string.h"
#include "libpq/libpq.h"
#include "storage/fd.h"
Include dependency graph for be-secure-common.c:

Go to the source code of this file.

Functions

int run_ssl_passphrase_command (const char *prompt, bool is_server_start, char *buf, int size)
 
bool check_ssl_key_file_permissions (const char *ssl_key_file, bool isServerStart)
 

Function Documentation

◆ check_ssl_key_file_permissions()

bool check_ssl_key_file_permissions ( const char *  ssl_key_file,
bool  isServerStart 
)

Definition at line 114 of file be-secure-common.c.

115 {
116  int loglevel = isServerStart ? FATAL : LOG;
117  struct stat buf;
118 
119  if (stat(ssl_key_file, &buf) != 0)
120  {
121  ereport(loglevel,
123  errmsg("could not access private key file \"%s\": %m",
124  ssl_key_file)));
125  return false;
126  }
127 
128  /* Key file must be a regular file */
129  if (!S_ISREG(buf.st_mode))
130  {
131  ereport(loglevel,
132  (errcode(ERRCODE_CONFIG_FILE_ERROR),
133  errmsg("private key file \"%s\" is not a regular file",
134  ssl_key_file)));
135  return false;
136  }
137 
138  /*
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.
144  *
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.
149  *
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
152  * available.
153  */
154 #if !defined(WIN32) && !defined(__CYGWIN__)
155  if (buf.st_uid != geteuid() && buf.st_uid != 0)
156  {
157  ereport(loglevel,
158  (errcode(ERRCODE_CONFIG_FILE_ERROR),
159  errmsg("private key file \"%s\" must be owned by the database user or root",
160  ssl_key_file)));
161  return false;
162  }
163 
164  if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) ||
165  (buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)))
166  {
167  ereport(loglevel,
168  (errcode(ERRCODE_CONFIG_FILE_ERROR),
169  errmsg("private key file \"%s\" has group or world access",
170  ssl_key_file),
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.")));
172  return false;
173  }
174 #endif
175 
176  return true;
177 }
char * ssl_key_file
Definition: be-secure.c:37
int errcode_for_file_access(void)
Definition: elog.c:880
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:857
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define LOG
Definition: elog.h:31
#define FATAL
Definition: elog.h:41
#define ereport(elevel,...)
Definition: elog.h:149
static char * buf
Definition: pg_test_fsync.c:73
#define S_IXGRP
Definition: win32_port.h:307
#define stat
Definition: win32_port.h:284
#define S_IRWXG
Definition: win32_port.h:310
#define S_IRWXO
Definition: win32_port.h:322
#define S_ISREG(m)
Definition: win32_port.h:328
#define S_IWGRP
Definition: win32_port.h:304

References buf, ereport, errcode(), errcode_for_file_access(), errdetail(), errmsg(), FATAL, LOG, S_IRWXG, S_IRWXO, S_ISREG, S_IWGRP, S_IXGRP, ssl_key_file, and stat.

Referenced by be_tls_init().

◆ run_ssl_passphrase_command()

int run_ssl_passphrase_command ( const char *  prompt,
bool  is_server_start,
char *  buf,
int  size 
)

Definition at line 40 of file be-secure-common.c.

41 {
42  int loglevel = is_server_start ? ERROR : LOG;
43  char *command;
44  FILE *fh;
45  int pclose_rc;
46  size_t len = 0;
47 
48  Assert(prompt);
49  Assert(size > 0);
50  buf[0] = '\0';
51 
52  command = replace_percent_placeholders(ssl_passphrase_command, "ssl_passphrase_command", "p", prompt);
53 
54  fh = OpenPipeStream(command, "r");
55  if (fh == NULL)
56  {
57  ereport(loglevel,
59  errmsg("could not execute command \"%s\": %m",
60  command)));
61  goto error;
62  }
63 
64  if (!fgets(buf, size, fh))
65  {
66  if (ferror(fh))
67  {
69  ereport(loglevel,
71  errmsg("could not read from command \"%s\": %m",
72  command)));
73  goto error;
74  }
75  }
76 
77  pclose_rc = ClosePipeStream(fh);
78  if (pclose_rc == -1)
79  {
81  ereport(loglevel,
83  errmsg("could not close pipe to external command: %m")));
84  goto error;
85  }
86  else if (pclose_rc != 0)
87  {
88  char *reason;
89 
91  reason = wait_result_to_str(pclose_rc);
92  ereport(loglevel,
94  errmsg("command \"%s\" failed",
95  command),
96  errdetail_internal("%s", reason)));
97  pfree(reason);
98  goto error;
99  }
100 
101  /* strip trailing newline and carriage return */
102  len = pg_strip_crlf(buf);
103 
104 error:
105  pfree(command);
106  return len;
107 }
char * ssl_passphrase_command
Definition: be-secure.c:42
#define Assert(condition)
Definition: c.h:858
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1230
#define ERROR
Definition: elog.h:39
int ClosePipeStream(FILE *file)
Definition: fd.c:2991
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2686
void pfree(void *pointer)
Definition: mcxt.c:1520
char * replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...)
Definition: percentrepl.c:59
const void size_t len
void explicit_bzero(void *buf, size_t len)
static pg_noinline void Size size
Definition: slab.c:607
static void error(void)
Definition: sql-dyntest.c:147
int pg_strip_crlf(char *str)
Definition: string.c:155
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:33

References Assert, buf, ClosePipeStream(), ereport, errcode_for_file_access(), errdetail_internal(), errmsg(), ERROR, error(), explicit_bzero(), len, LOG, OpenPipeStream(), pfree(), pg_strip_crlf(), replace_percent_placeholders(), size, ssl_passphrase_command, and wait_result_to_str().

Referenced by ssl_external_passwd_cb().