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-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 :
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 4 : PQsslInUse(PGconn *conn)
104 : {
105 4 : if (!conn)
106 0 : return 0;
107 4 : 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 752 : pqsecure_open_client(PGconn *conn)
139 : {
140 : #ifdef USE_SSL
141 752 : 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 53734 : pqsecure_close(PGconn *conn)
153 : {
154 : #ifdef USE_SSL
155 53734 : pgtls_close(conn);
156 : #endif
157 53734 : }
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 1994968 : pqsecure_read(PGconn *conn, void *ptr, size_t len)
168 : {
169 : ssize_t n;
170 :
171 : #ifdef USE_SSL
172 1994968 : if (conn->ssl_in_use)
173 : {
174 562 : 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 1994406 : n = pqsecure_raw_read(conn, ptr, len);
187 : }
188 :
189 1994968 : return n;
190 : }
191 :
192 : ssize_t
193 1999648 : pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
194 : {
195 : ssize_t n;
196 1999648 : int result_errno = 0;
197 : char sebuf[PG_STRERROR_R_BUFLEN];
198 :
199 1999648 : SOCK_ERRNO_SET(0);
200 :
201 1999648 : n = recv(conn->sock, ptr, len, 0);
202 :
203 1999648 : if (n < 0)
204 : {
205 591146 : result_errno = SOCK_ERRNO;
206 :
207 : /* Set error message if appropriate */
208 591146 : switch (result_errno)
209 : {
210 : #ifdef EAGAIN
211 591128 : 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 591128 : break;
219 :
220 18 : case EPIPE:
221 : case ECONNRESET:
222 18 : 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 18 : 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 1408502 : }
239 :
240 : /* ensure we return the intended errno to caller */
241 1999648 : SOCK_ERRNO_SET(result_errno);
242 :
243 1999648 : 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 707120 : pqsecure_write(PGconn *conn, const void *ptr, size_t len)
268 : {
269 : ssize_t n;
270 :
271 : #ifdef USE_SSL
272 707120 : if (conn->ssl_in_use)
273 : {
274 560 : 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 706560 : n = pqsecure_raw_write(conn, ptr, len);
287 : }
288 :
289 707120 : 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 708068 : pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
317 : {
318 : ssize_t n;
319 708068 : int flags = 0;
320 708068 : 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 708068 : if (conn->write_failed)
334 0 : return len;
335 :
336 : #ifdef MSG_NOSIGNAL
337 708068 : if (conn->sigpipe_flag)
338 708068 : flags |= MSG_NOSIGNAL;
339 :
340 708068 : retry_masked:
341 : #endif /* MSG_NOSIGNAL */
342 :
343 708068 : DISABLE_SIGPIPE(conn, spinfo, return -1);
344 :
345 708068 : n = send(conn->sock, ptr, len, flags);
346 :
347 708068 : if (n < 0)
348 : {
349 68 : 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 68 : if (flags != 0 && result_errno == EINVAL)
358 : {
359 0 : conn->sigpipe_flag = false;
360 0 : flags = 0;
361 0 : goto retry_masked;
362 : }
363 : #endif /* MSG_NOSIGNAL */
364 :
365 : /* Set error message if appropriate */
366 68 : switch (result_errno)
367 : {
368 : #ifdef EAGAIN
369 40 : 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 40 : break;
377 :
378 28 : case EPIPE:
379 : /* Set flag for EPIPE */
380 28 : REMEMBER_EPIPE(spinfo, true);
381 :
382 : /* FALL THRU */
383 :
384 : case ECONNRESET:
385 28 : 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 28 : snprintf(msgbuf, sizeof(msgbuf),
389 28 : 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 28 : strlcat(msgbuf, "\n", sizeof(msgbuf));
394 28 : conn->write_err_msg = strdup(msgbuf);
395 : /* Now claim the write succeeded */
396 28 : n = len;
397 28 : break;
398 :
399 0 : default:
400 0 : 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 0 : snprintf(msgbuf, sizeof(msgbuf),
404 0 : 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 0 : strlcat(msgbuf, "\n", sizeof(msgbuf));
409 0 : conn->write_err_msg = strdup(msgbuf);
410 : /* Now claim the write succeeded */
411 0 : n = len;
412 0 : break;
413 : }
414 708000 : }
415 :
416 708068 : RESTORE_SIGPIPE(conn, spinfo);
417 :
418 : /* ensure we return the intended errno to caller */
419 708068 : SOCK_ERRNO_SET(result_errno);
420 :
421 708068 : return n;
422 : }
423 :
424 : /* Dummy versions of SSL info functions, when built without SSL support */
425 : #ifndef USE_SSL
426 :
427 : void *
428 : PQgetssl(PGconn *conn)
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 *
446 : PQsslAttributeNames(PGconn *conn)
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 :
460 : PQsslKeyPassHook_OpenSSL_type
461 : PQgetSSLKeyPassHook_OpenSSL(void)
462 : {
463 : return NULL;
464 : }
465 :
466 : void
467 : PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook)
468 : {
469 : return;
470 : }
471 :
472 : int
473 : PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)
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 *
483 0 : PQgetgssctx(PGconn *conn)
484 : {
485 0 : return NULL;
486 : }
487 :
488 : int
489 4 : PQgssEncInUse(PGconn *conn)
490 : {
491 4 : 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 0 : pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
505 : {
506 : sigset_t sigpipe_sigset;
507 : sigset_t sigset;
508 :
509 0 : sigemptyset(&sigpipe_sigset);
510 0 : sigaddset(&sigpipe_sigset, SIGPIPE);
511 :
512 : /* Block SIGPIPE and save previous mask for later reset */
513 0 : SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
514 0 : if (SOCK_ERRNO)
515 0 : return -1;
516 :
517 : /* We can have a pending SIGPIPE only if it was blocked before */
518 0 : if (sigismember(osigset, SIGPIPE))
519 : {
520 : /* Is there a pending SIGPIPE? */
521 0 : if (sigpending(&sigset) != 0)
522 0 : return -1;
523 :
524 0 : if (sigismember(&sigset, SIGPIPE))
525 0 : *sigpipe_pending = true;
526 : else
527 0 : *sigpipe_pending = false;
528 : }
529 : else
530 0 : *sigpipe_pending = false;
531 :
532 0 : 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 0 : pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
555 : {
556 0 : int save_errno = SOCK_ERRNO;
557 : int signo;
558 : sigset_t sigset;
559 :
560 : /* Clear SIGPIPE only if none was pending */
561 0 : if (got_epipe && !sigpipe_pending)
562 : {
563 0 : if (sigpending(&sigset) == 0 &&
564 0 : sigismember(&sigset, SIGPIPE))
565 : {
566 : sigset_t sigpipe_sigset;
567 :
568 0 : sigemptyset(&sigpipe_sigset);
569 0 : sigaddset(&sigpipe_sigset, SIGPIPE);
570 :
571 0 : sigwait(&sigpipe_sigset, &signo);
572 : }
573 : }
574 :
575 : /* Restore saved block mask */
576 0 : pthread_sigmask(SIG_SETMASK, osigset, NULL);
577 :
578 0 : SOCK_ERRNO_SET(save_errno);
579 0 : }
580 :
581 : #endif /* !WIN32 */
|