PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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-2026, 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
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
102int
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 */
116void
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 */
128void
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 */
145#endif
146}
147
148/*
149 * Close secure session.
150 */
151void
153{
154#ifdef USE_SSL
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 */
167pqsecure_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
193pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
194{
195 ssize_t n;
196 int result_errno = 0;
198
200
201 n = recv(conn->sock, ptr, len, 0);
202
203 if (n < 0)
204 {
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",
235 sebuf, sizeof(sebuf)));
236 break;
237 }
238 }
239
240 /* ensure we return the intended errno to caller */
242
243 return n;
244}
245
246/*
247 * Return the number of bytes available in the transport buffer.
248 *
249 * If pqsecure_read() is called for this number of bytes, it's guaranteed to
250 * return successfully with the same number of bytes, without reading from the
251 * underlying socket. See pqDrainPending() for a more complete discussion of
252 * the concepts involved.
253 */
256{
257#ifdef USE_SSL
258 if (conn->ssl_in_use)
260#endif
261#ifdef ENABLE_GSS
262 if (conn->gssenc)
264#endif
265
266 /* Plaintext connections have no transport buffer. */
267 return 0;
268}
269
270/*
271 * Write data to a secure connection.
272 *
273 * Returns the number of bytes written, or a negative value (with errno
274 * set) upon failure. The write count could be less than requested.
275 *
276 * Note that socket-level hard failures are masked from the caller,
277 * instead setting conn->write_failed and storing an error message
278 * in conn->write_err_msg; see pqsecure_raw_write. This allows us to
279 * postpone reporting of write failures until we're sure no error
280 * message is available from the server.
281 *
282 * However, errors detected in the SSL or GSS management level are reported
283 * via a negative result, with message appended to conn->errorMessage.
284 * It's frequently unclear whether such errors should be considered read or
285 * write errors, so we don't attempt to postpone reporting them.
286 *
287 * The caller must still inspect errno upon failure, but only to determine
288 * whether to continue/retry; a message has been saved someplace in any case.
289 */
291pqsecure_write(PGconn *conn, const void *ptr, size_t len)
292{
293 ssize_t n;
294
295#ifdef USE_SSL
296 if (conn->ssl_in_use)
297 {
298 n = pgtls_write(conn, ptr, len);
299 }
300 else
301#endif
302#ifdef ENABLE_GSS
303 if (conn->gssenc)
304 {
305 n = pg_GSS_write(conn, ptr, len);
306 }
307 else
308#endif
309 {
310 n = pqsecure_raw_write(conn, ptr, len);
311 }
312
313 return n;
314}
315
316/*
317 * Low-level implementation of pqsecure_write.
318 *
319 * This is used directly for an unencrypted connection. For encrypted
320 * connections, this does the physical I/O on behalf of pgtls_write or
321 * pg_GSS_write.
322 *
323 * This function reports failure (i.e., returns a negative result) only
324 * for retryable errors such as EINTR. Looping for such cases is to be
325 * handled at some outer level, maybe all the way up to the application.
326 * For hard failures, we set conn->write_failed and store an error message
327 * in conn->write_err_msg, but then claim to have written the data anyway.
328 * This is because we don't want to report write failures so long as there
329 * is a possibility of reading from the server and getting an error message
330 * that could explain why the connection dropped. Many TCP stacks have
331 * race conditions such that a write failure may or may not be reported
332 * before all incoming data has been read.
333 *
334 * Note that this error behavior happens below the SSL management level when
335 * we are using SSL. That's because at least some versions of OpenSSL are
336 * too quick to report a write failure when there's still a possibility to
337 * get a more useful error from the server.
338 */
340pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
341{
342 ssize_t n;
343 int flags = 0;
344 int result_errno = 0;
345 char msgbuf[1024];
347
349
350 /*
351 * If we already had a write failure, we will never again try to send data
352 * on that connection. Even if the kernel would let us, we've probably
353 * lost message boundary sync with the server. conn->write_failed
354 * therefore persists until the connection is reset, and we just discard
355 * all data presented to be written.
356 */
357 if (conn->write_failed)
358 return len;
359
360#ifdef MSG_NOSIGNAL
361 if (conn->sigpipe_flag)
362 flags |= MSG_NOSIGNAL;
363
365#endif /* MSG_NOSIGNAL */
366
367 DISABLE_SIGPIPE(conn, spinfo, return -1);
368
369 n = send(conn->sock, ptr, len, flags);
370
371 if (n < 0)
372 {
374
375 /*
376 * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
377 * on this machine. So, clear sigpipe_flag so we don't try the flag
378 * again, and retry the send().
379 */
380#ifdef MSG_NOSIGNAL
381 if (flags != 0 && result_errno == EINVAL)
382 {
383 conn->sigpipe_flag = false;
384 flags = 0;
385 goto retry_masked;
386 }
387#endif /* MSG_NOSIGNAL */
388
389 /* Set error message if appropriate */
390 switch (result_errno)
391 {
392#ifdef EAGAIN
393 case EAGAIN:
394#endif
395#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
396 case EWOULDBLOCK:
397#endif
398 case EINTR:
399 /* no error message, caller is expected to retry */
400 break;
401
402 case EPIPE:
403 /* Set flag for EPIPE */
404 REMEMBER_EPIPE(spinfo, true);
405
407
408 case ECONNRESET:
409 conn->write_failed = true;
410 /* Store error message in conn->write_err_msg, if possible */
411 /* (strdup failure is OK, we'll cope later) */
412 snprintf(msgbuf, sizeof(msgbuf),
413 libpq_gettext("server closed the connection unexpectedly\n"
414 "\tThis probably means the server terminated abnormally\n"
415 "\tbefore or while processing the request."));
416 /* keep newline out of translated string */
417 strlcat(msgbuf, "\n", sizeof(msgbuf));
419 /* Now claim the write succeeded */
420 n = len;
421 break;
422
423 default:
424 conn->write_failed = true;
425 /* Store error message in conn->write_err_msg, if possible */
426 /* (strdup failure is OK, we'll cope later) */
427 snprintf(msgbuf, sizeof(msgbuf),
428 libpq_gettext("could not send data to server: %s"),
430 sebuf, sizeof(sebuf)));
431 /* keep newline out of translated string */
432 strlcat(msgbuf, "\n", sizeof(msgbuf));
434 /* Now claim the write succeeded */
435 n = len;
436 break;
437 }
438 }
439
441
442 /* ensure we return the intended errno to caller */
444
445 return n;
446}
447
448/* Dummy versions of SSL info functions, when built without SSL support */
449#ifndef USE_SSL
450
451void *
453{
454 return NULL;
455}
456
457void *
459{
460 return NULL;
461}
462
463const char *
465{
466 return NULL;
467}
468
469const char *const *
471{
472 static const char *const result[] = {NULL};
473
474 return result;
475}
476#endif /* USE_SSL */
477
478/*
479 * Dummy versions of OpenSSL key password hook functions, when built without
480 * OpenSSL.
481 */
482#ifndef USE_OPENSSL
483
486{
487 return NULL;
488}
489
490void
495
496int
498{
499 return 0;
500}
501#endif /* USE_OPENSSL */
502
503/* Dummy version of GSSAPI information functions, when built without GSS support */
504#ifndef ENABLE_GSS
505
506void *
508{
509 return NULL;
510}
511
512int
514{
515 return 0;
516}
517
518#endif /* ENABLE_GSS */
519
520
521#if !defined(WIN32)
522
523/*
524 * Block SIGPIPE for this thread. This prevents send()/write() from exiting
525 * the application.
526 */
527int
528pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
529{
532
535
536 /* Block SIGPIPE and save previous mask for later reset */
538 if (SOCK_ERRNO)
539 return -1;
540
541 /* We can have a pending SIGPIPE only if it was blocked before */
543 {
544 /* Is there a pending SIGPIPE? */
545 if (sigpending(&sigset) != 0)
546 return -1;
547
549 *sigpipe_pending = true;
550 else
551 *sigpipe_pending = false;
552 }
553 else
554 *sigpipe_pending = false;
555
556 return 0;
557}
558
559/*
560 * Discard any pending SIGPIPE and reset the signal mask.
561 *
562 * Note: we are effectively assuming here that the C library doesn't queue
563 * up multiple SIGPIPE events. If it did, then we'd accidentally leave
564 * ours in the queue when an event was already pending and we got another.
565 * As long as it doesn't queue multiple events, we're OK because the caller
566 * can't tell the difference.
567 *
568 * The caller should say got_epipe = false if it is certain that it
569 * didn't get an EPIPE error; in that case we'll skip the clear operation
570 * and things are definitely OK, queuing or no. If it got one or might have
571 * gotten one, pass got_epipe = true.
572 *
573 * We do not want this to change errno, since if it did that could lose
574 * the error code from a preceding send(). We essentially assume that if
575 * we were able to do pq_block_sigpipe(), this can't fail.
576 */
577void
578pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
579{
581 int signo;
583
584 /* Clear SIGPIPE only if none was pending */
585 if (got_epipe && !sigpipe_pending)
586 {
587 if (sigpending(&sigset) == 0 &&
589 {
591
594
596 }
597 }
598
599 /* Restore saved block mask */
601
603}
604
605#endif /* !WIN32 */
#define pg_fallthrough
Definition c.h:220
uint32 result
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition fe-misc.c:1548
ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len)
ssize_t pg_GSS_bytes_pending(PGconn *conn)
ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
ssize_t pgtls_bytes_pending(PGconn *conn)
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:291
void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
Definition fe-secure.c:578
void PQinitSSL(int do_init)
Definition fe-secure.c:117
void * PQgetssl(PGconn *conn)
Definition fe-secure.c:452
PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void)
Definition fe-secure.c:485
void * PQsslStruct(PGconn *conn, const char *struct_name)
Definition fe-secure.c:458
#define REMEMBER_EPIPE(spinfo, cond)
Definition fe-secure.c:77
int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
Definition fe-secure.c:528
void * PQgetgssctx(PGconn *conn)
Definition fe-secure.c:507
int PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)
Definition fe-secure.c:497
PostgresPollingStatusType pqsecure_open_client(PGconn *conn)
Definition fe-secure.c:138
int PQgssEncInUse(PGconn *conn)
Definition fe-secure.c:513
ssize_t pqsecure_bytes_pending(PGconn *conn)
Definition fe-secure.c:255
#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:340
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
Definition fe-secure.c:464
void pqsecure_close(PGconn *conn)
Definition fe-secure.c:152
const char *const * PQsslAttributeNames(PGconn *conn)
Definition fe-secure.c:470
#define DECLARE_SIGPIPE_INFO(spinfo)
Definition fe-secure.c:64
void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook)
Definition fe-secure.c:491
#define RESTORE_SIGPIPE(conn, spinfo)
Definition fe-secure.c:83
int(* PQsslKeyPassHook_OpenSSL_type)(char *buf, int size, PGconn *conn)
Definition libpq-fe.h:868
PostgresPollingStatusType
Definition libpq-fe.h:120
@ PGRES_POLLING_FAILED
Definition libpq-fe.h:121
#define SOCK_STRERROR
Definition libpq-int.h:983
#define SOCK_ERRNO
Definition oauth-utils.c:86
#define SOCK_ERRNO_SET(e)
Definition oauth-utils.c:87
#define libpq_gettext(x)
Definition oauth-utils.h:44
const void size_t len
static void do_init(void)
Definition pg_ctl.c:905
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define PG_STRERROR_R_BUFLEN
Definition port.h:279
#define snprintf
Definition port.h:261
size_t strlcat(char *dst, const char *src, size_t siz)
Definition strlcat.c:34
static int fb(int x)
#define EINVAL
Definition private.h:69
PGconn * conn
Definition streamutil.c:52
char * write_err_msg
Definition libpq-int.h:516
bool sigpipe_flag
Definition libpq-int.h:514
pgsocket sock
Definition libpq-int.h:502
bool write_failed
Definition libpq-int.h:515
bool ssl_in_use
Definition libpq-int.h:623
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:378
#define EWOULDBLOCK
Definition win32_port.h:384
#define SIGPIPE
Definition win32_port.h:163
#define recv(s, buf, len, flags)
Definition win32_port.h:518
#define send(s, buf, len, flags)
Definition win32_port.h:519
#define ECONNRESET
Definition win32_port.h:388
#define EAGAIN
Definition win32_port.h:376