LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-secure.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 28 88 31.8 %
Date: 2017-09-29 15:12:54 Functions: 5 16 31.2 %
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-2017, 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             :  * NOTES
      17             :  *
      18             :  *    We don't provide informational callbacks here (like
      19             :  *    info_cb() in be-secure.c), since there's no good mechanism to
      20             :  *    display such information to the user.
      21             :  *
      22             :  *-------------------------------------------------------------------------
      23             :  */
      24             : 
      25             : #include "postgres_fe.h"
      26             : 
      27             : #include <signal.h>
      28             : #include <fcntl.h>
      29             : #include <ctype.h>
      30             : 
      31             : #include "libpq-fe.h"
      32             : #include "fe-auth.h"
      33             : #include "libpq-int.h"
      34             : 
      35             : #ifdef WIN32
      36             : #include "win32.h"
      37             : #else
      38             : #include <sys/socket.h>
      39             : #include <unistd.h>
      40             : #include <netdb.h>
      41             : #include <netinet/in.h>
      42             : #ifdef HAVE_NETINET_TCP_H
      43             : #include <netinet/tcp.h>
      44             : #endif
      45             : #include <arpa/inet.h>
      46             : #endif
      47             : 
      48             : #include <sys/stat.h>
      49             : 
      50             : #ifdef ENABLE_THREAD_SAFETY
      51             : #ifdef WIN32
      52             : #include "pthread-win32.h"
      53             : #else
      54             : #include <pthread.h>
      55             : #endif
      56             : #endif
      57             : 
      58             : /*
      59             :  * Macros to handle disabling and then restoring the state of SIGPIPE handling.
      60             :  * On Windows, these are all no-ops since there's no SIGPIPEs.
      61             :  */
      62             : 
      63             : #ifndef WIN32
      64             : 
      65             : #define SIGPIPE_MASKED(conn)    ((conn)->sigpipe_so || (conn)->sigpipe_flag)
      66             : 
      67             : #ifdef ENABLE_THREAD_SAFETY
      68             : 
      69             : struct sigpipe_info
      70             : {
      71             :     sigset_t    oldsigmask;
      72             :     bool        sigpipe_pending;
      73             :     bool        got_epipe;
      74             : };
      75             : 
      76             : #define DECLARE_SIGPIPE_INFO(spinfo) struct sigpipe_info spinfo
      77             : 
      78             : #define DISABLE_SIGPIPE(conn, spinfo, failaction) \
      79             :     do { \
      80             :         (spinfo).got_epipe = false; \
      81             :         if (!SIGPIPE_MASKED(conn)) \
      82             :         { \
      83             :             if (pq_block_sigpipe(&(spinfo).oldsigmask, \
      84             :                                  &(spinfo).sigpipe_pending) < 0) \
      85             :                 failaction; \
      86             :         } \
      87             :     } while (0)
      88             : 
      89             : #define REMEMBER_EPIPE(spinfo, cond) \
      90             :     do { \
      91             :         if (cond) \
      92             :             (spinfo).got_epipe = true; \
      93             :     } while (0)
      94             : 
      95             : #define RESTORE_SIGPIPE(conn, spinfo) \
      96             :     do { \
      97             :         if (!SIGPIPE_MASKED(conn)) \
      98             :             pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
      99             :                              (spinfo).got_epipe); \
     100             :     } while (0)
     101             : #else                           /* !ENABLE_THREAD_SAFETY */
     102             : 
     103             : #define DECLARE_SIGPIPE_INFO(spinfo) pqsigfunc spinfo = NULL
     104             : 
     105             : #define DISABLE_SIGPIPE(conn, spinfo, failaction) \
     106             :     do { \
     107             :         if (!SIGPIPE_MASKED(conn)) \
     108             :             spinfo = pqsignal(SIGPIPE, SIG_IGN); \
     109             :     } while (0)
     110             : 
     111             : #define REMEMBER_EPIPE(spinfo, cond)
     112             : 
     113             : #define RESTORE_SIGPIPE(conn, spinfo) \
     114             :     do { \
     115             :         if (!SIGPIPE_MASKED(conn)) \
     116             :             pqsignal(SIGPIPE, spinfo); \
     117             :     } while (0)
     118             : #endif                          /* ENABLE_THREAD_SAFETY */
     119             : #else                           /* WIN32 */
     120             : 
     121             : #define DECLARE_SIGPIPE_INFO(spinfo)
     122             : #define DISABLE_SIGPIPE(conn, spinfo, failaction)
     123             : #define REMEMBER_EPIPE(spinfo, cond)
     124             : #define RESTORE_SIGPIPE(conn, spinfo)
     125             : #endif                          /* WIN32 */
     126             : 
     127             : /* ------------------------------------------------------------ */
     128             : /*           Procedures common to all secure sessions           */
     129             : /* ------------------------------------------------------------ */
     130             : 
     131             : 
     132             : /*
     133             :  *  Exported function to allow application to tell us it's already
     134             :  *  initialized OpenSSL.
     135             :  */
     136             : void
     137           0 : PQinitSSL(int do_init)
     138             : {
     139             : #ifdef USE_SSL
     140             :     pgtls_init_library(do_init, do_init);
     141             : #endif
     142           0 : }
     143             : 
     144             : /*
     145             :  *  Exported function to allow application to tell us it's already
     146             :  *  initialized OpenSSL and/or libcrypto.
     147             :  */
     148             : void
     149           0 : PQinitOpenSSL(int do_ssl, int do_crypto)
     150             : {
     151             : #ifdef USE_SSL
     152             :     pgtls_init_library(do_ssl, do_crypto);
     153             : #endif
     154           0 : }
     155             : 
     156             : /*
     157             :  *  Initialize global SSL context
     158             :  */
     159             : int
     160           0 : pqsecure_initialize(PGconn *conn)
     161             : {
     162           0 :     int         r = 0;
     163             : 
     164             : #ifdef USE_SSL
     165             :     r = pgtls_init(conn);
     166             : #endif
     167             : 
     168           0 :     return r;
     169             : }
     170             : 
     171             : /*
     172             :  *  Begin or continue negotiating a secure session.
     173             :  */
     174             : PostgresPollingStatusType
     175           0 : pqsecure_open_client(PGconn *conn)
     176             : {
     177             : #ifdef USE_SSL
     178             :     return pgtls_open_client(conn);
     179             : #else
     180             :     /* shouldn't get here */
     181           0 :     return PGRES_POLLING_FAILED;
     182             : #endif
     183             : }
     184             : 
     185             : /*
     186             :  *  Close secure session.
     187             :  */
     188             : void
     189         222 : pqsecure_close(PGconn *conn)
     190             : {
     191             : #ifdef USE_SSL
     192             :     if (conn->ssl_in_use)
     193             :         pgtls_close(conn);
     194             : #endif
     195         222 : }
     196             : 
     197             : /*
     198             :  *  Read data from a secure connection.
     199             :  *
     200             :  * On failure, this function is responsible for putting a suitable message
     201             :  * into conn->errorMessage.  The caller must still inspect errno, but only
     202             :  * to determine whether to continue/retry after error.
     203             :  */
     204             : ssize_t
     205       32025 : pqsecure_read(PGconn *conn, void *ptr, size_t len)
     206             : {
     207             :     ssize_t     n;
     208             : 
     209             : #ifdef USE_SSL
     210             :     if (conn->ssl_in_use)
     211             :     {
     212             :         n = pgtls_read(conn, ptr, len);
     213             :     }
     214             :     else
     215             : #endif
     216             :     {
     217       32025 :         n = pqsecure_raw_read(conn, ptr, len);
     218             :     }
     219             : 
     220       32025 :     return n;
     221             : }
     222             : 
     223             : ssize_t
     224       32025 : pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
     225             : {
     226             :     ssize_t     n;
     227       32025 :     int         result_errno = 0;
     228             :     char        sebuf[256];
     229             : 
     230       32025 :     n = recv(conn->sock, ptr, len, 0);
     231             : 
     232       32025 :     if (n < 0)
     233             :     {
     234           1 :         result_errno = SOCK_ERRNO;
     235             : 
     236             :         /* Set error message if appropriate */
     237           1 :         switch (result_errno)
     238             :         {
     239             : #ifdef EAGAIN
     240             :             case EAGAIN:
     241             : #endif
     242             : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
     243             :             case EWOULDBLOCK:
     244             : #endif
     245             :             case EINTR:
     246             :                 /* no error message, caller is expected to retry */
     247           1 :                 break;
     248             : 
     249             : #ifdef ECONNRESET
     250             :             case ECONNRESET:
     251           0 :                 printfPQExpBuffer(&conn->errorMessage,
     252             :                                   libpq_gettext(
     253             :                                                 "server closed the connection unexpectedly\n"
     254             :                                                 "\tThis probably means the server terminated abnormally\n"
     255             :                                                 "\tbefore or while processing the request.\n"));
     256           0 :                 break;
     257             : #endif
     258             : 
     259             :             default:
     260           0 :                 printfPQExpBuffer(&conn->errorMessage,
     261             :                                   libpq_gettext("could not receive data from server: %s\n"),
     262             :                                   SOCK_STRERROR(result_errno,
     263             :                                                 sebuf, sizeof(sebuf)));
     264           0 :                 break;
     265             :         }
     266             :     }
     267             : 
     268             :     /* ensure we return the intended errno to caller */
     269       32025 :     SOCK_ERRNO_SET(result_errno);
     270             : 
     271       32025 :     return n;
     272             : }
     273             : 
     274             : /*
     275             :  *  Write data to a secure connection.
     276             :  *
     277             :  * On failure, this function is responsible for putting a suitable message
     278             :  * into conn->errorMessage.  The caller must still inspect errno, but only
     279             :  * to determine whether to continue/retry after error.
     280             :  */
     281             : ssize_t
     282       27475 : pqsecure_write(PGconn *conn, const void *ptr, size_t len)
     283             : {
     284             :     ssize_t     n;
     285             : 
     286             : #ifdef USE_SSL
     287             :     if (conn->ssl_in_use)
     288             :     {
     289             :         n = pgtls_write(conn, ptr, len);
     290             :     }
     291             :     else
     292             : #endif
     293             :     {
     294       27475 :         n = pqsecure_raw_write(conn, ptr, len);
     295             :     }
     296             : 
     297       27475 :     return n;
     298             : }
     299             : 
     300             : ssize_t
     301       27475 : pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
     302             : {
     303             :     ssize_t     n;
     304       27475 :     int         flags = 0;
     305       27475 :     int         result_errno = 0;
     306             :     char        sebuf[256];
     307             : 
     308             :     DECLARE_SIGPIPE_INFO(spinfo);
     309             : 
     310             : #ifdef MSG_NOSIGNAL
     311       27475 :     if (conn->sigpipe_flag)
     312       27475 :         flags |= MSG_NOSIGNAL;
     313             : 
     314             : retry_masked:
     315             : #endif                          /* MSG_NOSIGNAL */
     316             : 
     317       27475 :     DISABLE_SIGPIPE(conn, spinfo, return -1);
     318             : 
     319       27475 :     n = send(conn->sock, ptr, len, flags);
     320             : 
     321       27475 :     if (n < 0)
     322             :     {
     323           0 :         result_errno = SOCK_ERRNO;
     324             : 
     325             :         /*
     326             :          * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
     327             :          * on this machine.  So, clear sigpipe_flag so we don't try the flag
     328             :          * again, and retry the send().
     329             :          */
     330             : #ifdef MSG_NOSIGNAL
     331           0 :         if (flags != 0 && result_errno == EINVAL)
     332             :         {
     333           0 :             conn->sigpipe_flag = false;
     334           0 :             flags = 0;
     335           0 :             goto retry_masked;
     336             :         }
     337             : #endif                          /* MSG_NOSIGNAL */
     338             : 
     339             :         /* Set error message if appropriate */
     340           0 :         switch (result_errno)
     341             :         {
     342             : #ifdef EAGAIN
     343             :             case EAGAIN:
     344             : #endif
     345             : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
     346             :             case EWOULDBLOCK:
     347             : #endif
     348             :             case EINTR:
     349             :                 /* no error message, caller is expected to retry */
     350           0 :                 break;
     351             : 
     352             :             case EPIPE:
     353             :                 /* Set flag for EPIPE */
     354           0 :                 REMEMBER_EPIPE(spinfo, true);
     355             :                 /* FALL THRU */
     356             : 
     357             : #ifdef ECONNRESET
     358             :             case ECONNRESET:
     359             : #endif
     360           0 :                 printfPQExpBuffer(&conn->errorMessage,
     361             :                                   libpq_gettext(
     362             :                                                 "server closed the connection unexpectedly\n"
     363             :                                                 "\tThis probably means the server terminated abnormally\n"
     364             :                                                 "\tbefore or while processing the request.\n"));
     365           0 :                 break;
     366             : 
     367             :             default:
     368           0 :                 printfPQExpBuffer(&conn->errorMessage,
     369             :                                   libpq_gettext("could not send data to server: %s\n"),
     370             :                                   SOCK_STRERROR(result_errno,
     371             :                                                 sebuf, sizeof(sebuf)));
     372           0 :                 break;
     373             :         }
     374             :     }
     375             : 
     376       27475 :     RESTORE_SIGPIPE(conn, spinfo);
     377             : 
     378             :     /* ensure we return the intended errno to caller */
     379       27475 :     SOCK_ERRNO_SET(result_errno);
     380             : 
     381       27475 :     return n;
     382             : }
     383             : 
     384             : /* Dummy versions of SSL info functions, when built without SSL support */
     385             : #ifndef USE_SSL
     386             : 
     387             : int
     388           0 : PQsslInUse(PGconn *conn)
     389             : {
     390           0 :     return 0;
     391             : }
     392             : 
     393             : void *
     394           0 : PQgetssl(PGconn *conn)
     395             : {
     396           0 :     return NULL;
     397             : }
     398             : 
     399             : void *
     400           0 : PQsslStruct(PGconn *conn, const char *struct_name)
     401             : {
     402           0 :     return NULL;
     403             : }
     404             : 
     405             : const char *
     406           0 : PQsslAttribute(PGconn *conn, const char *attribute_name)
     407             : {
     408           0 :     return NULL;
     409             : }
     410             : 
     411             : const char *const *
     412           0 : PQsslAttributeNames(PGconn *conn)
     413             : {
     414             :     static const char *const result[] = {NULL};
     415             : 
     416           0 :     return result;
     417             : }
     418             : #endif                          /* USE_SSL */
     419             : 
     420             : 
     421             : #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
     422             : 
     423             : /*
     424             :  *  Block SIGPIPE for this thread.  This prevents send()/write() from exiting
     425             :  *  the application.
     426             :  */
     427             : int
     428           0 : pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
     429             : {
     430             :     sigset_t    sigpipe_sigset;
     431             :     sigset_t    sigset;
     432             : 
     433           0 :     sigemptyset(&sigpipe_sigset);
     434           0 :     sigaddset(&sigpipe_sigset, SIGPIPE);
     435             : 
     436             :     /* Block SIGPIPE and save previous mask for later reset */
     437           0 :     SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
     438           0 :     if (SOCK_ERRNO)
     439           0 :         return -1;
     440             : 
     441             :     /* We can have a pending SIGPIPE only if it was blocked before */
     442           0 :     if (sigismember(osigset, SIGPIPE))
     443             :     {
     444             :         /* Is there a pending SIGPIPE? */
     445           0 :         if (sigpending(&sigset) != 0)
     446           0 :             return -1;
     447             : 
     448           0 :         if (sigismember(&sigset, SIGPIPE))
     449           0 :             *sigpipe_pending = true;
     450             :         else
     451           0 :             *sigpipe_pending = false;
     452             :     }
     453             :     else
     454           0 :         *sigpipe_pending = false;
     455             : 
     456           0 :     return 0;
     457             : }
     458             : 
     459             : /*
     460             :  *  Discard any pending SIGPIPE and reset the signal mask.
     461             :  *
     462             :  * Note: we are effectively assuming here that the C library doesn't queue
     463             :  * up multiple SIGPIPE events.  If it did, then we'd accidentally leave
     464             :  * ours in the queue when an event was already pending and we got another.
     465             :  * As long as it doesn't queue multiple events, we're OK because the caller
     466             :  * can't tell the difference.
     467             :  *
     468             :  * The caller should say got_epipe = FALSE if it is certain that it
     469             :  * didn't get an EPIPE error; in that case we'll skip the clear operation
     470             :  * and things are definitely OK, queuing or no.  If it got one or might have
     471             :  * gotten one, pass got_epipe = TRUE.
     472             :  *
     473             :  * We do not want this to change errno, since if it did that could lose
     474             :  * the error code from a preceding send().  We essentially assume that if
     475             :  * we were able to do pq_block_sigpipe(), this can't fail.
     476             :  */
     477             : void
     478           0 : pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
     479             : {
     480           0 :     int         save_errno = SOCK_ERRNO;
     481             :     int         signo;
     482             :     sigset_t    sigset;
     483             : 
     484             :     /* Clear SIGPIPE only if none was pending */
     485           0 :     if (got_epipe && !sigpipe_pending)
     486             :     {
     487           0 :         if (sigpending(&sigset) == 0 &&
     488           0 :             sigismember(&sigset, SIGPIPE))
     489             :         {
     490             :             sigset_t    sigpipe_sigset;
     491             : 
     492           0 :             sigemptyset(&sigpipe_sigset);
     493           0 :             sigaddset(&sigpipe_sigset, SIGPIPE);
     494             : 
     495           0 :             sigwait(&sigpipe_sigset, &signo);
     496             :         }
     497             :     }
     498             : 
     499             :     /* Restore saved block mask */
     500           0 :     pthread_sigmask(SIG_SETMASK, osigset, NULL);
     501             : 
     502           0 :     SOCK_ERRNO_SET(save_errno);
     503           0 : }
     504             : 
     505             : #endif                          /* ENABLE_THREAD_SAFETY && !WIN32 */

Generated by: LCOV version 1.11