Branch data Line data Source code
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 : :
57 : : struct sigpipe_info
58 : : {
59 : : sigset_t oldsigmask;
60 : : bool sigpipe_pending;
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
103 : 3 : PQsslInUse(PGconn *conn)
104 : : {
105 [ - + ]: 3 : if (!conn)
106 : 0 : return 0;
107 : 3 : 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
117 : 0 : PQinitSSL(int do_init)
118 : : {
119 : : /* no-op */
120 : 0 : }
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 : 0 : PQinitOpenSSL(int do_ssl, int do_crypto)
130 : : {
131 : : /* no-op */
132 : 0 : }
133 : :
134 : : /*
135 : : * Begin or continue negotiating a secure session.
136 : : */
137 : : PostgresPollingStatusType
138 : 318 : pqsecure_open_client(PGconn *conn)
139 : : {
140 : : #ifdef USE_SSL
141 : 318 : 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
152 : 32653 : pqsecure_close(PGconn *conn)
153 : : {
154 : : #ifdef USE_SSL
155 : 32653 : pgtls_close(conn);
156 : : #endif
157 : 32653 : }
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 : 1229279 : pqsecure_read(PGconn *conn, void *ptr, size_t len)
168 : : {
169 : : ssize_t n;
170 : :
171 : : #ifdef USE_SSL
172 [ + + ]: 1229279 : if (conn->ssl_in_use)
173 : : {
174 : 368 : 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 : 1228911 : n = pqsecure_raw_read(conn, ptr, len);
187 : : }
188 : :
189 : 1229279 : return n;
190 : : }
191 : :
192 : : ssize_t
193 : 1232151 : pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
194 : : {
195 : : ssize_t n;
196 : 1232151 : int result_errno = 0;
197 : : char sebuf[PG_STRERROR_R_BUFLEN];
198 : :
199 : 1232151 : SOCK_ERRNO_SET(0);
200 : :
201 : 1232151 : n = recv(conn->sock, ptr, len, 0);
202 : :
203 [ + + ]: 1232151 : if (n < 0)
204 : : {
205 : 424313 : result_errno = SOCK_ERRNO;
206 : :
207 : : /* Set error message if appropriate */
208 [ + + - - ]: 424313 : switch (result_errno)
209 : : {
210 : : #ifdef EAGAIN
211 : 424303 : 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 : 424303 : break;
219 : :
220 : 10 : case EPIPE:
221 : : case ECONNRESET:
222 : 10 : 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 : 10 : break;
226 : :
227 : 0 : case 0:
228 : : /* If errno didn't get set, treat it as regular EOF */
229 : 0 : n = 0;
230 : 0 : break;
231 : :
232 : 0 : default:
233 : 0 : libpq_append_conn_error(conn, "could not receive data from server: %s",
234 : : SOCK_STRERROR(result_errno,
235 : : sebuf, sizeof(sebuf)));
236 : 0 : break;
237 : : }
238 : : }
239 : :
240 : : /* ensure we return the intended errno to caller */
241 : 1232151 : SOCK_ERRNO_SET(result_errno);
242 : :
243 : 1232151 : 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 : : */
254 : : ssize_t
255 : 1390230 : pqsecure_bytes_pending(PGconn *conn)
256 : : {
257 : : #ifdef USE_SSL
258 [ + + ]: 1390230 : if (conn->ssl_in_use)
259 : 653 : return pgtls_bytes_pending(conn);
260 : : #endif
261 : : #ifdef ENABLE_GSS
262 : : if (conn->gssenc)
263 : : return pg_GSS_bytes_pending(conn);
264 : : #endif
265 : :
266 : : /* Plaintext connections have no transport buffer. */
267 : 1389577 : 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 : : */
290 : : ssize_t
291 : 574073 : pqsecure_write(PGconn *conn, const void *ptr, size_t len)
292 : : {
293 : : ssize_t n;
294 : :
295 : : #ifdef USE_SSL
296 [ + + ]: 574073 : if (conn->ssl_in_use)
297 : : {
298 : 367 : 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 : 573706 : n = pqsecure_raw_write(conn, ptr, len);
311 : : }
312 : :
313 : 574073 : 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 : : */
339 : : ssize_t
340 : 574691 : pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
341 : : {
342 : : ssize_t n;
343 : 574691 : int flags = 0;
344 : 574691 : int result_errno = 0;
345 : : char msgbuf[1024];
346 : : char sebuf[PG_STRERROR_R_BUFLEN];
347 : :
348 : : DECLARE_SIGPIPE_INFO(spinfo);
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 [ - + ]: 574691 : if (conn->write_failed)
358 : 0 : return len;
359 : :
360 : : #ifdef MSG_NOSIGNAL
361 [ - + ]: 574691 : if (conn->sigpipe_flag)
362 : 574691 : flags |= MSG_NOSIGNAL;
363 : :
364 : 574691 : retry_masked:
365 : : #endif /* MSG_NOSIGNAL */
366 : :
367 [ + - - + : 574691 : DISABLE_SIGPIPE(conn, spinfo, return -1);
- - ]
368 : :
369 : 574691 : n = send(conn->sock, ptr, len, flags);
370 : :
371 [ + + ]: 574691 : if (n < 0)
372 : : {
373 : 42 : result_errno = SOCK_ERRNO;
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 [ + - - + ]: 42 : if (flags != 0 && result_errno == EINVAL)
382 : : {
383 : 0 : conn->sigpipe_flag = false;
384 : 0 : flags = 0;
385 : 0 : goto retry_masked;
386 : : }
387 : : #endif /* MSG_NOSIGNAL */
388 : :
389 : : /* Set error message if appropriate */
390 [ + + - - ]: 42 : switch (result_errno)
391 : : {
392 : : #ifdef EAGAIN
393 : 11 : 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 : 11 : break;
401 : :
402 : 31 : case EPIPE:
403 : : /* Set flag for EPIPE */
404 : 31 : REMEMBER_EPIPE(spinfo, true);
405 : :
406 : : pg_fallthrough;
407 : :
408 : : case ECONNRESET:
409 : 31 : 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 : 31 : snprintf(msgbuf, sizeof(msgbuf),
413 : 31 : 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 : 31 : strlcat(msgbuf, "\n", sizeof(msgbuf));
418 : 31 : conn->write_err_msg = strdup(msgbuf);
419 : : /* Now claim the write succeeded */
420 : 31 : n = len;
421 : 31 : break;
422 : :
423 : 0 : default:
424 : 0 : 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 : 0 : snprintf(msgbuf, sizeof(msgbuf),
428 : 0 : libpq_gettext("could not send data to server: %s"),
429 : : SOCK_STRERROR(result_errno,
430 : : sebuf, sizeof(sebuf)));
431 : : /* keep newline out of translated string */
432 : 0 : strlcat(msgbuf, "\n", sizeof(msgbuf));
433 : 0 : conn->write_err_msg = strdup(msgbuf);
434 : : /* Now claim the write succeeded */
435 : 0 : n = len;
436 : 0 : break;
437 : : }
438 : : }
439 : :
440 [ + - - + ]: 574691 : RESTORE_SIGPIPE(conn, spinfo);
441 : :
442 : : /* ensure we return the intended errno to caller */
443 : 574691 : SOCK_ERRNO_SET(result_errno);
444 : :
445 : 574691 : return n;
446 : : }
447 : :
448 : : /* Dummy versions of SSL info functions, when built without SSL support */
449 : : #ifndef USE_SSL
450 : :
451 : : void *
452 : : PQgetssl(PGconn *conn)
453 : : {
454 : : return NULL;
455 : : }
456 : :
457 : : void *
458 : : PQsslStruct(PGconn *conn, const char *struct_name)
459 : : {
460 : : return NULL;
461 : : }
462 : :
463 : : const char *
464 : : PQsslAttribute(PGconn *conn, const char *attribute_name)
465 : : {
466 : : return NULL;
467 : : }
468 : :
469 : : const char *const *
470 : : PQsslAttributeNames(PGconn *conn)
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 : :
484 : : PQsslKeyPassHook_OpenSSL_type
485 : : PQgetSSLKeyPassHook_OpenSSL(void)
486 : : {
487 : : return NULL;
488 : : }
489 : :
490 : : void
491 : : PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook)
492 : : {
493 : : return;
494 : : }
495 : :
496 : : int
497 : : PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)
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 : :
506 : : void *
507 : 0 : PQgetgssctx(PGconn *conn)
508 : : {
509 : 0 : return NULL;
510 : : }
511 : :
512 : : int
513 : 3 : PQgssEncInUse(PGconn *conn)
514 : : {
515 : 3 : 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 : : */
527 : : int
528 : 0 : pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
529 : : {
530 : : sigset_t sigpipe_sigset;
531 : : sigset_t sigset;
532 : :
533 : 0 : sigemptyset(&sigpipe_sigset);
534 : 0 : sigaddset(&sigpipe_sigset, SIGPIPE);
535 : :
536 : : /* Block SIGPIPE and save previous mask for later reset */
537 : 0 : SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
538 [ # # ]: 0 : if (SOCK_ERRNO)
539 : 0 : return -1;
540 : :
541 : : /* We can have a pending SIGPIPE only if it was blocked before */
542 [ # # ]: 0 : if (sigismember(osigset, SIGPIPE))
543 : : {
544 : : /* Is there a pending SIGPIPE? */
545 [ # # ]: 0 : if (sigpending(&sigset) != 0)
546 : 0 : return -1;
547 : :
548 [ # # ]: 0 : if (sigismember(&sigset, SIGPIPE))
549 : 0 : *sigpipe_pending = true;
550 : : else
551 : 0 : *sigpipe_pending = false;
552 : : }
553 : : else
554 : 0 : *sigpipe_pending = false;
555 : :
556 : 0 : 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 : : */
577 : : void
578 : 0 : pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
579 : : {
580 : 0 : int save_errno = SOCK_ERRNO;
581 : : int signo;
582 : : sigset_t sigset;
583 : :
584 : : /* Clear SIGPIPE only if none was pending */
585 [ # # # # ]: 0 : if (got_epipe && !sigpipe_pending)
586 : : {
587 [ # # # # ]: 0 : if (sigpending(&sigset) == 0 &&
588 : 0 : sigismember(&sigset, SIGPIPE))
589 : : {
590 : : sigset_t sigpipe_sigset;
591 : :
592 : 0 : sigemptyset(&sigpipe_sigset);
593 : 0 : sigaddset(&sigpipe_sigset, SIGPIPE);
594 : :
595 : 0 : sigwait(&sigpipe_sigset, &signo);
596 : : }
597 : : }
598 : :
599 : : /* Restore saved block mask */
600 : 0 : pthread_sigmask(SIG_SETMASK, osigset, NULL);
601 : :
602 : 0 : SOCK_ERRNO_SET(save_errno);
603 : 0 : }
604 : :
605 : : #endif /* !WIN32 */
|