LCOV - code coverage report
Current view: top level - src/backend/libpq - be-secure.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 29 48 60.4 %
Date: 2017-09-29 13:40:31 Functions: 5 9 55.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * be-secure.c
       4             :  *    functions related to setting up a secure connection to the frontend.
       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/backend/libpq/be-secure.c
      15             :  *
      16             :  *-------------------------------------------------------------------------
      17             :  */
      18             : 
      19             : #include "postgres.h"
      20             : 
      21             : #include <sys/stat.h>
      22             : #include <signal.h>
      23             : #include <fcntl.h>
      24             : #include <ctype.h>
      25             : #include <sys/socket.h>
      26             : #include <unistd.h>
      27             : #include <netdb.h>
      28             : #include <netinet/in.h>
      29             : #ifdef HAVE_NETINET_TCP_H
      30             : #include <netinet/tcp.h>
      31             : #include <arpa/inet.h>
      32             : #endif
      33             : 
      34             : #include "libpq/libpq.h"
      35             : #include "miscadmin.h"
      36             : #include "pgstat.h"
      37             : #include "tcop/tcopprot.h"
      38             : #include "utils/memutils.h"
      39             : #include "storage/ipc.h"
      40             : #include "storage/proc.h"
      41             : 
      42             : 
      43             : char       *ssl_cert_file;
      44             : char       *ssl_key_file;
      45             : char       *ssl_ca_file;
      46             : char       *ssl_crl_file;
      47             : char       *ssl_dh_params_file;
      48             : 
      49             : #ifdef USE_SSL
      50             : bool        ssl_loaded_verify_locations = false;
      51             : #endif
      52             : 
      53             : /* GUC variable controlling SSL cipher list */
      54             : char       *SSLCipherSuites = NULL;
      55             : 
      56             : /* GUC variable for default ECHD curve. */
      57             : char       *SSLECDHCurve;
      58             : 
      59             : /* GUC variable: if false, prefer client ciphers */
      60             : bool        SSLPreferServerCiphers;
      61             : 
      62             : /* ------------------------------------------------------------ */
      63             : /*           Procedures common to all secure sessions           */
      64             : /* ------------------------------------------------------------ */
      65             : 
      66             : /*
      67             :  *  Initialize global context.
      68             :  *
      69             :  * If isServerStart is true, report any errors as FATAL (so we don't return).
      70             :  * Otherwise, log errors at LOG level and return -1 to indicate trouble,
      71             :  * preserving the old SSL state if any.  Returns 0 if OK.
      72             :  */
      73             : int
      74           0 : secure_initialize(bool isServerStart)
      75             : {
      76             : #ifdef USE_SSL
      77             :     return be_tls_init(isServerStart);
      78             : #else
      79           0 :     return 0;
      80             : #endif
      81             : }
      82             : 
      83             : /*
      84             :  *  Destroy global context, if any.
      85             :  */
      86             : void
      87           0 : secure_destroy(void)
      88             : {
      89             : #ifdef USE_SSL
      90             :     be_tls_destroy();
      91             : #endif
      92           0 : }
      93             : 
      94             : /*
      95             :  * Indicate if we have loaded the root CA store to verify certificates
      96             :  */
      97             : bool
      98           0 : secure_loaded_verify_locations(void)
      99             : {
     100             : #ifdef USE_SSL
     101             :     return ssl_loaded_verify_locations;
     102             : #else
     103           0 :     return false;
     104             : #endif
     105             : }
     106             : 
     107             : /*
     108             :  *  Attempt to negotiate secure session.
     109             :  */
     110             : int
     111           0 : secure_open_server(Port *port)
     112             : {
     113           0 :     int         r = 0;
     114             : 
     115             : #ifdef USE_SSL
     116             :     r = be_tls_open_server(port);
     117             : #endif
     118             : 
     119           0 :     return r;
     120             : }
     121             : 
     122             : /*
     123             :  *  Close secure session.
     124             :  */
     125             : void
     126         215 : secure_close(Port *port)
     127             : {
     128             : #ifdef USE_SSL
     129             :     if (port->ssl_in_use)
     130             :         be_tls_close(port);
     131             : #endif
     132         215 : }
     133             : 
     134             : /*
     135             :  *  Read data from a secure connection.
     136             :  */
     137             : ssize_t
     138       42680 : secure_read(Port *port, void *ptr, size_t len)
     139             : {
     140             :     ssize_t     n;
     141             :     int         waitfor;
     142             : 
     143             : retry:
     144             : #ifdef USE_SSL
     145             :     waitfor = 0;
     146             :     if (port->ssl_in_use)
     147             :     {
     148             :         n = be_tls_read(port, ptr, len, &waitfor);
     149             :     }
     150             :     else
     151             : #endif
     152             :     {
     153       42680 :         n = secure_raw_read(port, ptr, len);
     154       42680 :         waitfor = WL_SOCKET_READABLE;
     155             :     }
     156             : 
     157             :     /* In blocking mode, wait until the socket is ready */
     158       42680 :     if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
     159             :     {
     160             :         WaitEvent   event;
     161             : 
     162       15279 :         Assert(waitfor);
     163             : 
     164       15279 :         ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
     165             : 
     166       15279 :         WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
     167             :                          WAIT_EVENT_CLIENT_READ);
     168             : 
     169             :         /*
     170             :          * If the postmaster has died, it's not safe to continue running,
     171             :          * because it is the postmaster's job to kill us if some other backend
     172             :          * exists uncleanly.  Moreover, we won't run very well in this state;
     173             :          * helper processes like walwriter and the bgwriter will exit, so
     174             :          * performance may be poor.  Finally, if we don't exit, pg_ctl will be
     175             :          * unable to restart the postmaster without manual intervention, so no
     176             :          * new connections can be accepted.  Exiting clears the deck for a
     177             :          * postmaster restart.
     178             :          *
     179             :          * (Note that we only make this check when we would otherwise sleep on
     180             :          * our latch.  We might still continue running for a while if the
     181             :          * postmaster is killed in mid-query, or even through multiple queries
     182             :          * if we never have to wait for read.  We don't want to burn too many
     183             :          * cycles checking for this very rare condition, and this should cause
     184             :          * us to exit quickly in most cases.)
     185             :          */
     186       15279 :         if (event.events & WL_POSTMASTER_DEATH)
     187           0 :             ereport(FATAL,
     188             :                     (errcode(ERRCODE_ADMIN_SHUTDOWN),
     189             :                      errmsg("terminating connection due to unexpected postmaster exit")));
     190             : 
     191             :         /* Handle interrupt. */
     192       15279 :         if (event.events & WL_LATCH_SET)
     193             :         {
     194         278 :             ResetLatch(MyLatch);
     195         278 :             ProcessClientReadInterrupt(true);
     196             : 
     197             :             /*
     198             :              * We'll retry the read. Most likely it will return immediately
     199             :              * because there's still no data available, and we'll wait for the
     200             :              * socket to become ready again.
     201             :              */
     202             :         }
     203       15279 :         goto retry;
     204             :     }
     205             : 
     206             :     /*
     207             :      * Process interrupts that happened while (or before) receiving. Note that
     208             :      * we signal that we're not blocking, which will prevent some types of
     209             :      * interrupts from being processed.
     210             :      */
     211       27401 :     ProcessClientReadInterrupt(false);
     212             : 
     213       27401 :     return n;
     214             : }
     215             : 
     216             : ssize_t
     217       42680 : secure_raw_read(Port *port, void *ptr, size_t len)
     218             : {
     219             :     ssize_t     n;
     220             : 
     221             :     /*
     222             :      * Try to read from the socket without blocking. If it succeeds we're
     223             :      * done, otherwise we'll wait for the socket using the latch mechanism.
     224             :      */
     225             : #ifdef WIN32
     226             :     pgwin32_noblock = true;
     227             : #endif
     228       42680 :     n = recv(port->sock, ptr, len, 0);
     229             : #ifdef WIN32
     230             :     pgwin32_noblock = false;
     231             : #endif
     232             : 
     233       42680 :     return n;
     234             : }
     235             : 
     236             : 
     237             : /*
     238             :  *  Write data to a secure connection.
     239             :  */
     240             : ssize_t
     241       32117 : secure_write(Port *port, void *ptr, size_t len)
     242             : {
     243             :     ssize_t     n;
     244             :     int         waitfor;
     245             : 
     246             : retry:
     247       32117 :     waitfor = 0;
     248             : #ifdef USE_SSL
     249             :     if (port->ssl_in_use)
     250             :     {
     251             :         n = be_tls_write(port, ptr, len, &waitfor);
     252             :     }
     253             :     else
     254             : #endif
     255             :     {
     256       32117 :         n = secure_raw_write(port, ptr, len);
     257       32117 :         waitfor = WL_SOCKET_WRITEABLE;
     258             :     }
     259             : 
     260       32117 :     if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
     261             :     {
     262             :         WaitEvent   event;
     263             : 
     264           0 :         Assert(waitfor);
     265             : 
     266           0 :         ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
     267             : 
     268           0 :         WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
     269             :                          WAIT_EVENT_CLIENT_WRITE);
     270             : 
     271             :         /* See comments in secure_read. */
     272           0 :         if (event.events & WL_POSTMASTER_DEATH)
     273           0 :             ereport(FATAL,
     274             :                     (errcode(ERRCODE_ADMIN_SHUTDOWN),
     275             :                      errmsg("terminating connection due to unexpected postmaster exit")));
     276             : 
     277             :         /* Handle interrupt. */
     278           0 :         if (event.events & WL_LATCH_SET)
     279             :         {
     280           0 :             ResetLatch(MyLatch);
     281           0 :             ProcessClientWriteInterrupt(true);
     282             : 
     283             :             /*
     284             :              * We'll retry the write. Most likely it will return immediately
     285             :              * because there's still no data available, and we'll wait for the
     286             :              * socket to become ready again.
     287             :              */
     288             :         }
     289           0 :         goto retry;
     290             :     }
     291             : 
     292             :     /*
     293             :      * Process interrupts that happened while (or before) sending. Note that
     294             :      * we signal that we're not blocking, which will prevent some types of
     295             :      * interrupts from being processed.
     296             :      */
     297       32117 :     ProcessClientWriteInterrupt(false);
     298             : 
     299       32117 :     return n;
     300             : }
     301             : 
     302             : ssize_t
     303       32117 : secure_raw_write(Port *port, const void *ptr, size_t len)
     304             : {
     305             :     ssize_t     n;
     306             : 
     307             : #ifdef WIN32
     308             :     pgwin32_noblock = true;
     309             : #endif
     310       32117 :     n = send(port->sock, ptr, len, 0);
     311             : #ifdef WIN32
     312             :     pgwin32_noblock = false;
     313             : #endif
     314             : 
     315       32117 :     return n;
     316             : }

Generated by: LCOV version 1.11