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