LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-secure.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 63 113 55.8 %
Date: 2024-11-21 08:14:44 Functions: 8 13 61.5 %
Legend: Lines: hit not hit

          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 */

Generated by: LCOV version 1.14