LCOV - differential code coverage report
Current view: top level - src/interfaces/libpq - fe-secure.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 58.4 % 113 66 3 1 13 30 3 40 2 21 12 43 2 1
Current Date: 2023-04-08 17:13:01 Functions: 66.7 % 12 8 2 2 8 2 8
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (120,180] days: 40.0 % 5 2 3 2
Legend: Lines: hit not hit (240..) days: 59.3 % 108 64 1 13 30 3 40 21 12 43
Function coverage date bins:
(240..) days: 36.4 % 22 8 2 2 8 2 8

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

Generated by: LCOV version v1.16-55-g56c0a2a