LCOV - differential code coverage report
Current view: top level - src/backend/libpq - be-secure.c (source / functions) Coverage Total Hit UIC GIC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 97.1 % 68 66 2 46 20 2 46
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 9 9 9 9
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

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