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 17:13:01 Functions: 100.0 % 9 9 9 9
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 97.1 % 68 66 2 46 20 2 46
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 50.0 % 18 9 9 9

 Age         Owner                  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.
 7604 bruce                      74 ECB             :  */
                                 75                 : int
 2286 tgl                        76 GIC          26 : secure_initialize(bool isServerStart)
 7604 bruce                      77 ECB             : {
                                 78                 : #ifdef USE_SSL
 2286 tgl                        79 GIC          26 :     return be_tls_init(isServerStart);
                                 80                 : #else
                                 81                 :     return 0;
                                 82                 : #endif
                                 83                 : }
                                 84                 : 
                                 85                 : /*
                                 86                 :  *  Destroy global context, if any.
 2288 tgl                        87 ECB             :  */
                                 88                 : void
 2288 tgl                        89 GIC         103 : secure_destroy(void)
 2288 tgl                        90 ECB             : {
                                 91                 : #ifdef USE_SSL
 2288 tgl                        92 CBC         103 :     be_tls_destroy();
                                 93                 : #endif
 7604 bruce                      94 GIC         103 : }
                                 95                 : 
                                 96                 : /*
                                 97                 :  * Indicate if we have loaded the root CA store to verify certificates
 5253 magnus                     98 ECB             :  */
                                 99                 : bool
 5253 magnus                    100 GIC          30 : secure_loaded_verify_locations(void)
 5253 magnus                    101 ECB             : {
                                102                 : #ifdef USE_SSL
 5253 magnus                    103 GIC          30 :     return ssl_loaded_verify_locations;
                                104                 : #else
                                105                 :     return false;
                                106                 : #endif
                                107                 : }
                                108                 : 
                                109                 : /*
                                110                 :  *  Attempt to negotiate secure session.
 7604 bruce                     111 ECB             :  */
                                112                 : int
 7522 bruce                     113 CBC         112 : secure_open_server(Port *port)
                                114                 : {
 7522 bruce                     115 GIC         112 :     int         r = 0;
 7604 bruce                     116 ECB             : 
                                117                 : #ifdef USE_SSL
 3163 heikki.linnakangas        118 CBC         112 :     r = be_tls_open_server(port);
                                119                 : 
 1906 peter_e                   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)")));
 7604 bruce                     124 ECB             : #endif
                                125                 : 
 7604 bruce                     126 GIC         112 :     return r;
                                127                 : }
                                128                 : 
                                129                 : /*
                                130                 :  *  Close secure session.
 7604 bruce                     131 ECB             :  */
                                132                 : void
 7522 bruce                     133 GIC        8661 : secure_close(Port *port)
 7604 bruce                     134 ECB             : {
                                135                 : #ifdef USE_SSL
 3163 heikki.linnakangas        136 GIC        8661 :     if (port->ssl_in_use)
 3163 heikki.linnakangas        137 CBC         112 :         be_tls_close(port);
                                138                 : #endif
 7604 bruce                     139 GIC        8661 : }
                                140                 : 
                                141                 : /*
                                142                 :  *  Read data from a secure connection.
 7604 bruce                     143 ECB             :  */
                                144                 : ssize_t
 7522 bruce                     145 GIC     1287235 : secure_read(Port *port, void *ptr, size_t len)
                                146                 : {
                                147                 :     ssize_t     n;
                                148                 :     int         waitfor;
 7604 bruce                     149 ECB             : 
                                150                 :     /* Deal with any already-pending interrupt condition. */
 1633 tgl                       151 CBC     1287235 :     ProcessClientReadInterrupt(false);
                                152                 : 
 2987 andres                    153         1381478 : retry:
 7604 bruce                     154 ECB             : #ifdef USE_SSL
 2977 heikki.linnakangas        155 GIC     1381478 :     waitfor = 0;
 3163 heikki.linnakangas        156 CBC     1381478 :     if (port->ssl_in_use)
                                157                 :     {
 2977 heikki.linnakangas        158 GIC         305 :         n = be_tls_read(port, ptr, len, &waitfor);
                                159                 :     }
                                160                 :     else
 1467 sfrost                    161 ECB             : #endif
                                162                 : #ifdef ENABLE_GSS
  832 tgl                       163 CBC     1381173 :     if (port->gss && port->gss->enc)
 1467 sfrost                    164 ECB             :     {
 1467 sfrost                    165 GIC         148 :         n = be_gssapi_read(port, ptr, len);
                                166             148 :         waitfor = WL_SOCKET_READABLE;
                                167                 :     }
                                168                 :     else
 7604 bruce                     169 ECB             : #endif
 6520 tgl                       170                 :     {
 3163 heikki.linnakangas        171 GIC     1381025 :         n = secure_raw_read(port, ptr, len);
 2977                           172         1381025 :         waitfor = WL_SOCKET_READABLE;
                                173                 :     }
 6520 tgl                       174 ECB             : 
                                175                 :     /* In blocking mode, wait until the socket is ready */
 2977 heikki.linnakangas        176 GIC     1381478 :     if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
                                177                 :     {
 2495 rhaas                     178 ECB             :         WaitEvent   event;
                                179                 : 
 2977 heikki.linnakangas        180 CBC       94279 :         Assert(waitfor);
                                181                 : 
  769 tmunro                    182           94279 :         ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, waitfor, NULL);
                                183                 : 
 2378 rhaas                     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
 2705 rhaas                     202 ECB             :          * us to exit quickly in most cases.)
 2705 rhaas                     203 EUB             :          */
 2575 andres                    204 GIC       94279 :         if (event.events & WL_POSTMASTER_DEATH)
 2705 rhaas                     205 UIC           0 :             ereport(FATAL,
                                206                 :                     (errcode(ERRCODE_ADMIN_SHUTDOWN),
                                207                 :                      errmsg("terminating connection due to unexpected postmaster exit")));
 2705 rhaas                     208 ECB             : 
                                209                 :         /* Handle interrupt. */
 2575 andres                    210 CBC       94279 :         if (event.events & WL_LATCH_SET)
 2977 heikki.linnakangas        211 ECB             :         {
 2977 heikki.linnakangas        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.
 2977 heikki.linnakangas        219 ECB             :              */
                                220                 :         }
 2987 andres                    221 GIC       94272 :         goto retry;
                                222                 :     }
                                223                 : 
                                224                 :     /*
                                225                 :      * Process interrupts that happened during a successful (or non-blocking,
 1633 tgl                       226 ECB             :      * or hard-failed) read.
                                227                 :      */
 2987 andres                    228 CBC     1287199 :     ProcessClientReadInterrupt(false);
                                229                 : 
 7604 bruce                     230 GIC     1287199 :     return n;
                                231                 : }
 7604 bruce                     232 ECB             : 
                                233                 : ssize_t
 3163 heikki.linnakangas        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
 2987 andres                    243 ECB             :     pgwin32_noblock = true;
                                244                 : #endif
 3163 heikki.linnakangas        245 GIC     1383210 :     n = recv(port->sock, ptr, len, 0);
                                246                 : #ifdef WIN32
                                247                 :     pgwin32_noblock = false;
 2987 andres                    248 ECB             : #endif
                                249                 : 
 3163 heikki.linnakangas        250 GIC     1383210 :     return n;
                                251                 : }
                                252                 : 
                                253                 : 
                                254                 : /*
                                255                 :  *  Write data to a secure connection.
 7604 bruce                     256 ECB             :  */
                                257                 : ssize_t
 3163 heikki.linnakangas        258 GIC      909156 : secure_write(Port *port, void *ptr, size_t len)
                                259                 : {
                                260                 :     ssize_t     n;
                                261                 :     int         waitfor;
 7052 tgl                       262 ECB             : 
                                263                 :     /* Deal with any already-pending interrupt condition. */
 1633 tgl                       264 CBC      909156 :     ProcessClientWriteInterrupt(false);
 1633 tgl                       265 ECB             : 
 2987 andres                    266 GIC      921493 : retry:
 2977 heikki.linnakangas        267 CBC      921493 :     waitfor = 0;
                                268                 : #ifdef USE_SSL
 3163                           269          921493 :     if (port->ssl_in_use)
                                270                 :     {
 2977 heikki.linnakangas        271 GIC         168 :         n = be_tls_write(port, ptr, len, &waitfor);
                                272                 :     }
                                273                 :     else
 1467 sfrost                    274 ECB             : #endif
                                275                 : #ifdef ENABLE_GSS
  832 tgl                       276 CBC      921325 :     if (port->gss && port->gss->enc)
 1467 sfrost                    277 ECB             :     {
 1467 sfrost                    278 GIC         230 :         n = be_gssapi_write(port, ptr, len);
                                279             230 :         waitfor = WL_SOCKET_WRITEABLE;
                                280                 :     }
                                281                 :     else
 6714 tgl                       282 ECB             : #endif
 2987 andres                    283                 :     {
 3163 heikki.linnakangas        284 GIC      921095 :         n = secure_raw_write(port, ptr, len);
 2977                           285          921095 :         waitfor = WL_SOCKET_WRITEABLE;
 2987 andres                    286 ECB             :     }
                                287                 : 
 2977 heikki.linnakangas        288 GIC      921493 :     if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
                                289                 :     {
 2495 rhaas                     290 ECB             :         WaitEvent   event;
                                291                 : 
 2977 heikki.linnakangas        292 CBC       12337 :         Assert(waitfor);
                                293                 : 
  769 tmunro                    294           12337 :         ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, waitfor, NULL);
                                295                 : 
 2378 rhaas                     296 GIC       12337 :         WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
                                297                 :                          WAIT_EVENT_CLIENT_WRITE);
 2977 heikki.linnakangas        298 ECB             : 
 2705 rhaas                     299 EUB             :         /* See comments in secure_read. */
 2575 andres                    300 GIC       12337 :         if (event.events & WL_POSTMASTER_DEATH)
 2705 rhaas                     301 UIC           0 :             ereport(FATAL,
                                302                 :                     (errcode(ERRCODE_ADMIN_SHUTDOWN),
                                303                 :                      errmsg("terminating connection due to unexpected postmaster exit")));
 2705 rhaas                     304 ECB             : 
                                305                 :         /* Handle interrupt. */
 2575 andres                    306 CBC       12337 :         if (event.events & WL_LATCH_SET)
 2977 heikki.linnakangas        307 ECB             :         {
 2977 heikki.linnakangas        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.
 2977 heikki.linnakangas        315 ECB             :              */
                                316                 :         }
 2987 andres                    317 GIC       12337 :         goto retry;
                                318                 :     }
                                319                 : 
                                320                 :     /*
                                321                 :      * Process interrupts that happened during a successful (or non-blocking,
 1633 tgl                       322 ECB             :      * or hard-failed) write.
                                323                 :      */
 2977 heikki.linnakangas        324 CBC      909156 :     ProcessClientWriteInterrupt(false);
                                325                 : 
 3163 heikki.linnakangas        326 GIC      909156 :     return n;
                                327                 : }
 7604 bruce                     328 ECB             : 
                                329                 : ssize_t
 3163 heikki.linnakangas        330 GIC      922009 : secure_raw_write(Port *port, const void *ptr, size_t len)
                                331                 : {
                                332                 :     ssize_t     n;
                                333                 : 
                                334                 : #ifdef WIN32
 2987 andres                    335 ECB             :     pgwin32_noblock = true;
                                336                 : #endif
 2987 andres                    337 GIC      922009 :     n = send(port->sock, ptr, len, 0);
                                338                 : #ifdef WIN32
                                339                 :     pgwin32_noblock = false;
 2987 andres                    340 ECB             : #endif
                                341                 : 
 2987 andres                    342 GIC      922009 :     return n;
                                343                 : }
        

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