PostgreSQL Source Code  git master
be-secure-common.c File Reference
#include "postgres.h"
#include <sys/stat.h>
#include <unistd.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 132 of file be-secure-common.c.

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

Referenced by be_tls_init().

133 {
134  int loglevel = isServerStart ? FATAL : LOG;
135  struct stat buf;
136 
137  if (stat(ssl_key_file, &buf) != 0)
138  {
139  ereport(loglevel,
141  errmsg("could not access private key file \"%s\": %m",
142  ssl_key_file)));
143  return false;
144  }
145 
146  if (!S_ISREG(buf.st_mode))
147  {
148  ereport(loglevel,
149  (errcode(ERRCODE_CONFIG_FILE_ERROR),
150  errmsg("private key file \"%s\" is not a regular file",
151  ssl_key_file)));
152  return false;
153  }
154 
155  /*
156  * Refuse to load key files owned by users other than us or root.
157  *
158  * XXX surely we can check this on Windows somehow, too.
159  */
160 #if !defined(WIN32) && !defined(__CYGWIN__)
161  if (buf.st_uid != geteuid() && buf.st_uid != 0)
162  {
163  ereport(loglevel,
164  (errcode(ERRCODE_CONFIG_FILE_ERROR),
165  errmsg("private key file \"%s\" must be owned by the database user or root",
166  ssl_key_file)));
167  return false;
168  }
169 #endif
170 
171  /*
172  * Require no public access to key file. If the file is owned by us,
173  * require mode 0600 or less. If owned by root, require 0640 or less to
174  * allow read access through our gid, or a supplementary gid that allows
175  * to read system-wide certificates.
176  *
177  * XXX temporarily suppress check when on Windows, because there may not
178  * be proper support for Unix-y file permissions. Need to think of a
179  * reasonable check to apply on Windows. (See also the data directory
180  * permission check in postmaster.c)
181  */
182 #if !defined(WIN32) && !defined(__CYGWIN__)
183  if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) ||
184  (buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)))
185  {
186  ereport(loglevel,
187  (errcode(ERRCODE_CONFIG_FILE_ERROR),
188  errmsg("private key file \"%s\" has group or world access",
189  ssl_key_file),
190  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.")));
191  return false;
192  }
193 #endif
194 
195  return true;
196 }
int errcode(int sqlerrcode)
Definition: elog.c:570
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:52
static char * buf
Definition: pg_test_fsync.c:68
#define S_IRWXG
Definition: win32_port.h:281
int errdetail(const char *fmt,...)
Definition: elog.c:860
int errcode_for_file_access(void)
Definition: elog.c:593
#define S_IWGRP
Definition: win32_port.h:275
#define ereport(elevel, rest)
Definition: elog.h:141
#define S_ISREG(m)
Definition: win32_port.h:299
#define stat(a, b)
Definition: win32_port.h:255
#define S_IXGRP
Definition: win32_port.h:278
int errmsg(const char *fmt,...)
Definition: elog.c:784
char * ssl_key_file
Definition: be-secure.c:43
#define S_IRWXO
Definition: win32_port.h:293

◆ run_ssl_passphrase_command()

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

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

References appendStringInfoChar(), appendStringInfoString(), Assert, ClosePipeStream(), StringInfoData::data, ereport, errcode_for_file_access(), errdetail_internal(), errmsg(), ERROR, error(), explicit_bzero(), initStringInfo(), LOG, OpenPipeStream(), pfree(), pg_strip_crlf(), ssl_passphrase_command, and wait_result_to_str().

Referenced by ssl_external_passwd_cb().

40 {
41  int loglevel = is_server_start ? ERROR : LOG;
42  StringInfoData command;
43  char *p;
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  initStringInfo(&command);
53 
54  for (p = ssl_passphrase_command; *p; p++)
55  {
56  if (p[0] == '%')
57  {
58  switch (p[1])
59  {
60  case 'p':
61  appendStringInfoString(&command, prompt);
62  p++;
63  break;
64  case '%':
65  appendStringInfoChar(&command, '%');
66  p++;
67  break;
68  default:
69  appendStringInfoChar(&command, p[0]);
70  }
71  }
72  else
73  appendStringInfoChar(&command, p[0]);
74  }
75 
76  fh = OpenPipeStream(command.data, "r");
77  if (fh == NULL)
78  {
79  ereport(loglevel,
81  errmsg("could not execute command \"%s\": %m",
82  command.data)));
83  goto error;
84  }
85 
86  if (!fgets(buf, size, fh))
87  {
88  if (ferror(fh))
89  {
90  explicit_bzero(buf, size);
91  ereport(loglevel,
93  errmsg("could not read from command \"%s\": %m",
94  command.data)));
95  goto error;
96  }
97  }
98 
99  pclose_rc = ClosePipeStream(fh);
100  if (pclose_rc == -1)
101  {
102  explicit_bzero(buf, size);
103  ereport(loglevel,
105  errmsg("could not close pipe to external command: %m")));
106  goto error;
107  }
108  else if (pclose_rc != 0)
109  {
110  explicit_bzero(buf, size);
111  ereport(loglevel,
113  errmsg("command \"%s\" failed",
114  command.data),
115  errdetail_internal("%s", wait_result_to_str(pclose_rc))));
116  goto error;
117  }
118 
119  /* strip trailing newline and carriage return */
120  len = pg_strip_crlf(buf);
121 
122 error:
123  pfree(command.data);
124  return len;
125 }
int pg_strip_crlf(char *str)
Definition: string.c:105
static void error(void)
Definition: sql-dyntest.c:147
#define LOG
Definition: elog.h:26
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:32
int ClosePipeStream(FILE *file)
Definition: fd.c:2614
int errdetail_internal(const char *fmt,...)
Definition: elog.c:887
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ERROR
Definition: elog.h:43
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
static char * buf
Definition: pg_test_fsync.c:68
int errcode_for_file_access(void)
Definition: elog.c:593
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2308
#define ereport(elevel, rest)
Definition: elog.h:141
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define Assert(condition)
Definition: c.h:732
int errmsg(const char *fmt,...)
Definition: elog.c:784
void explicit_bzero(void *buf, size_t len)
char * ssl_passphrase_command
Definition: be-secure.c:47