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