PostgreSQL Source Code  git master
fe-secure.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * fe-secure.c
4  * functions related to setting up a secure connection to the backend.
5  * Secure connections are expected to provide confidentiality,
6  * message integrity and endpoint authentication.
7  *
8  *
9  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
10  * Portions Copyright (c) 1994, Regents of the University of California
11  *
12  *
13  * IDENTIFICATION
14  * src/interfaces/libpq/fe-secure.c
15  *
16  *-------------------------------------------------------------------------
17  */
18 
19 #include "postgres_fe.h"
20 
21 #include <signal.h>
22 #include <fcntl.h>
23 #include <ctype.h>
24 
25 #ifdef WIN32
26 #include "win32.h"
27 #else
28 #include <sys/socket.h>
29 #include <unistd.h>
30 #include <netdb.h>
31 #include <netinet/in.h>
32 #include <netinet/tcp.h>
33 #include <arpa/inet.h>
34 #endif
35 
36 #include <sys/stat.h>
37 
38 #ifdef ENABLE_THREAD_SAFETY
39 #ifdef WIN32
40 #include "pthread-win32.h"
41 #else
42 #include <pthread.h>
43 #endif
44 #endif
45 
46 #include "fe-auth.h"
47 #include "libpq-fe.h"
48 #include "libpq-int.h"
49 
50 /*
51  * Macros to handle disabling and then restoring the state of SIGPIPE handling.
52  * On Windows, these are all no-ops since there's no SIGPIPEs.
53  */
54 
55 #ifndef WIN32
56 
57 #define SIGPIPE_MASKED(conn) ((conn)->sigpipe_so || (conn)->sigpipe_flag)
58 
59 #ifdef ENABLE_THREAD_SAFETY
60 
61 struct sigpipe_info
62 {
63  sigset_t oldsigmask;
64  bool sigpipe_pending;
65  bool got_epipe;
66 };
67 
68 #define DECLARE_SIGPIPE_INFO(spinfo) struct sigpipe_info spinfo
69 
70 #define DISABLE_SIGPIPE(conn, spinfo, failaction) \
71  do { \
72  (spinfo).got_epipe = false; \
73  if (!SIGPIPE_MASKED(conn)) \
74  { \
75  if (pq_block_sigpipe(&(spinfo).oldsigmask, \
76  &(spinfo).sigpipe_pending) < 0) \
77  failaction; \
78  } \
79  } while (0)
80 
81 #define REMEMBER_EPIPE(spinfo, cond) \
82  do { \
83  if (cond) \
84  (spinfo).got_epipe = true; \
85  } while (0)
86 
87 #define RESTORE_SIGPIPE(conn, spinfo) \
88  do { \
89  if (!SIGPIPE_MASKED(conn)) \
90  pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
91  (spinfo).got_epipe); \
92  } while (0)
93 #else /* !ENABLE_THREAD_SAFETY */
94 
95 #define DECLARE_SIGPIPE_INFO(spinfo) pqsigfunc spinfo = NULL
96 
97 #define DISABLE_SIGPIPE(conn, spinfo, failaction) \
98  do { \
99  if (!SIGPIPE_MASKED(conn)) \
100  spinfo = pqsignal(SIGPIPE, SIG_IGN); \
101  } while (0)
102 
103 #define REMEMBER_EPIPE(spinfo, cond)
104 
105 #define RESTORE_SIGPIPE(conn, spinfo) \
106  do { \
107  if (!SIGPIPE_MASKED(conn)) \
108  pqsignal(SIGPIPE, spinfo); \
109  } while (0)
110 #endif /* ENABLE_THREAD_SAFETY */
111 #else /* WIN32 */
112 
113 #define DECLARE_SIGPIPE_INFO(spinfo)
114 #define DISABLE_SIGPIPE(conn, spinfo, failaction)
115 #define REMEMBER_EPIPE(spinfo, cond)
116 #define RESTORE_SIGPIPE(conn, spinfo)
117 #endif /* WIN32 */
118 
119 /* ------------------------------------------------------------ */
120 /* Procedures common to all secure sessions */
121 /* ------------------------------------------------------------ */
122 
123 
124 int
126 {
127  if (!conn)
128  return 0;
129  return conn->ssl_in_use;
130 }
131 
132 /*
133  * Exported function to allow application to tell us it's already
134  * initialized OpenSSL.
135  */
136 void
138 {
139 #ifdef USE_SSL
141 #endif
142 }
143 
144 /*
145  * Exported function to allow application to tell us it's already
146  * initialized OpenSSL and/or libcrypto.
147  */
148 void
149 PQinitOpenSSL(int do_ssl, int do_crypto)
150 {
151 #ifdef USE_SSL
152  pgtls_init_library(do_ssl, do_crypto);
153 #endif
154 }
155 
156 /*
157  * Initialize global SSL context
158  */
159 int
160 pqsecure_initialize(PGconn *conn, bool do_ssl, bool do_crypto)
161 {
162  int r = 0;
163 
164 #ifdef USE_SSL
165  r = pgtls_init(conn, do_ssl, do_crypto);
166 #endif
167 
168  return r;
169 }
170 
171 /*
172  * Begin or continue negotiating a secure session.
173  */
176 {
177 #ifdef USE_SSL
178  return pgtls_open_client(conn);
179 #else
180  /* shouldn't get here */
181  return PGRES_POLLING_FAILED;
182 #endif
183 }
184 
185 /*
186  * Close secure session.
187  */
188 void
190 {
191 #ifdef USE_SSL
192  pgtls_close(conn);
193 #endif
194 }
195 
196 /*
197  * Read data from a secure connection.
198  *
199  * On failure, this function is responsible for appending a suitable message
200  * to conn->errorMessage. The caller must still inspect errno, but only
201  * to determine whether to continue/retry after error.
202  */
203 ssize_t
204 pqsecure_read(PGconn *conn, void *ptr, size_t len)
205 {
206  ssize_t n;
207 
208 #ifdef USE_SSL
209  if (conn->ssl_in_use)
210  {
211  n = pgtls_read(conn, ptr, len);
212  }
213  else
214 #endif
215 #ifdef ENABLE_GSS
216  if (conn->gssenc)
217  {
218  n = pg_GSS_read(conn, ptr, len);
219  }
220  else
221 #endif
222  {
223  n = pqsecure_raw_read(conn, ptr, len);
224  }
225 
226  return n;
227 }
228 
229 ssize_t
230 pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
231 {
232  ssize_t n;
233  int result_errno = 0;
234  char sebuf[PG_STRERROR_R_BUFLEN];
235 
236  n = recv(conn->sock, ptr, len, 0);
237 
238  if (n < 0)
239  {
240  result_errno = SOCK_ERRNO;
241 
242  /* Set error message if appropriate */
243  switch (result_errno)
244  {
245 #ifdef EAGAIN
246  case EAGAIN:
247 #endif
248 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
249  case EWOULDBLOCK:
250 #endif
251  case EINTR:
252  /* no error message, caller is expected to retry */
253  break;
254 
255  case EPIPE:
256  case ECONNRESET:
257  libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
258  "\tThis probably means the server terminated abnormally\n"
259  "\tbefore or while processing the request.");
260  break;
261 
262  default:
263  libpq_append_conn_error(conn, "could not receive data from server: %s",
264  SOCK_STRERROR(result_errno,
265  sebuf, sizeof(sebuf)));
266  break;
267  }
268  }
269 
270  /* ensure we return the intended errno to caller */
271  SOCK_ERRNO_SET(result_errno);
272 
273  return n;
274 }
275 
276 /*
277  * Write data to a secure connection.
278  *
279  * Returns the number of bytes written, or a negative value (with errno
280  * set) upon failure. The write count could be less than requested.
281  *
282  * Note that socket-level hard failures are masked from the caller,
283  * instead setting conn->write_failed and storing an error message
284  * in conn->write_err_msg; see pqsecure_raw_write. This allows us to
285  * postpone reporting of write failures until we're sure no error
286  * message is available from the server.
287  *
288  * However, errors detected in the SSL or GSS management level are reported
289  * via a negative result, with message appended to conn->errorMessage.
290  * It's frequently unclear whether such errors should be considered read or
291  * write errors, so we don't attempt to postpone reporting them.
292  *
293  * The caller must still inspect errno upon failure, but only to determine
294  * whether to continue/retry; a message has been saved someplace in any case.
295  */
296 ssize_t
297 pqsecure_write(PGconn *conn, const void *ptr, size_t len)
298 {
299  ssize_t n;
300 
301 #ifdef USE_SSL
302  if (conn->ssl_in_use)
303  {
304  n = pgtls_write(conn, ptr, len);
305  }
306  else
307 #endif
308 #ifdef ENABLE_GSS
309  if (conn->gssenc)
310  {
311  n = pg_GSS_write(conn, ptr, len);
312  }
313  else
314 #endif
315  {
316  n = pqsecure_raw_write(conn, ptr, len);
317  }
318 
319  return n;
320 }
321 
322 /*
323  * Low-level implementation of pqsecure_write.
324  *
325  * This is used directly for an unencrypted connection. For encrypted
326  * connections, this does the physical I/O on behalf of pgtls_write or
327  * pg_GSS_write.
328  *
329  * This function reports failure (i.e., returns a negative result) only
330  * for retryable errors such as EINTR. Looping for such cases is to be
331  * handled at some outer level, maybe all the way up to the application.
332  * For hard failures, we set conn->write_failed and store an error message
333  * in conn->write_err_msg, but then claim to have written the data anyway.
334  * This is because we don't want to report write failures so long as there
335  * is a possibility of reading from the server and getting an error message
336  * that could explain why the connection dropped. Many TCP stacks have
337  * race conditions such that a write failure may or may not be reported
338  * before all incoming data has been read.
339  *
340  * Note that this error behavior happens below the SSL management level when
341  * we are using SSL. That's because at least some versions of OpenSSL are
342  * too quick to report a write failure when there's still a possibility to
343  * get a more useful error from the server.
344  */
345 ssize_t
346 pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
347 {
348  ssize_t n;
349  int flags = 0;
350  int result_errno = 0;
351  char msgbuf[1024];
352  char sebuf[PG_STRERROR_R_BUFLEN];
353 
354  DECLARE_SIGPIPE_INFO(spinfo);
355 
356  /*
357  * If we already had a write failure, we will never again try to send data
358  * on that connection. Even if the kernel would let us, we've probably
359  * lost message boundary sync with the server. conn->write_failed
360  * therefore persists until the connection is reset, and we just discard
361  * all data presented to be written.
362  */
363  if (conn->write_failed)
364  return len;
365 
366 #ifdef MSG_NOSIGNAL
367  if (conn->sigpipe_flag)
368  flags |= MSG_NOSIGNAL;
369 
370 retry_masked:
371 #endif /* MSG_NOSIGNAL */
372 
373  DISABLE_SIGPIPE(conn, spinfo, return -1);
374 
375  n = send(conn->sock, ptr, len, flags);
376 
377  if (n < 0)
378  {
379  result_errno = SOCK_ERRNO;
380 
381  /*
382  * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
383  * on this machine. So, clear sigpipe_flag so we don't try the flag
384  * again, and retry the send().
385  */
386 #ifdef MSG_NOSIGNAL
387  if (flags != 0 && result_errno == EINVAL)
388  {
389  conn->sigpipe_flag = false;
390  flags = 0;
391  goto retry_masked;
392  }
393 #endif /* MSG_NOSIGNAL */
394 
395  /* Set error message if appropriate */
396  switch (result_errno)
397  {
398 #ifdef EAGAIN
399  case EAGAIN:
400 #endif
401 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
402  case EWOULDBLOCK:
403 #endif
404  case EINTR:
405  /* no error message, caller is expected to retry */
406  break;
407 
408  case EPIPE:
409  /* Set flag for EPIPE */
410  REMEMBER_EPIPE(spinfo, true);
411 
412  /* FALL THRU */
413 
414  case ECONNRESET:
415  conn->write_failed = true;
416  /* Store error message in conn->write_err_msg, if possible */
417  /* (strdup failure is OK, we'll cope later) */
418  snprintf(msgbuf, sizeof(msgbuf),
419  libpq_gettext("server closed the connection unexpectedly\n"
420  "\tThis probably means the server terminated abnormally\n"
421  "\tbefore or while processing the request."));
422  /* keep newline out of translated string */
423  strlcat(msgbuf, "\n", sizeof(msgbuf));
424  conn->write_err_msg = strdup(msgbuf);
425  /* Now claim the write succeeded */
426  n = len;
427  break;
428 
429  default:
430  conn->write_failed = true;
431  /* Store error message in conn->write_err_msg, if possible */
432  /* (strdup failure is OK, we'll cope later) */
433  snprintf(msgbuf, sizeof(msgbuf),
434  libpq_gettext("could not send data to server: %s"),
435  SOCK_STRERROR(result_errno,
436  sebuf, sizeof(sebuf)));
437  /* keep newline out of translated string */
438  strlcat(msgbuf, "\n", sizeof(msgbuf));
439  conn->write_err_msg = strdup(msgbuf);
440  /* Now claim the write succeeded */
441  n = len;
442  break;
443  }
444  }
445 
446  RESTORE_SIGPIPE(conn, spinfo);
447 
448  /* ensure we return the intended errno to caller */
449  SOCK_ERRNO_SET(result_errno);
450 
451  return n;
452 }
453 
454 /* Dummy versions of SSL info functions, when built without SSL support */
455 #ifndef USE_SSL
456 
457 void *
459 {
460  return NULL;
461 }
462 
463 void *
464 PQsslStruct(PGconn *conn, const char *struct_name)
465 {
466  return NULL;
467 }
468 
469 const char *
470 PQsslAttribute(PGconn *conn, const char *attribute_name)
471 {
472  return NULL;
473 }
474 
475 const char *const *
477 {
478  static const char *const result[] = {NULL};
479 
480  return result;
481 }
482 #endif /* USE_SSL */
483 
484 /*
485  * Dummy versions of OpenSSL key password hook functions, when built without
486  * OpenSSL.
487  */
488 #ifndef USE_OPENSSL
489 
492 {
493  return NULL;
494 }
495 
496 void
498 {
499  return;
500 }
501 
502 int
504 {
505  return 0;
506 }
507 #endif /* USE_OPENSSL */
508 
509 /* Dummy version of GSSAPI information functions, when built without GSS support */
510 #ifndef ENABLE_GSS
511 
512 void *
514 {
515  return NULL;
516 }
517 
518 int
520 {
521  return 0;
522 }
523 
524 #endif /* ENABLE_GSS */
525 
526 
527 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
528 
529 /*
530  * Block SIGPIPE for this thread. This prevents send()/write() from exiting
531  * the application.
532  */
533 int
534 pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
535 {
536  sigset_t sigpipe_sigset;
537  sigset_t sigset;
538 
539  sigemptyset(&sigpipe_sigset);
540  sigaddset(&sigpipe_sigset, SIGPIPE);
541 
542  /* Block SIGPIPE and save previous mask for later reset */
543  SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
544  if (SOCK_ERRNO)
545  return -1;
546 
547  /* We can have a pending SIGPIPE only if it was blocked before */
548  if (sigismember(osigset, SIGPIPE))
549  {
550  /* Is there a pending SIGPIPE? */
551  if (sigpending(&sigset) != 0)
552  return -1;
553 
554  if (sigismember(&sigset, SIGPIPE))
555  *sigpipe_pending = true;
556  else
557  *sigpipe_pending = false;
558  }
559  else
560  *sigpipe_pending = false;
561 
562  return 0;
563 }
564 
565 /*
566  * Discard any pending SIGPIPE and reset the signal mask.
567  *
568  * Note: we are effectively assuming here that the C library doesn't queue
569  * up multiple SIGPIPE events. If it did, then we'd accidentally leave
570  * ours in the queue when an event was already pending and we got another.
571  * As long as it doesn't queue multiple events, we're OK because the caller
572  * can't tell the difference.
573  *
574  * The caller should say got_epipe = false if it is certain that it
575  * didn't get an EPIPE error; in that case we'll skip the clear operation
576  * and things are definitely OK, queuing or no. If it got one or might have
577  * gotten one, pass got_epipe = true.
578  *
579  * We do not want this to change errno, since if it did that could lose
580  * the error code from a preceding send(). We essentially assume that if
581  * we were able to do pq_block_sigpipe(), this can't fail.
582  */
583 void
584 pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
585 {
586  int save_errno = SOCK_ERRNO;
587  int signo;
588  sigset_t sigset;
589 
590  /* Clear SIGPIPE only if none was pending */
591  if (got_epipe && !sigpipe_pending)
592  {
593  if (sigpending(&sigset) == 0 &&
594  sigismember(&sigset, SIGPIPE))
595  {
596  sigset_t sigpipe_sigset;
597 
598  sigemptyset(&sigpipe_sigset);
599  sigaddset(&sigpipe_sigset, SIGPIPE);
600 
601  sigwait(&sigpipe_sigset, &signo);
602  }
603  }
604 
605  /* Restore saved block mask */
606  pthread_sigmask(SIG_SETMASK, osigset, NULL);
607 
608  SOCK_ERRNO_SET(save_errno);
609 }
610 
611 #endif /* ENABLE_THREAD_SAFETY && !WIN32 */
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1312
ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len)
ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
PostgresPollingStatusType pgtls_open_client(PGconn *conn)
void pgtls_init_library(bool do_ssl, int do_crypto)
ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len)
ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len)
int pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
void pgtls_close(PGconn *conn)
ssize_t pqsecure_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:297
void PQinitSSL(int do_init)
Definition: fe-secure.c:137
PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void)
Definition: fe-secure.c:491
#define REMEMBER_EPIPE(spinfo, cond)
Definition: fe-secure.c:103
int PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)
Definition: fe-secure.c:503
PostgresPollingStatusType pqsecure_open_client(PGconn *conn)
Definition: fe-secure.c:175
int PQgssEncInUse(PGconn *conn)
Definition: fe-secure.c:519
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
Definition: fe-secure.c:97
void PQinitOpenSSL(int do_ssl, int do_crypto)
Definition: fe-secure.c:149
int PQsslInUse(PGconn *conn)
Definition: fe-secure.c:125
ssize_t pqsecure_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:204
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:230
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:346
const char *const * PQsslAttributeNames(PGconn *conn)
Definition: fe-secure.c:476
void * PQgetssl(PGconn *conn)
Definition: fe-secure.c:458
void * PQsslStruct(PGconn *conn, const char *struct_name)
Definition: fe-secure.c:464
void * PQgetgssctx(PGconn *conn)
Definition: fe-secure.c:513
void pqsecure_close(PGconn *conn)
Definition: fe-secure.c:189
int pqsecure_initialize(PGconn *conn, bool do_ssl, bool do_crypto)
Definition: fe-secure.c:160
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
Definition: fe-secure.c:470
#define DECLARE_SIGPIPE_INFO(spinfo)
Definition: fe-secure.c:95
void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook)
Definition: fe-secure.c:497
#define RESTORE_SIGPIPE(conn, spinfo)
Definition: fe-secure.c:105
int(* PQsslKeyPassHook_OpenSSL_type)(char *buf, int size, PGconn *conn)
Definition: libpq-fe.h:665
PostgresPollingStatusType
Definition: libpq-fe.h:85
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:86
#define libpq_gettext(x)
Definition: libpq-int.h:882
#define SOCK_STRERROR
Definition: libpq-int.h:904
#define SOCK_ERRNO
Definition: libpq-int.h:903
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:905
const void size_t len
static void do_init(void)
Definition: pg_ctl.c:895
static char * buf
Definition: pg_test_fsync.c:67
#define PG_STRERROR_R_BUFLEN
Definition: port.h:256
#define snprintf
Definition: port.h:238
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: strlcat.c:33
PGconn * conn
Definition: streamutil.c:54
char * write_err_msg
Definition: libpq-int.h:458
bool sigpipe_flag
Definition: libpq-int.h:456
pgsocket sock
Definition: libpq-int.h:447
bool write_failed
Definition: libpq-int.h:457
bool ssl_in_use
Definition: libpq-int.h:520
#define EINTR
Definition: win32_port.h:369
#define EWOULDBLOCK
Definition: win32_port.h:375
#define SIGPIPE
Definition: win32_port.h:181
#define recv(s, buf, len, flags)
Definition: win32_port.h:493
#define send(s, buf, len, flags)
Definition: win32_port.h:494
#define ECONNRESET
Definition: win32_port.h:379
#define EAGAIN
Definition: win32_port.h:367