LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-connect.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 1645 2542 64.7 %
Date: 2024-11-21 08:14:44 Functions: 93 106 87.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * fe-connect.c
       4             :  *    functions related to setting up a connection to the backend
       5             :  *
       6             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/interfaces/libpq/fe-connect.c
      12             :  *
      13             :  *-------------------------------------------------------------------------
      14             :  */
      15             : 
      16             : #include "postgres_fe.h"
      17             : 
      18             : #include <sys/stat.h>
      19             : #include <fcntl.h>
      20             : #include <ctype.h>
      21             : #include <netdb.h>
      22             : #include <time.h>
      23             : #include <unistd.h>
      24             : 
      25             : #include "common/ip.h"
      26             : #include "common/link-canary.h"
      27             : #include "common/scram-common.h"
      28             : #include "common/string.h"
      29             : #include "fe-auth.h"
      30             : #include "libpq-fe.h"
      31             : #include "libpq-int.h"
      32             : #include "mb/pg_wchar.h"
      33             : #include "pg_config_paths.h"
      34             : #include "port/pg_bswap.h"
      35             : 
      36             : #ifdef WIN32
      37             : #include "win32.h"
      38             : #ifdef _WIN32_IE
      39             : #undef _WIN32_IE
      40             : #endif
      41             : #define _WIN32_IE 0x0500
      42             : #ifdef near
      43             : #undef near
      44             : #endif
      45             : #define near
      46             : #include <shlobj.h>
      47             : #include <mstcpip.h>
      48             : #else
      49             : #include <sys/socket.h>
      50             : #include <netdb.h>
      51             : #include <netinet/in.h>
      52             : #include <netinet/tcp.h>
      53             : #include <pwd.h>
      54             : #endif
      55             : 
      56             : #ifdef WIN32
      57             : #include "pthread-win32.h"
      58             : #else
      59             : #include <pthread.h>
      60             : #endif
      61             : 
      62             : #ifdef USE_LDAP
      63             : #ifdef WIN32
      64             : #include <winldap.h>
      65             : #else
      66             : /* OpenLDAP deprecates RFC 1823, but we want standard conformance */
      67             : #define LDAP_DEPRECATED 1
      68             : #include <ldap.h>
      69             : typedef struct timeval LDAP_TIMEVAL;
      70             : #endif
      71             : static int  ldapServiceLookup(const char *purl, PQconninfoOption *options,
      72             :                               PQExpBuffer errorMessage);
      73             : #endif
      74             : 
      75             : #ifndef WIN32
      76             : #define PGPASSFILE ".pgpass"
      77             : #else
      78             : #define PGPASSFILE "pgpass.conf"
      79             : #endif
      80             : 
      81             : /*
      82             :  * Pre-9.0 servers will return this SQLSTATE if asked to set
      83             :  * application_name in a startup packet.  We hard-wire the value rather
      84             :  * than looking into errcodes.h since it reflects historical behavior
      85             :  * rather than that of the current code.
      86             :  */
      87             : #define ERRCODE_APPNAME_UNKNOWN "42704"
      88             : 
      89             : /* This is part of the protocol so just define it */
      90             : #define ERRCODE_INVALID_PASSWORD "28P01"
      91             : /* This too */
      92             : #define ERRCODE_CANNOT_CONNECT_NOW "57P03"
      93             : 
      94             : /*
      95             :  * Cope with the various platform-specific ways to spell TCP keepalive socket
      96             :  * options.  This doesn't cover Windows, which as usual does its own thing.
      97             :  */
      98             : #if defined(TCP_KEEPIDLE)
      99             : /* TCP_KEEPIDLE is the name of this option on Linux and *BSD */
     100             : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE
     101             : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE"
     102             : #elif defined(TCP_KEEPALIVE_THRESHOLD)
     103             : /* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris >= 11 */
     104             : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD
     105             : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD"
     106             : #elif defined(TCP_KEEPALIVE) && defined(__darwin__)
     107             : /* TCP_KEEPALIVE is the name of this option on macOS */
     108             : /* Caution: Solaris has this symbol but it means something different */
     109             : #define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE
     110             : #define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE"
     111             : #endif
     112             : 
     113             : /*
     114             :  * fall back options if they are not specified by arguments or defined
     115             :  * by environment variables
     116             :  */
     117             : #define DefaultHost     "localhost"
     118             : #define DefaultOption   ""
     119             : #ifdef USE_SSL
     120             : #define DefaultChannelBinding   "prefer"
     121             : #else
     122             : #define DefaultChannelBinding   "disable"
     123             : #endif
     124             : #define DefaultTargetSessionAttrs   "any"
     125             : #define DefaultLoadBalanceHosts "disable"
     126             : #ifdef USE_SSL
     127             : #define DefaultSSLMode "prefer"
     128             : #define DefaultSSLCertMode "allow"
     129             : #else
     130             : #define DefaultSSLMode  "disable"
     131             : #define DefaultSSLCertMode "disable"
     132             : #endif
     133             : #define DefaultSSLNegotiation   "postgres"
     134             : #ifdef ENABLE_GSS
     135             : #include "fe-gssapi-common.h"
     136             : #define DefaultGSSMode "prefer"
     137             : #else
     138             : #define DefaultGSSMode "disable"
     139             : #endif
     140             : 
     141             : /* ----------
     142             :  * Definition of the conninfo parameters and their fallback resources.
     143             :  *
     144             :  * If Environment-Var and Compiled-in are specified as NULL, no
     145             :  * fallback is available. If after all no value can be determined
     146             :  * for an option, an error is returned.
     147             :  *
     148             :  * The value for the username is treated specially in conninfo_add_defaults.
     149             :  * If the value is not obtained any other way, the username is determined
     150             :  * by pg_fe_getauthname().
     151             :  *
     152             :  * The Label and Disp-Char entries are provided for applications that
     153             :  * want to use PQconndefaults() to create a generic database connection
     154             :  * dialog. Disp-Char is defined as follows:
     155             :  *      ""        Normal input field
     156             :  *      "*"       Password field - hide value
     157             :  *      "D"       Debug option - don't show by default
     158             :  *
     159             :  * PQconninfoOptions[] is a constant static array that we use to initialize
     160             :  * a dynamically allocated working copy.  All the "val" fields in
     161             :  * PQconninfoOptions[] *must* be NULL.  In a working copy, non-null "val"
     162             :  * fields point to malloc'd strings that should be freed when the working
     163             :  * array is freed (see PQconninfoFree).
     164             :  *
     165             :  * The first part of each struct is identical to the one in libpq-fe.h,
     166             :  * which is required since we memcpy() data between the two!
     167             :  * ----------
     168             :  */
     169             : typedef struct _internalPQconninfoOption
     170             : {
     171             :     char       *keyword;        /* The keyword of the option            */
     172             :     char       *envvar;         /* Fallback environment variable name   */
     173             :     char       *compiled;       /* Fallback compiled in default value   */
     174             :     char       *val;            /* Option's current value, or NULL      */
     175             :     char       *label;          /* Label for field in connect dialog    */
     176             :     char       *dispchar;       /* Indicates how to display this field in a
     177             :                                  * connect dialog. Values are: "" Display
     178             :                                  * entered value as is "*" Password field -
     179             :                                  * hide value "D"  Debug option - don't show
     180             :                                  * by default */
     181             :     int         dispsize;       /* Field size in characters for dialog  */
     182             :     /* ---
     183             :      * Anything above this comment must be synchronized with
     184             :      * PQconninfoOption in libpq-fe.h, since we memcpy() data
     185             :      * between them!
     186             :      * ---
     187             :      */
     188             :     off_t       connofs;        /* Offset into PGconn struct, -1 if not there */
     189             : } internalPQconninfoOption;
     190             : 
     191             : static const internalPQconninfoOption PQconninfoOptions[] = {
     192             :     {"service", "PGSERVICE", NULL, NULL,
     193             :     "Database-Service", "", 20, -1},
     194             : 
     195             :     {"user", "PGUSER", NULL, NULL,
     196             :         "Database-User", "", 20,
     197             :     offsetof(struct pg_conn, pguser)},
     198             : 
     199             :     {"password", "PGPASSWORD", NULL, NULL,
     200             :         "Database-Password", "*", 20,
     201             :     offsetof(struct pg_conn, pgpass)},
     202             : 
     203             :     {"passfile", "PGPASSFILE", NULL, NULL,
     204             :         "Database-Password-File", "", 64,
     205             :     offsetof(struct pg_conn, pgpassfile)},
     206             : 
     207             :     {"channel_binding", "PGCHANNELBINDING", DefaultChannelBinding, NULL,
     208             :         "Channel-Binding", "", 8,   /* sizeof("require") == 8 */
     209             :     offsetof(struct pg_conn, channel_binding)},
     210             : 
     211             :     {"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL,
     212             :         "Connect-timeout", "", 10,  /* strlen(INT32_MAX) == 10 */
     213             :     offsetof(struct pg_conn, connect_timeout)},
     214             : 
     215             :     {"dbname", "PGDATABASE", NULL, NULL,
     216             :         "Database-Name", "", 20,
     217             :     offsetof(struct pg_conn, dbName)},
     218             : 
     219             :     {"host", "PGHOST", NULL, NULL,
     220             :         "Database-Host", "", 40,
     221             :     offsetof(struct pg_conn, pghost)},
     222             : 
     223             :     {"hostaddr", "PGHOSTADDR", NULL, NULL,
     224             :         "Database-Host-IP-Address", "", 45,
     225             :     offsetof(struct pg_conn, pghostaddr)},
     226             : 
     227             :     {"port", "PGPORT", DEF_PGPORT_STR, NULL,
     228             :         "Database-Port", "", 6,
     229             :     offsetof(struct pg_conn, pgport)},
     230             : 
     231             :     {"client_encoding", "PGCLIENTENCODING", NULL, NULL,
     232             :         "Client-Encoding", "", 10,
     233             :     offsetof(struct pg_conn, client_encoding_initial)},
     234             : 
     235             :     {"options", "PGOPTIONS", DefaultOption, NULL,
     236             :         "Backend-Options", "", 40,
     237             :     offsetof(struct pg_conn, pgoptions)},
     238             : 
     239             :     {"application_name", "PGAPPNAME", NULL, NULL,
     240             :         "Application-Name", "", 64,
     241             :     offsetof(struct pg_conn, appname)},
     242             : 
     243             :     {"fallback_application_name", NULL, NULL, NULL,
     244             :         "Fallback-Application-Name", "", 64,
     245             :     offsetof(struct pg_conn, fbappname)},
     246             : 
     247             :     {"keepalives", NULL, NULL, NULL,
     248             :         "TCP-Keepalives", "", 1,    /* should be just '0' or '1' */
     249             :     offsetof(struct pg_conn, keepalives)},
     250             : 
     251             :     {"keepalives_idle", NULL, NULL, NULL,
     252             :         "TCP-Keepalives-Idle", "", 10,  /* strlen(INT32_MAX) == 10 */
     253             :     offsetof(struct pg_conn, keepalives_idle)},
     254             : 
     255             :     {"keepalives_interval", NULL, NULL, NULL,
     256             :         "TCP-Keepalives-Interval", "", 10,  /* strlen(INT32_MAX) == 10 */
     257             :     offsetof(struct pg_conn, keepalives_interval)},
     258             : 
     259             :     {"keepalives_count", NULL, NULL, NULL,
     260             :         "TCP-Keepalives-Count", "", 10, /* strlen(INT32_MAX) == 10 */
     261             :     offsetof(struct pg_conn, keepalives_count)},
     262             : 
     263             :     {"tcp_user_timeout", NULL, NULL, NULL,
     264             :         "TCP-User-Timeout", "", 10, /* strlen(INT32_MAX) == 10 */
     265             :     offsetof(struct pg_conn, pgtcp_user_timeout)},
     266             : 
     267             :     /*
     268             :      * ssl options are allowed even without client SSL support because the
     269             :      * client can still handle SSL modes "disable" and "allow". Other
     270             :      * parameters have no effect on non-SSL connections, so there is no reason
     271             :      * to exclude them since none of them are mandatory.
     272             :      */
     273             :     {"sslmode", "PGSSLMODE", DefaultSSLMode, NULL,
     274             :         "SSL-Mode", "", 12,     /* sizeof("verify-full") == 12 */
     275             :     offsetof(struct pg_conn, sslmode)},
     276             : 
     277             :     {"sslnegotiation", "PGSSLNEGOTIATION", DefaultSSLNegotiation, NULL,
     278             :         "SSL-Negotiation", "", 9,   /* sizeof("postgres") == 9  */
     279             :     offsetof(struct pg_conn, sslnegotiation)},
     280             : 
     281             :     {"sslcompression", "PGSSLCOMPRESSION", "0", NULL,
     282             :         "SSL-Compression", "", 1,
     283             :     offsetof(struct pg_conn, sslcompression)},
     284             : 
     285             :     {"sslcert", "PGSSLCERT", NULL, NULL,
     286             :         "SSL-Client-Cert", "", 64,
     287             :     offsetof(struct pg_conn, sslcert)},
     288             : 
     289             :     {"sslkey", "PGSSLKEY", NULL, NULL,
     290             :         "SSL-Client-Key", "", 64,
     291             :     offsetof(struct pg_conn, sslkey)},
     292             : 
     293             :     {"sslcertmode", "PGSSLCERTMODE", NULL, NULL,
     294             :         "SSL-Client-Cert-Mode", "", 8,  /* sizeof("disable") == 8 */
     295             :     offsetof(struct pg_conn, sslcertmode)},
     296             : 
     297             :     {"sslpassword", NULL, NULL, NULL,
     298             :         "SSL-Client-Key-Password", "*", 20,
     299             :     offsetof(struct pg_conn, sslpassword)},
     300             : 
     301             :     {"sslrootcert", "PGSSLROOTCERT", NULL, NULL,
     302             :         "SSL-Root-Certificate", "", 64,
     303             :     offsetof(struct pg_conn, sslrootcert)},
     304             : 
     305             :     {"sslcrl", "PGSSLCRL", NULL, NULL,
     306             :         "SSL-Revocation-List", "", 64,
     307             :     offsetof(struct pg_conn, sslcrl)},
     308             : 
     309             :     {"sslcrldir", "PGSSLCRLDIR", NULL, NULL,
     310             :         "SSL-Revocation-List-Dir", "", 64,
     311             :     offsetof(struct pg_conn, sslcrldir)},
     312             : 
     313             :     {"sslsni", "PGSSLSNI", "1", NULL,
     314             :         "SSL-SNI", "", 1,
     315             :     offsetof(struct pg_conn, sslsni)},
     316             : 
     317             :     {"requirepeer", "PGREQUIREPEER", NULL, NULL,
     318             :         "Require-Peer", "", 10,
     319             :     offsetof(struct pg_conn, requirepeer)},
     320             : 
     321             :     {"require_auth", "PGREQUIREAUTH", NULL, NULL,
     322             :         "Require-Auth", "", 14, /* sizeof("scram-sha-256") == 14 */
     323             :     offsetof(struct pg_conn, require_auth)},
     324             : 
     325             :     {"ssl_min_protocol_version", "PGSSLMINPROTOCOLVERSION", "TLSv1.2", NULL,
     326             :         "SSL-Minimum-Protocol-Version", "", 8,  /* sizeof("TLSv1.x") == 8 */
     327             :     offsetof(struct pg_conn, ssl_min_protocol_version)},
     328             : 
     329             :     {"ssl_max_protocol_version", "PGSSLMAXPROTOCOLVERSION", NULL, NULL,
     330             :         "SSL-Maximum-Protocol-Version", "", 8,  /* sizeof("TLSv1.x") == 8 */
     331             :     offsetof(struct pg_conn, ssl_max_protocol_version)},
     332             : 
     333             :     /*
     334             :      * As with SSL, all GSS options are exposed even in builds that don't have
     335             :      * support.
     336             :      */
     337             :     {"gssencmode", "PGGSSENCMODE", DefaultGSSMode, NULL,
     338             :         "GSSENC-Mode", "", 8,   /* sizeof("disable") == 8 */
     339             :     offsetof(struct pg_conn, gssencmode)},
     340             : 
     341             :     /* Kerberos and GSSAPI authentication support specifying the service name */
     342             :     {"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL,
     343             :         "Kerberos-service-name", "", 20,
     344             :     offsetof(struct pg_conn, krbsrvname)},
     345             : 
     346             :     {"gsslib", "PGGSSLIB", NULL, NULL,
     347             :         "GSS-library", "", 7,   /* sizeof("gssapi") == 7 */
     348             :     offsetof(struct pg_conn, gsslib)},
     349             : 
     350             :     {"gssdelegation", "PGGSSDELEGATION", "0", NULL,
     351             :         "GSS-delegation", "", 1,
     352             :     offsetof(struct pg_conn, gssdelegation)},
     353             : 
     354             :     {"replication", NULL, NULL, NULL,
     355             :         "Replication", "D", 5,
     356             :     offsetof(struct pg_conn, replication)},
     357             : 
     358             :     {"target_session_attrs", "PGTARGETSESSIONATTRS",
     359             :         DefaultTargetSessionAttrs, NULL,
     360             :         "Target-Session-Attrs", "", 15, /* sizeof("prefer-standby") = 15 */
     361             :     offsetof(struct pg_conn, target_session_attrs)},
     362             : 
     363             :     {"load_balance_hosts", "PGLOADBALANCEHOSTS",
     364             :         DefaultLoadBalanceHosts, NULL,
     365             :         "Load-Balance-Hosts", "", 8,    /* sizeof("disable") = 8 */
     366             :     offsetof(struct pg_conn, load_balance_hosts)},
     367             : 
     368             :     /* Terminating entry --- MUST BE LAST */
     369             :     {NULL, NULL, NULL, NULL,
     370             :     NULL, NULL, 0}
     371             : };
     372             : 
     373             : static const PQEnvironmentOption EnvironmentOptions[] =
     374             : {
     375             :     /* common user-interface settings */
     376             :     {
     377             :         "PGDATESTYLE", "datestyle"
     378             :     },
     379             :     {
     380             :         "PGTZ", "timezone"
     381             :     },
     382             :     /* internal performance-related settings */
     383             :     {
     384             :         "PGGEQO", "geqo"
     385             :     },
     386             :     {
     387             :         NULL, NULL
     388             :     }
     389             : };
     390             : 
     391             : /* The connection URI must start with either of the following designators: */
     392             : static const char uri_designator[] = "postgresql://";
     393             : static const char short_uri_designator[] = "postgres://";
     394             : 
     395             : static bool connectOptions1(PGconn *conn, const char *conninfo);
     396             : static bool init_allowed_encryption_methods(PGconn *conn);
     397             : #if defined(USE_SSL) || defined(ENABLE_GSS)
     398             : static int  encryption_negotiation_failed(PGconn *conn);
     399             : #endif
     400             : static bool connection_failed(PGconn *conn);
     401             : static bool select_next_encryption_method(PGconn *conn, bool have_valid_connection);
     402             : static PGPing internal_ping(PGconn *conn);
     403             : static void pqFreeCommandQueue(PGcmdQueueEntry *queue);
     404             : static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions);
     405             : static void freePGconn(PGconn *conn);
     406             : static void release_conn_addrinfo(PGconn *conn);
     407             : static int  store_conn_addrinfo(PGconn *conn, struct addrinfo *addrlist);
     408             : static void sendTerminateConn(PGconn *conn);
     409             : static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage);
     410             : static PQconninfoOption *parse_connection_string(const char *connstr,
     411             :                                                  PQExpBuffer errorMessage, bool use_defaults);
     412             : static int  uri_prefix_length(const char *connstr);
     413             : static bool recognized_connection_string(const char *connstr);
     414             : static PQconninfoOption *conninfo_parse(const char *conninfo,
     415             :                                         PQExpBuffer errorMessage, bool use_defaults);
     416             : static PQconninfoOption *conninfo_array_parse(const char *const *keywords,
     417             :                                               const char *const *values, PQExpBuffer errorMessage,
     418             :                                               bool use_defaults, int expand_dbname);
     419             : static bool conninfo_add_defaults(PQconninfoOption *options,
     420             :                                   PQExpBuffer errorMessage);
     421             : static PQconninfoOption *conninfo_uri_parse(const char *uri,
     422             :                                             PQExpBuffer errorMessage, bool use_defaults);
     423             : static bool conninfo_uri_parse_options(PQconninfoOption *options,
     424             :                                        const char *uri, PQExpBuffer errorMessage);
     425             : static bool conninfo_uri_parse_params(char *params,
     426             :                                       PQconninfoOption *connOptions,
     427             :                                       PQExpBuffer errorMessage);
     428             : static char *conninfo_uri_decode(const char *str, PQExpBuffer errorMessage);
     429             : static bool get_hexdigit(char digit, int *value);
     430             : static const char *conninfo_getval(PQconninfoOption *connOptions,
     431             :                                    const char *keyword);
     432             : static PQconninfoOption *conninfo_storeval(PQconninfoOption *connOptions,
     433             :                                            const char *keyword, const char *value,
     434             :                                            PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode);
     435             : static PQconninfoOption *conninfo_find(PQconninfoOption *connOptions,
     436             :                                        const char *keyword);
     437             : static void defaultNoticeReceiver(void *arg, const PGresult *res);
     438             : static void defaultNoticeProcessor(void *arg, const char *message);
     439             : static int  parseServiceInfo(PQconninfoOption *options,
     440             :                              PQExpBuffer errorMessage);
     441             : static int  parseServiceFile(const char *serviceFile,
     442             :                              const char *service,
     443             :                              PQconninfoOption *options,
     444             :                              PQExpBuffer errorMessage,
     445             :                              bool *group_found);
     446             : static char *pwdfMatchesString(char *buf, const char *token);
     447             : static char *passwordFromFile(const char *hostname, const char *port, const char *dbname,
     448             :                               const char *username, const char *pgpassfile);
     449             : static void pgpassfileWarning(PGconn *conn);
     450             : static void default_threadlock(int acquire);
     451             : static bool sslVerifyProtocolVersion(const char *version);
     452             : static bool sslVerifyProtocolRange(const char *min, const char *max);
     453             : 
     454             : 
     455             : /* global variable because fe-auth.c needs to access it */
     456             : pgthreadlock_t pg_g_threadlock = default_threadlock;
     457             : 
     458             : 
     459             : /*
     460             :  *      pqDropConnection
     461             :  *
     462             :  * Close any physical connection to the server, and reset associated
     463             :  * state inside the connection object.  We don't release state that
     464             :  * would be needed to reconnect, though, nor local state that might still
     465             :  * be useful later.
     466             :  *
     467             :  * We can always flush the output buffer, since there's no longer any hope
     468             :  * of sending that data.  However, unprocessed input data might still be
     469             :  * valuable, so the caller must tell us whether to flush that or not.
     470             :  */
     471             : void
     472       53734 : pqDropConnection(PGconn *conn, bool flushInput)
     473             : {
     474             :     /* Drop any SSL state */
     475       53734 :     pqsecure_close(conn);
     476             : 
     477             :     /* Close the socket itself */
     478       53734 :     if (conn->sock != PGINVALID_SOCKET)
     479       26152 :         closesocket(conn->sock);
     480       53734 :     conn->sock = PGINVALID_SOCKET;
     481             : 
     482             :     /* Optionally discard any unread data */
     483       53734 :     if (flushInput)
     484       53512 :         conn->inStart = conn->inCursor = conn->inEnd = 0;
     485             : 
     486             :     /* Always discard any unsent data */
     487       53734 :     conn->outCount = 0;
     488             : 
     489             :     /* Likewise, discard any pending pipelined commands */
     490       53734 :     pqFreeCommandQueue(conn->cmd_queue_head);
     491       53734 :     conn->cmd_queue_head = conn->cmd_queue_tail = NULL;
     492       53734 :     pqFreeCommandQueue(conn->cmd_queue_recycle);
     493       53734 :     conn->cmd_queue_recycle = NULL;
     494             : 
     495             :     /* Free authentication/encryption state */
     496             : #ifdef ENABLE_GSS
     497             :     {
     498             :         OM_uint32   min_s;
     499             : 
     500             :         if (conn->gcred != GSS_C_NO_CREDENTIAL)
     501             :         {
     502             :             gss_release_cred(&min_s, &conn->gcred);
     503             :             conn->gcred = GSS_C_NO_CREDENTIAL;
     504             :         }
     505             :         if (conn->gctx)
     506             :             gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
     507             :         if (conn->gtarg_nam)
     508             :             gss_release_name(&min_s, &conn->gtarg_nam);
     509             :         if (conn->gss_SendBuffer)
     510             :         {
     511             :             free(conn->gss_SendBuffer);
     512             :             conn->gss_SendBuffer = NULL;
     513             :         }
     514             :         if (conn->gss_RecvBuffer)
     515             :         {
     516             :             free(conn->gss_RecvBuffer);
     517             :             conn->gss_RecvBuffer = NULL;
     518             :         }
     519             :         if (conn->gss_ResultBuffer)
     520             :         {
     521             :             free(conn->gss_ResultBuffer);
     522             :             conn->gss_ResultBuffer = NULL;
     523             :         }
     524             :         conn->gssenc = false;
     525             :     }
     526             : #endif
     527             : #ifdef ENABLE_SSPI
     528             :     if (conn->sspitarget)
     529             :     {
     530             :         free(conn->sspitarget);
     531             :         conn->sspitarget = NULL;
     532             :     }
     533             :     if (conn->sspicred)
     534             :     {
     535             :         FreeCredentialsHandle(conn->sspicred);
     536             :         free(conn->sspicred);
     537             :         conn->sspicred = NULL;
     538             :     }
     539             :     if (conn->sspictx)
     540             :     {
     541             :         DeleteSecurityContext(conn->sspictx);
     542             :         free(conn->sspictx);
     543             :         conn->sspictx = NULL;
     544             :     }
     545             :     conn->usesspi = 0;
     546             : #endif
     547       53734 :     if (conn->sasl_state)
     548             :     {
     549          80 :         conn->sasl->free(conn->sasl_state);
     550          80 :         conn->sasl_state = NULL;
     551             :     }
     552       53734 : }
     553             : 
     554             : /*
     555             :  * pqFreeCommandQueue
     556             :  * Free all the entries of PGcmdQueueEntry queue passed.
     557             :  */
     558             : static void
     559      107468 : pqFreeCommandQueue(PGcmdQueueEntry *queue)
     560             : {
     561      133988 :     while (queue != NULL)
     562             :     {
     563       26520 :         PGcmdQueueEntry *cur = queue;
     564             : 
     565       26520 :         queue = cur->next;
     566       26520 :         free(cur->query);
     567       26520 :         free(cur);
     568             :     }
     569      107468 : }
     570             : 
     571             : /*
     572             :  *      pqDropServerData
     573             :  *
     574             :  * Clear all connection state data that was received from (or deduced about)
     575             :  * the server.  This is essential to do between connection attempts to
     576             :  * different servers, else we may incorrectly hold over some data from the
     577             :  * old server.
     578             :  *
     579             :  * It would be better to merge this into pqDropConnection, perhaps, but
     580             :  * right now we cannot because that function is called immediately on
     581             :  * detection of connection loss (cf. pqReadData, for instance).  This data
     582             :  * should be kept until we are actually starting a new connection.
     583             :  */
     584             : static void
     585       53108 : pqDropServerData(PGconn *conn)
     586             : {
     587             :     PGnotify   *notify;
     588             :     pgParameterStatus *pstatus;
     589             : 
     590             :     /* Forget pending notifies */
     591       53108 :     notify = conn->notifyHead;
     592       53108 :     while (notify != NULL)
     593             :     {
     594           0 :         PGnotify   *prev = notify;
     595             : 
     596           0 :         notify = notify->next;
     597           0 :         free(prev);
     598             :     }
     599       53108 :     conn->notifyHead = conn->notifyTail = NULL;
     600             : 
     601             :     /* Reset ParameterStatus data, as well as variables deduced from it */
     602       53108 :     pstatus = conn->pstatus;
     603      431318 :     while (pstatus != NULL)
     604             :     {
     605      378210 :         pgParameterStatus *prev = pstatus;
     606             : 
     607      378210 :         pstatus = pstatus->next;
     608      378210 :         free(prev);
     609             :     }
     610       53108 :     conn->pstatus = NULL;
     611       53108 :     conn->client_encoding = PG_SQL_ASCII;
     612       53108 :     conn->std_strings = false;
     613       53108 :     conn->default_transaction_read_only = PG_BOOL_UNKNOWN;
     614       53108 :     conn->in_hot_standby = PG_BOOL_UNKNOWN;
     615       53108 :     conn->scram_sha_256_iterations = SCRAM_SHA_256_DEFAULT_ITERATIONS;
     616       53108 :     conn->sversion = 0;
     617             : 
     618             :     /* Drop large-object lookup data */
     619       53108 :     free(conn->lobjfuncs);
     620       53108 :     conn->lobjfuncs = NULL;
     621             : 
     622             :     /* Reset assorted other per-connection state */
     623       53108 :     conn->last_sqlstate[0] = '\0';
     624       53108 :     conn->auth_req_received = false;
     625       53108 :     conn->client_finished_auth = false;
     626       53108 :     conn->password_needed = false;
     627       53108 :     conn->gssapi_used = false;
     628       53108 :     conn->write_failed = false;
     629       53108 :     free(conn->write_err_msg);
     630       53108 :     conn->write_err_msg = NULL;
     631             : 
     632             :     /*
     633             :      * Cancel connections need to retain their be_pid and be_key across
     634             :      * PQcancelReset invocations, otherwise they would not have access to the
     635             :      * secret token of the connection they are supposed to cancel.
     636             :      */
     637       53108 :     if (!conn->cancelRequest)
     638             :     {
     639       53098 :         conn->be_pid = 0;
     640       53098 :         conn->be_key = 0;
     641             :     }
     642       53108 : }
     643             : 
     644             : 
     645             : /*
     646             :  *      Connecting to a Database
     647             :  *
     648             :  * There are now six different ways a user of this API can connect to the
     649             :  * database.  Two are not recommended for use in new code, because of their
     650             :  * lack of extensibility with respect to the passing of options to the
     651             :  * backend.  These are PQsetdb and PQsetdbLogin (the former now being a macro
     652             :  * to the latter).
     653             :  *
     654             :  * If it is desired to connect in a synchronous (blocking) manner, use the
     655             :  * function PQconnectdb or PQconnectdbParams. The former accepts a string of
     656             :  * option = value pairs (or a URI) which must be parsed; the latter takes two
     657             :  * NULL terminated arrays instead.
     658             :  *
     659             :  * To connect in an asynchronous (non-blocking) manner, use the functions
     660             :  * PQconnectStart or PQconnectStartParams (which differ in the same way as
     661             :  * PQconnectdb and PQconnectdbParams) and PQconnectPoll.
     662             :  *
     663             :  * The non-exported functions pqConnectDBStart, pqConnectDBComplete are
     664             :  * part of the connection procedure implementation.
     665             :  */
     666             : 
     667             : /*
     668             :  *      PQconnectdbParams
     669             :  *
     670             :  * establishes a connection to a postgres backend through the postmaster
     671             :  * using connection information in two arrays.
     672             :  *
     673             :  * The keywords array is defined as
     674             :  *
     675             :  *     const char *params[] = {"option1", "option2", NULL}
     676             :  *
     677             :  * The values array is defined as
     678             :  *
     679             :  *     const char *values[] = {"value1", "value2", NULL}
     680             :  *
     681             :  * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
     682             :  * if a memory allocation failed.
     683             :  * If the status field of the connection returned is CONNECTION_BAD,
     684             :  * then some fields may be null'ed out instead of having valid values.
     685             :  *
     686             :  * You should call PQfinish (if conn is not NULL) regardless of whether this
     687             :  * call succeeded.
     688             :  */
     689             : PGconn *
     690       22308 : PQconnectdbParams(const char *const *keywords,
     691             :                   const char *const *values,
     692             :                   int expand_dbname)
     693             : {
     694       22308 :     PGconn     *conn = PQconnectStartParams(keywords, values, expand_dbname);
     695             : 
     696       22308 :     if (conn && conn->status != CONNECTION_BAD)
     697       22234 :         (void) pqConnectDBComplete(conn);
     698             : 
     699       22308 :     return conn;
     700             : }
     701             : 
     702             : /*
     703             :  *      PQpingParams
     704             :  *
     705             :  * check server status, accepting parameters identical to PQconnectdbParams
     706             :  */
     707             : PGPing
     708         632 : PQpingParams(const char *const *keywords,
     709             :              const char *const *values,
     710             :              int expand_dbname)
     711             : {
     712         632 :     PGconn     *conn = PQconnectStartParams(keywords, values, expand_dbname);
     713             :     PGPing      ret;
     714             : 
     715         632 :     ret = internal_ping(conn);
     716         632 :     PQfinish(conn);
     717             : 
     718         632 :     return ret;
     719             : }
     720             : 
     721             : /*
     722             :  *      PQconnectdb
     723             :  *
     724             :  * establishes a connection to a postgres backend through the postmaster
     725             :  * using connection information in a string.
     726             :  *
     727             :  * The conninfo string is either a whitespace-separated list of
     728             :  *
     729             :  *     option = value
     730             :  *
     731             :  * definitions or a URI (refer to the documentation for details.) Value
     732             :  * might be a single value containing no whitespaces or a single quoted
     733             :  * string. If a single quote should appear anywhere in the value, it must be
     734             :  * escaped with a backslash like \'
     735             :  *
     736             :  * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL
     737             :  * if a memory allocation failed.
     738             :  * If the status field of the connection returned is CONNECTION_BAD,
     739             :  * then some fields may be null'ed out instead of having valid values.
     740             :  *
     741             :  * You should call PQfinish (if conn is not NULL) regardless of whether this
     742             :  * call succeeded.
     743             :  */
     744             : PGconn *
     745        1362 : PQconnectdb(const char *conninfo)
     746             : {
     747        1362 :     PGconn     *conn = PQconnectStart(conninfo);
     748             : 
     749        1362 :     if (conn && conn->status != CONNECTION_BAD)
     750        1362 :         (void) pqConnectDBComplete(conn);
     751             : 
     752        1362 :     return conn;
     753             : }
     754             : 
     755             : /*
     756             :  *      PQping
     757             :  *
     758             :  * check server status, accepting parameters identical to PQconnectdb
     759             :  */
     760             : PGPing
     761           0 : PQping(const char *conninfo)
     762             : {
     763           0 :     PGconn     *conn = PQconnectStart(conninfo);
     764             :     PGPing      ret;
     765             : 
     766           0 :     ret = internal_ping(conn);
     767           0 :     PQfinish(conn);
     768             : 
     769           0 :     return ret;
     770             : }
     771             : 
     772             : /*
     773             :  *      PQconnectStartParams
     774             :  *
     775             :  * Begins the establishment of a connection to a postgres backend through the
     776             :  * postmaster using connection information in a struct.
     777             :  *
     778             :  * See comment for PQconnectdbParams for the definition of the string format.
     779             :  *
     780             :  * Returns a PGconn*.  If NULL is returned, a malloc error has occurred, and
     781             :  * you should not attempt to proceed with this connection.  If the status
     782             :  * field of the connection returned is CONNECTION_BAD, an error has
     783             :  * occurred. In this case you should call PQfinish on the result, (perhaps
     784             :  * inspecting the error message first).  Other fields of the structure may not
     785             :  * be valid if that occurs.  If the status field is not CONNECTION_BAD, then
     786             :  * this stage has succeeded - call PQconnectPoll, using select(2) to see when
     787             :  * this is necessary.
     788             :  *
     789             :  * See PQconnectPoll for more info.
     790             :  */
     791             : PGconn *
     792       24914 : PQconnectStartParams(const char *const *keywords,
     793             :                      const char *const *values,
     794             :                      int expand_dbname)
     795             : {
     796             :     PGconn     *conn;
     797             :     PQconninfoOption *connOptions;
     798             : 
     799             :     /*
     800             :      * Allocate memory for the conn structure.  Note that we also expect this
     801             :      * to initialize conn->errorMessage to empty.  All subsequent steps during
     802             :      * connection initialization will only append to that buffer.
     803             :      */
     804       24914 :     conn = pqMakeEmptyPGconn();
     805       24914 :     if (conn == NULL)
     806           0 :         return NULL;
     807             : 
     808             :     /*
     809             :      * Parse the conninfo arrays
     810             :      */
     811       24914 :     connOptions = conninfo_array_parse(keywords, values,
     812             :                                        &conn->errorMessage,
     813             :                                        true, expand_dbname);
     814       24914 :     if (connOptions == NULL)
     815             :     {
     816           0 :         conn->status = CONNECTION_BAD;
     817             :         /* errorMessage is already set */
     818           0 :         return conn;
     819             :     }
     820             : 
     821             :     /*
     822             :      * Move option values into conn structure
     823             :      */
     824       24914 :     if (!fillPGconn(conn, connOptions))
     825             :     {
     826           0 :         PQconninfoFree(connOptions);
     827           0 :         return conn;
     828             :     }
     829             : 
     830             :     /*
     831             :      * Free the option info - all is in conn now
     832             :      */
     833       24914 :     PQconninfoFree(connOptions);
     834             : 
     835             :     /*
     836             :      * Compute derived options
     837             :      */
     838       24914 :     if (!pqConnectOptions2(conn))
     839          74 :         return conn;
     840             : 
     841             :     /*
     842             :      * Connect to the database
     843             :      */
     844       24840 :     if (!pqConnectDBStart(conn))
     845             :     {
     846             :         /* Just in case we failed to set it in pqConnectDBStart */
     847         404 :         conn->status = CONNECTION_BAD;
     848             :     }
     849             : 
     850       24840 :     return conn;
     851             : }
     852             : 
     853             : /*
     854             :  *      PQconnectStart
     855             :  *
     856             :  * Begins the establishment of a connection to a postgres backend through the
     857             :  * postmaster using connection information in a string.
     858             :  *
     859             :  * See comment for PQconnectdb for the definition of the string format.
     860             :  *
     861             :  * Returns a PGconn*.  If NULL is returned, a malloc error has occurred, and
     862             :  * you should not attempt to proceed with this connection.  If the status
     863             :  * field of the connection returned is CONNECTION_BAD, an error has
     864             :  * occurred. In this case you should call PQfinish on the result, (perhaps
     865             :  * inspecting the error message first).  Other fields of the structure may not
     866             :  * be valid if that occurs.  If the status field is not CONNECTION_BAD, then
     867             :  * this stage has succeeded - call PQconnectPoll, using select(2) to see when
     868             :  * this is necessary.
     869             :  *
     870             :  * See PQconnectPoll for more info.
     871             :  */
     872             : PGconn *
     873        1648 : PQconnectStart(const char *conninfo)
     874             : {
     875             :     PGconn     *conn;
     876             : 
     877             :     /*
     878             :      * Allocate memory for the conn structure.  Note that we also expect this
     879             :      * to initialize conn->errorMessage to empty.  All subsequent steps during
     880             :      * connection initialization will only append to that buffer.
     881             :      */
     882        1648 :     conn = pqMakeEmptyPGconn();
     883        1648 :     if (conn == NULL)
     884           0 :         return NULL;
     885             : 
     886             :     /*
     887             :      * Parse the conninfo string
     888             :      */
     889        1648 :     if (!connectOptions1(conn, conninfo))
     890           4 :         return conn;
     891             : 
     892             :     /*
     893             :      * Compute derived options
     894             :      */
     895        1644 :     if (!pqConnectOptions2(conn))
     896           0 :         return conn;
     897             : 
     898             :     /*
     899             :      * Connect to the database
     900             :      */
     901        1644 :     if (!pqConnectDBStart(conn))
     902             :     {
     903             :         /* Just in case we failed to set it in pqConnectDBStart */
     904           0 :         conn->status = CONNECTION_BAD;
     905             :     }
     906             : 
     907        1644 :     return conn;
     908             : }
     909             : 
     910             : /*
     911             :  * Move option values into conn structure
     912             :  *
     913             :  * Don't put anything cute here --- intelligence should be in
     914             :  * pqConnectOptions2 ...
     915             :  *
     916             :  * Returns true on success. On failure, returns false and sets error message.
     917             :  */
     918             : static bool
     919       26558 : fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
     920             : {
     921             :     const internalPQconninfoOption *option;
     922             : 
     923     1115436 :     for (option = PQconninfoOptions; option->keyword; option++)
     924             :     {
     925     1088878 :         if (option->connofs >= 0)
     926             :         {
     927     1062320 :             const char *tmp = conninfo_getval(connOptions, option->keyword);
     928             : 
     929     1062320 :             if (tmp)
     930             :             {
     931      480914 :                 char      **connmember = (char **) ((char *) conn + option->connofs);
     932             : 
     933      480914 :                 free(*connmember);
     934      480914 :                 *connmember = strdup(tmp);
     935      480914 :                 if (*connmember == NULL)
     936             :                 {
     937           0 :                     libpq_append_conn_error(conn, "out of memory");
     938           0 :                     return false;
     939             :                 }
     940             :             }
     941             :         }
     942             :     }
     943             : 
     944       26558 :     return true;
     945             : }
     946             : 
     947             : /*
     948             :  * Copy over option values from srcConn to dstConn
     949             :  *
     950             :  * Don't put anything cute here --- intelligence should be in
     951             :  * pqConnectOptions2 ...
     952             :  *
     953             :  * Returns true on success. On failure, returns false and sets error message of
     954             :  * dstConn.
     955             :  */
     956             : bool
     957           8 : pqCopyPGconn(PGconn *srcConn, PGconn *dstConn)
     958             : {
     959             :     const internalPQconninfoOption *option;
     960             : 
     961             :     /* copy over connection options */
     962         336 :     for (option = PQconninfoOptions; option->keyword; option++)
     963             :     {
     964         328 :         if (option->connofs >= 0)
     965             :         {
     966         320 :             const char **tmp = (const char **) ((char *) srcConn + option->connofs);
     967             : 
     968         320 :             if (*tmp)
     969             :             {
     970         156 :                 char      **dstConnmember = (char **) ((char *) dstConn + option->connofs);
     971             : 
     972         156 :                 if (*dstConnmember)
     973           0 :                     free(*dstConnmember);
     974         156 :                 *dstConnmember = strdup(*tmp);
     975         156 :                 if (*dstConnmember == NULL)
     976             :                 {
     977           0 :                     libpq_append_conn_error(dstConn, "out of memory");
     978           0 :                     return false;
     979             :                 }
     980             :             }
     981             :         }
     982             :     }
     983           8 :     return true;
     984             : }
     985             : 
     986             : /*
     987             :  *      connectOptions1
     988             :  *
     989             :  * Internal subroutine to set up connection parameters given an already-
     990             :  * created PGconn and a conninfo string.  Derived settings should be
     991             :  * processed by calling pqConnectOptions2 next.  (We split them because
     992             :  * PQsetdbLogin overrides defaults in between.)
     993             :  *
     994             :  * Returns true if OK, false if trouble (in which case errorMessage is set
     995             :  * and so is conn->status).
     996             :  */
     997             : static bool
     998        1648 : connectOptions1(PGconn *conn, const char *conninfo)
     999             : {
    1000             :     PQconninfoOption *connOptions;
    1001             : 
    1002             :     /*
    1003             :      * Parse the conninfo string
    1004             :      */
    1005        1648 :     connOptions = parse_connection_string(conninfo, &conn->errorMessage, true);
    1006        1648 :     if (connOptions == NULL)
    1007             :     {
    1008           4 :         conn->status = CONNECTION_BAD;
    1009             :         /* errorMessage is already set */
    1010           4 :         return false;
    1011             :     }
    1012             : 
    1013             :     /*
    1014             :      * Move option values into conn structure
    1015             :      */
    1016        1644 :     if (!fillPGconn(conn, connOptions))
    1017             :     {
    1018           0 :         conn->status = CONNECTION_BAD;
    1019           0 :         PQconninfoFree(connOptions);
    1020           0 :         return false;
    1021             :     }
    1022             : 
    1023             :     /*
    1024             :      * Free the option info - all is in conn now
    1025             :      */
    1026        1644 :     PQconninfoFree(connOptions);
    1027             : 
    1028        1644 :     return true;
    1029             : }
    1030             : 
    1031             : /*
    1032             :  * Count the number of elements in a simple comma-separated list.
    1033             :  */
    1034             : static int
    1035       26566 : count_comma_separated_elems(const char *input)
    1036             : {
    1037             :     int         n;
    1038             : 
    1039       26566 :     n = 1;
    1040      450382 :     for (; *input != '\0'; input++)
    1041             :     {
    1042      423816 :         if (*input == ',')
    1043         266 :             n++;
    1044             :     }
    1045             : 
    1046       26566 :     return n;
    1047             : }
    1048             : 
    1049             : /*
    1050             :  * Parse a simple comma-separated list.
    1051             :  *
    1052             :  * On each call, returns a malloc'd copy of the next element, and sets *more
    1053             :  * to indicate whether there are any more elements in the list after this,
    1054             :  * and updates *startptr to point to the next element, if any.
    1055             :  *
    1056             :  * On out of memory, returns NULL.
    1057             :  */
    1058             : static char *
    1059       54162 : parse_comma_separated_list(char **startptr, bool *more)
    1060             : {
    1061             :     char       *p;
    1062       54162 :     char       *s = *startptr;
    1063             :     char       *e;
    1064             :     int         len;
    1065             : 
    1066             :     /*
    1067             :      * Search for the end of the current element; a comma or end-of-string
    1068             :      * acts as a terminator.
    1069             :      */
    1070       54162 :     e = s;
    1071      621372 :     while (*e != '\0' && *e != ',')
    1072      567210 :         ++e;
    1073       54162 :     *more = (*e == ',');
    1074             : 
    1075       54162 :     len = e - s;
    1076       54162 :     p = (char *) malloc(sizeof(char) * (len + 1));
    1077       54162 :     if (p)
    1078             :     {
    1079       54162 :         memcpy(p, s, len);
    1080       54162 :         p[len] = '\0';
    1081             :     }
    1082       54162 :     *startptr = e + 1;
    1083             : 
    1084       54162 :     return p;
    1085             : }
    1086             : 
    1087             : /*
    1088             :  * Initializes the prng_state field of the connection. We want something
    1089             :  * unpredictable, so if possible, use high-quality random bits for the
    1090             :  * seed. Otherwise, fall back to a seed based on the connection address,
    1091             :  * timestamp and PID.
    1092             :  */
    1093             : static void
    1094         110 : libpq_prng_init(PGconn *conn)
    1095             : {
    1096             :     uint64      rseed;
    1097         110 :     struct timeval tval = {0};
    1098             : 
    1099         110 :     if (pg_prng_strong_seed(&conn->prng_state))
    1100         110 :         return;
    1101             : 
    1102           0 :     gettimeofday(&tval, NULL);
    1103             : 
    1104           0 :     rseed = ((uintptr_t) conn) ^
    1105           0 :         ((uint64) getpid()) ^
    1106           0 :         ((uint64) tval.tv_usec) ^
    1107           0 :         ((uint64) tval.tv_sec);
    1108             : 
    1109           0 :     pg_prng_seed(&conn->prng_state, rseed);
    1110             : }
    1111             : 
    1112             : /*
    1113             :  *      pqConnectOptions2
    1114             :  *
    1115             :  * Compute derived connection options after absorbing all user-supplied info.
    1116             :  *
    1117             :  * Returns true if OK, false if trouble (in which case errorMessage is set
    1118             :  * and so is conn->status).
    1119             :  */
    1120             : bool
    1121       26566 : pqConnectOptions2(PGconn *conn)
    1122             : {
    1123             :     int         i;
    1124             : 
    1125             :     /*
    1126             :      * Allocate memory for details about each host to which we might possibly
    1127             :      * try to connect.  For that, count the number of elements in the hostaddr
    1128             :      * or host options.  If neither is given, assume one host.
    1129             :      */
    1130       26566 :     conn->whichhost = 0;
    1131       26566 :     if (conn->pghostaddr && conn->pghostaddr[0] != '\0')
    1132         346 :         conn->nconnhost = count_comma_separated_elems(conn->pghostaddr);
    1133       26220 :     else if (conn->pghost && conn->pghost[0] != '\0')
    1134       26220 :         conn->nconnhost = count_comma_separated_elems(conn->pghost);
    1135             :     else
    1136           0 :         conn->nconnhost = 1;
    1137       26566 :     conn->connhost = (pg_conn_host *)
    1138       26566 :         calloc(conn->nconnhost, sizeof(pg_conn_host));
    1139       26566 :     if (conn->connhost == NULL)
    1140           0 :         goto oom_error;
    1141             : 
    1142             :     /*
    1143             :      * We now have one pg_conn_host structure per possible host.  Fill in the
    1144             :      * host and hostaddr fields for each, by splitting the parameter strings.
    1145             :      */
    1146       26566 :     if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0')
    1147             :     {
    1148         346 :         char       *s = conn->pghostaddr;
    1149         346 :         bool        more = true;
    1150             : 
    1151         692 :         for (i = 0; i < conn->nconnhost && more; i++)
    1152             :         {
    1153         346 :             conn->connhost[i].hostaddr = parse_comma_separated_list(&s, &more);
    1154         346 :             if (conn->connhost[i].hostaddr == NULL)
    1155           0 :                 goto oom_error;
    1156             :         }
    1157             : 
    1158             :         /*
    1159             :          * If hostaddr was given, the array was allocated according to the
    1160             :          * number of elements in the hostaddr list, so it really should be the
    1161             :          * right size.
    1162             :          */
    1163             :         Assert(!more);
    1164             :         Assert(i == conn->nconnhost);
    1165             :     }
    1166             : 
    1167       26566 :     if (conn->pghost != NULL && conn->pghost[0] != '\0')
    1168             :     {
    1169       26566 :         char       *s = conn->pghost;
    1170       26566 :         bool        more = true;
    1171             : 
    1172       53398 :         for (i = 0; i < conn->nconnhost && more; i++)
    1173             :         {
    1174       26832 :             conn->connhost[i].host = parse_comma_separated_list(&s, &more);
    1175       26832 :             if (conn->connhost[i].host == NULL)
    1176           0 :                 goto oom_error;
    1177             :         }
    1178             : 
    1179             :         /* Check for wrong number of host items. */
    1180       26566 :         if (more || i != conn->nconnhost)
    1181             :         {
    1182           0 :             conn->status = CONNECTION_BAD;
    1183           0 :             libpq_append_conn_error(conn, "could not match %d host names to %d hostaddr values",
    1184           0 :                                     count_comma_separated_elems(conn->pghost), conn->nconnhost);
    1185           0 :             return false;
    1186             :         }
    1187             :     }
    1188             : 
    1189             :     /*
    1190             :      * Now, for each host slot, identify the type of address spec, and fill in
    1191             :      * the default address if nothing was given.
    1192             :      */
    1193       53398 :     for (i = 0; i < conn->nconnhost; i++)
    1194             :     {
    1195       26832 :         pg_conn_host *ch = &conn->connhost[i];
    1196             : 
    1197       26832 :         if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0')
    1198         346 :             ch->type = CHT_HOST_ADDRESS;
    1199       26486 :         else if (ch->host != NULL && ch->host[0] != '\0')
    1200             :         {
    1201       26486 :             ch->type = CHT_HOST_NAME;
    1202       26486 :             if (is_unixsock_path(ch->host))
    1203       26194 :                 ch->type = CHT_UNIX_SOCKET;
    1204             :         }
    1205             :         else
    1206             :         {
    1207           0 :             free(ch->host);
    1208             : 
    1209             :             /*
    1210             :              * This bit selects the default host location.  If you change
    1211             :              * this, see also pg_regress.
    1212             :              */
    1213           0 :             if (DEFAULT_PGSOCKET_DIR[0])
    1214             :             {
    1215           0 :                 ch->host = strdup(DEFAULT_PGSOCKET_DIR);
    1216           0 :                 ch->type = CHT_UNIX_SOCKET;
    1217             :             }
    1218             :             else
    1219             :             {
    1220           0 :                 ch->host = strdup(DefaultHost);
    1221           0 :                 ch->type = CHT_HOST_NAME;
    1222             :             }
    1223           0 :             if (ch->host == NULL)
    1224           0 :                 goto oom_error;
    1225             :         }
    1226             :     }
    1227             : 
    1228             :     /*
    1229             :      * Next, work out the port number corresponding to each host name.
    1230             :      *
    1231             :      * Note: unlike the above for host names, this could leave the port fields
    1232             :      * as null or empty strings.  We will substitute DEF_PGPORT whenever we
    1233             :      * read such a port field.
    1234             :      */
    1235       26566 :     if (conn->pgport != NULL && conn->pgport[0] != '\0')
    1236             :     {
    1237       26566 :         char       *s = conn->pgport;
    1238       26566 :         bool        more = true;
    1239             : 
    1240       53398 :         for (i = 0; i < conn->nconnhost && more; i++)
    1241             :         {
    1242       26832 :             conn->connhost[i].port = parse_comma_separated_list(&s, &more);
    1243       26832 :             if (conn->connhost[i].port == NULL)
    1244           0 :                 goto oom_error;
    1245             :         }
    1246             : 
    1247             :         /*
    1248             :          * If exactly one port was given, use it for every host.  Otherwise,
    1249             :          * there must be exactly as many ports as there were hosts.
    1250             :          */
    1251       26566 :         if (i == 1 && !more)
    1252             :         {
    1253       26416 :             for (i = 1; i < conn->nconnhost; i++)
    1254             :             {
    1255           0 :                 conn->connhost[i].port = strdup(conn->connhost[0].port);
    1256           0 :                 if (conn->connhost[i].port == NULL)
    1257           0 :                     goto oom_error;
    1258             :             }
    1259             :         }
    1260         150 :         else if (more || i != conn->nconnhost)
    1261             :         {
    1262           0 :             conn->status = CONNECTION_BAD;
    1263           0 :             libpq_append_conn_error(conn, "could not match %d port numbers to %d hosts",
    1264           0 :                                     count_comma_separated_elems(conn->pgport), conn->nconnhost);
    1265           0 :             return false;
    1266             :         }
    1267             :     }
    1268             : 
    1269             :     /*
    1270             :      * If user name was not given, fetch it.  (Most likely, the fetch will
    1271             :      * fail, since the only way we get here is if pg_fe_getauthname() failed
    1272             :      * during conninfo_add_defaults().  But now we want an error message.)
    1273             :      */
    1274       26566 :     if (conn->pguser == NULL || conn->pguser[0] == '\0')
    1275             :     {
    1276           0 :         free(conn->pguser);
    1277           0 :         conn->pguser = pg_fe_getauthname(&conn->errorMessage);
    1278           0 :         if (!conn->pguser)
    1279             :         {
    1280           0 :             conn->status = CONNECTION_BAD;
    1281           0 :             return false;
    1282             :         }
    1283             :     }
    1284             : 
    1285             :     /*
    1286             :      * If database name was not given, default it to equal user name
    1287             :      */
    1288       26566 :     if (conn->dbName == NULL || conn->dbName[0] == '\0')
    1289             :     {
    1290          12 :         free(conn->dbName);
    1291          12 :         conn->dbName = strdup(conn->pguser);
    1292          12 :         if (!conn->dbName)
    1293           0 :             goto oom_error;
    1294             :     }
    1295             : 
    1296             :     /*
    1297             :      * If password was not given, try to look it up in password file.  Note
    1298             :      * that the result might be different for each host/port pair.
    1299             :      */
    1300       26566 :     if (conn->pgpass == NULL || conn->pgpass[0] == '\0')
    1301             :     {
    1302             :         /* If password file wasn't specified, use ~/PGPASSFILE */
    1303       26248 :         if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0')
    1304             :         {
    1305             :             char        homedir[MAXPGPATH];
    1306             : 
    1307       25908 :             if (pqGetHomeDirectory(homedir, sizeof(homedir)))
    1308             :             {
    1309       25908 :                 free(conn->pgpassfile);
    1310       25908 :                 conn->pgpassfile = malloc(MAXPGPATH);
    1311       25908 :                 if (!conn->pgpassfile)
    1312           0 :                     goto oom_error;
    1313       25908 :                 snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s",
    1314             :                          homedir, PGPASSFILE);
    1315             :             }
    1316             :         }
    1317             : 
    1318       26248 :         if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0')
    1319             :         {
    1320       52762 :             for (i = 0; i < conn->nconnhost; i++)
    1321             :             {
    1322             :                 /*
    1323             :                  * Try to get a password for this host from file.  We use host
    1324             :                  * for the hostname search key if given, else hostaddr (at
    1325             :                  * least one of them is guaranteed nonempty by now).
    1326             :                  */
    1327       26514 :                 const char *pwhost = conn->connhost[i].host;
    1328             : 
    1329       26514 :                 if (pwhost == NULL || pwhost[0] == '\0')
    1330           0 :                     pwhost = conn->connhost[i].hostaddr;
    1331             : 
    1332       26514 :                 conn->connhost[i].password =
    1333       26514 :                     passwordFromFile(pwhost,
    1334       26514 :                                      conn->connhost[i].port,
    1335       26514 :                                      conn->dbName,
    1336       26514 :                                      conn->pguser,
    1337       26514 :                                      conn->pgpassfile);
    1338             :             }
    1339             :         }
    1340             :     }
    1341             : 
    1342             :     /*
    1343             :      * parse and validate require_auth option
    1344             :      */
    1345       26566 :     if (conn->require_auth && conn->require_auth[0])
    1346             :     {
    1347         100 :         char       *s = conn->require_auth;
    1348             :         bool        first,
    1349             :                     more;
    1350         100 :         bool        negated = false;
    1351             : 
    1352             :         /*
    1353             :          * By default, start from an empty set of allowed options and add to
    1354             :          * it.
    1355             :          */
    1356         100 :         conn->auth_required = true;
    1357         100 :         conn->allowed_auth_methods = 0;
    1358             : 
    1359         238 :         for (first = true, more = true; more; first = false)
    1360             :         {
    1361             :             char       *method,
    1362             :                        *part;
    1363             :             uint32      bits;
    1364             : 
    1365         152 :             part = parse_comma_separated_list(&s, &more);
    1366         152 :             if (part == NULL)
    1367           0 :                 goto oom_error;
    1368             : 
    1369             :             /*
    1370             :              * Check for negation, e.g. '!password'. If one element is
    1371             :              * negated, they all have to be.
    1372             :              */
    1373         152 :             method = part;
    1374         152 :             if (*method == '!')
    1375             :             {
    1376          64 :                 if (first)
    1377             :                 {
    1378             :                     /*
    1379             :                      * Switch to a permissive set of allowed options, and
    1380             :                      * subtract from it.
    1381             :                      */
    1382          38 :                     conn->auth_required = false;
    1383          38 :                     conn->allowed_auth_methods = -1;
    1384             :                 }
    1385          26 :                 else if (!negated)
    1386             :                 {
    1387           2 :                     conn->status = CONNECTION_BAD;
    1388           2 :                     libpq_append_conn_error(conn, "negative require_auth method \"%s\" cannot be mixed with non-negative methods",
    1389             :                                             method);
    1390             : 
    1391           2 :                     free(part);
    1392          14 :                     return false;
    1393             :                 }
    1394             : 
    1395          62 :                 negated = true;
    1396          62 :                 method++;
    1397             :             }
    1398          88 :             else if (negated)
    1399             :             {
    1400           2 :                 conn->status = CONNECTION_BAD;
    1401           2 :                 libpq_append_conn_error(conn, "require_auth method \"%s\" cannot be mixed with negative methods",
    1402             :                                         method);
    1403             : 
    1404           2 :                 free(part);
    1405           2 :                 return false;
    1406             :             }
    1407             : 
    1408         148 :             if (strcmp(method, "password") == 0)
    1409             :             {
    1410          40 :                 bits = (1 << AUTH_REQ_PASSWORD);
    1411             :             }
    1412         108 :             else if (strcmp(method, "md5") == 0)
    1413             :             {
    1414          32 :                 bits = (1 << AUTH_REQ_MD5);
    1415             :             }
    1416          76 :             else if (strcmp(method, "gss") == 0)
    1417             :             {
    1418           4 :                 bits = (1 << AUTH_REQ_GSS);
    1419           4 :                 bits |= (1 << AUTH_REQ_GSS_CONT);
    1420             :             }
    1421          72 :             else if (strcmp(method, "sspi") == 0)
    1422             :             {
    1423           4 :                 bits = (1 << AUTH_REQ_SSPI);
    1424           4 :                 bits |= (1 << AUTH_REQ_GSS_CONT);
    1425             :             }
    1426          68 :             else if (strcmp(method, "scram-sha-256") == 0)
    1427             :             {
    1428             :                 /* This currently assumes that SCRAM is the only SASL method. */
    1429          38 :                 bits = (1 << AUTH_REQ_SASL);
    1430          38 :                 bits |= (1 << AUTH_REQ_SASL_CONT);
    1431          38 :                 bits |= (1 << AUTH_REQ_SASL_FIN);
    1432             :             }
    1433          30 :             else if (strcmp(method, "none") == 0)
    1434             :             {
    1435             :                 /*
    1436             :                  * Special case: let the user explicitly allow (or disallow)
    1437             :                  * connections where the server does not send an explicit
    1438             :                  * authentication challenge, such as "trust" and "cert" auth.
    1439             :                  */
    1440          28 :                 if (negated)    /* "!none" */
    1441             :                 {
    1442          14 :                     if (conn->auth_required)
    1443           2 :                         goto duplicate;
    1444             : 
    1445          12 :                     conn->auth_required = true;
    1446             :                 }
    1447             :                 else            /* "none" */
    1448             :                 {
    1449          14 :                     if (!conn->auth_required)
    1450           2 :                         goto duplicate;
    1451             : 
    1452          12 :                     conn->auth_required = false;
    1453             :                 }
    1454             : 
    1455          24 :                 free(part);
    1456          24 :                 continue;       /* avoid the bitmask manipulation below */
    1457             :             }
    1458             :             else
    1459             :             {
    1460           2 :                 conn->status = CONNECTION_BAD;
    1461           2 :                 libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1462             :                                         "require_auth", method);
    1463             : 
    1464           2 :                 free(part);
    1465           2 :                 return false;
    1466             :             }
    1467             : 
    1468             :             /* Update the bitmask. */
    1469         118 :             if (negated)
    1470             :             {
    1471          48 :                 if ((conn->allowed_auth_methods & bits) == 0)
    1472           2 :                     goto duplicate;
    1473             : 
    1474          46 :                 conn->allowed_auth_methods &= ~bits;
    1475             :             }
    1476             :             else
    1477             :             {
    1478          70 :                 if ((conn->allowed_auth_methods & bits) == bits)
    1479           2 :                     goto duplicate;
    1480             : 
    1481          68 :                 conn->allowed_auth_methods |= bits;
    1482             :             }
    1483             : 
    1484         114 :             free(part);
    1485         114 :             continue;
    1486             : 
    1487           8 :     duplicate:
    1488             : 
    1489             :             /*
    1490             :              * A duplicated method probably indicates a typo in a setting
    1491             :              * where typos are extremely risky.
    1492             :              */
    1493           8 :             conn->status = CONNECTION_BAD;
    1494           8 :             libpq_append_conn_error(conn, "require_auth method \"%s\" is specified more than once",
    1495             :                                     part);
    1496             : 
    1497           8 :             free(part);
    1498           8 :             return false;
    1499             :         }
    1500             :     }
    1501             : 
    1502             :     /*
    1503             :      * validate channel_binding option
    1504             :      */
    1505       26552 :     if (conn->channel_binding)
    1506             :     {
    1507       26552 :         if (strcmp(conn->channel_binding, "disable") != 0
    1508       26548 :             && strcmp(conn->channel_binding, "prefer") != 0
    1509          18 :             && strcmp(conn->channel_binding, "require") != 0)
    1510             :         {
    1511           2 :             conn->status = CONNECTION_BAD;
    1512           2 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1513             :                                     "channel_binding", conn->channel_binding);
    1514           2 :             return false;
    1515             :         }
    1516             :     }
    1517             :     else
    1518             :     {
    1519           0 :         conn->channel_binding = strdup(DefaultChannelBinding);
    1520           0 :         if (!conn->channel_binding)
    1521           0 :             goto oom_error;
    1522             :     }
    1523             : 
    1524             : #ifndef USE_SSL
    1525             : 
    1526             :     /*
    1527             :      * sslrootcert=system is not supported. Since setting this changes the
    1528             :      * default sslmode, check this _before_ we validate sslmode, to avoid
    1529             :      * confusing the user with errors for an option they may not have set.
    1530             :      */
    1531             :     if (conn->sslrootcert
    1532             :         && strcmp(conn->sslrootcert, "system") == 0)
    1533             :     {
    1534             :         conn->status = CONNECTION_BAD;
    1535             :         libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
    1536             :                                 "sslrootcert", conn->sslrootcert);
    1537             :         return false;
    1538             :     }
    1539             : #endif
    1540             : 
    1541             :     /*
    1542             :      * validate sslmode option
    1543             :      */
    1544       26550 :     if (conn->sslmode)
    1545             :     {
    1546       26550 :         if (strcmp(conn->sslmode, "disable") != 0
    1547       26508 :             && strcmp(conn->sslmode, "allow") != 0
    1548       26484 :             && strcmp(conn->sslmode, "prefer") != 0
    1549         254 :             && strcmp(conn->sslmode, "require") != 0
    1550         112 :             && strcmp(conn->sslmode, "verify-ca") != 0
    1551          78 :             && strcmp(conn->sslmode, "verify-full") != 0)
    1552             :         {
    1553           0 :             conn->status = CONNECTION_BAD;
    1554           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1555             :                                     "sslmode", conn->sslmode);
    1556           0 :             return false;
    1557             :         }
    1558             : 
    1559             : #ifndef USE_SSL
    1560             :         switch (conn->sslmode[0])
    1561             :         {
    1562             :             case 'a':           /* "allow" */
    1563             :             case 'p':           /* "prefer" */
    1564             : 
    1565             :                 /*
    1566             :                  * warn user that an SSL connection will never be negotiated
    1567             :                  * since SSL was not compiled in?
    1568             :                  */
    1569             :                 break;
    1570             : 
    1571             :             case 'r':           /* "require" */
    1572             :             case 'v':           /* "verify-ca" or "verify-full" */
    1573             :                 conn->status = CONNECTION_BAD;
    1574             :                 libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
    1575             :                                         "sslmode", conn->sslmode);
    1576             :                 return false;
    1577             :         }
    1578             : #endif
    1579             :     }
    1580             :     else
    1581             :     {
    1582           0 :         conn->sslmode = strdup(DefaultSSLMode);
    1583           0 :         if (!conn->sslmode)
    1584           0 :             goto oom_error;
    1585             :     }
    1586             : 
    1587             :     /*
    1588             :      * validate sslnegotiation option, default is "postgres" for the postgres
    1589             :      * style negotiated connection with an extra round trip but more options.
    1590             :      */
    1591       26550 :     if (conn->sslnegotiation)
    1592             :     {
    1593       26550 :         if (strcmp(conn->sslnegotiation, "postgres") != 0
    1594          48 :             && strcmp(conn->sslnegotiation, "direct") != 0)
    1595             :         {
    1596           0 :             conn->status = CONNECTION_BAD;
    1597           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1598             :                                     "sslnegotiation", conn->sslnegotiation);
    1599           0 :             return false;
    1600             :         }
    1601             : 
    1602             : #ifndef USE_SSL
    1603             :         if (conn->sslnegotiation[0] != 'p')
    1604             :         {
    1605             :             conn->status = CONNECTION_BAD;
    1606             :             libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
    1607             :                                     "sslnegotiation", conn->sslnegotiation);
    1608             :             return false;
    1609             :         }
    1610             : #endif
    1611             : 
    1612             :         /*
    1613             :          * Don't allow direct SSL negotiation with sslmode='prefer', because
    1614             :          * that poses a risk of unintentional fallback to plaintext connection
    1615             :          * when connecting to a pre-v17 server that does not support direct
    1616             :          * SSL connections. To keep things simple, don't allow it with
    1617             :          * sslmode='allow' or sslmode='disable' either. If a user goes through
    1618             :          * the trouble of setting sslnegotiation='direct', they probably
    1619             :          * intend to use SSL, and sslmode=disable or allow is probably a user
    1620             :          * user mistake anyway.
    1621             :          */
    1622       26550 :         if (conn->sslnegotiation[0] == 'd' &&
    1623          48 :             conn->sslmode[0] != 'r' && conn->sslmode[0] != 'v')
    1624             :         {
    1625          36 :             conn->status = CONNECTION_BAD;
    1626          36 :             libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslnegotiation=direct (use \"require\", \"verify-ca\", or \"verify-full\")",
    1627             :                                     conn->sslmode);
    1628          36 :             return false;
    1629             :         }
    1630             :     }
    1631             :     else
    1632             :     {
    1633           0 :         conn->sslnegotiation = strdup(DefaultSSLNegotiation);
    1634           0 :         if (!conn->sslnegotiation)
    1635           0 :             goto oom_error;
    1636             :     }
    1637             : 
    1638             : #ifdef USE_SSL
    1639             : 
    1640             :     /*
    1641             :      * If sslrootcert=system, make sure our chosen sslmode is compatible.
    1642             :      */
    1643       26514 :     if (conn->sslrootcert
    1644         242 :         && strcmp(conn->sslrootcert, "system") == 0
    1645           8 :         && strcmp(conn->sslmode, "verify-full") != 0)
    1646             :     {
    1647           2 :         conn->status = CONNECTION_BAD;
    1648           2 :         libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslrootcert=system (use \"verify-full\")",
    1649             :                                 conn->sslmode);
    1650           2 :         return false;
    1651             :     }
    1652             : #endif
    1653             : 
    1654             :     /*
    1655             :      * Validate TLS protocol versions for ssl_min_protocol_version and
    1656             :      * ssl_max_protocol_version.
    1657             :      */
    1658       26512 :     if (!sslVerifyProtocolVersion(conn->ssl_min_protocol_version))
    1659             :     {
    1660           2 :         conn->status = CONNECTION_BAD;
    1661           2 :         libpq_append_conn_error(conn, "invalid \"%s\" value: \"%s\"",
    1662             :                                 "ssl_min_protocol_version",
    1663             :                                 conn->ssl_min_protocol_version);
    1664           2 :         return false;
    1665             :     }
    1666       26510 :     if (!sslVerifyProtocolVersion(conn->ssl_max_protocol_version))
    1667             :     {
    1668           2 :         conn->status = CONNECTION_BAD;
    1669           2 :         libpq_append_conn_error(conn, "invalid \"%s\" value: \"%s\"",
    1670             :                                 "ssl_max_protocol_version",
    1671             :                                 conn->ssl_max_protocol_version);
    1672           2 :         return false;
    1673             :     }
    1674             : 
    1675             :     /*
    1676             :      * Check if the range of SSL protocols defined is correct.  This is done
    1677             :      * at this early step because this is independent of the SSL
    1678             :      * implementation used, and this avoids unnecessary cycles with an
    1679             :      * already-built SSL context when the connection is being established, as
    1680             :      * it would be doomed anyway.
    1681             :      */
    1682       26508 :     if (!sslVerifyProtocolRange(conn->ssl_min_protocol_version,
    1683       26508 :                                 conn->ssl_max_protocol_version))
    1684             :     {
    1685           2 :         conn->status = CONNECTION_BAD;
    1686           2 :         libpq_append_conn_error(conn, "invalid SSL protocol version range");
    1687           2 :         return false;
    1688             :     }
    1689             : 
    1690             :     /*
    1691             :      * validate sslcertmode option
    1692             :      */
    1693       26506 :     if (conn->sslcertmode)
    1694             :     {
    1695         344 :         if (strcmp(conn->sslcertmode, "disable") != 0 &&
    1696         338 :             strcmp(conn->sslcertmode, "allow") != 0 &&
    1697           6 :             strcmp(conn->sslcertmode, "require") != 0)
    1698             :         {
    1699           0 :             conn->status = CONNECTION_BAD;
    1700           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1701             :                                     "sslcertmode", conn->sslcertmode);
    1702           0 :             return false;
    1703             :         }
    1704             : #ifndef USE_SSL
    1705             :         if (strcmp(conn->sslcertmode, "require") == 0)
    1706             :         {
    1707             :             conn->status = CONNECTION_BAD;
    1708             :             libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in",
    1709             :                                     "sslcertmode", conn->sslcertmode);
    1710             :             return false;
    1711             :         }
    1712             : #endif
    1713             : #ifndef HAVE_SSL_CTX_SET_CERT_CB
    1714             : 
    1715             :         /*
    1716             :          * Without a certificate callback, the current implementation can't
    1717             :          * figure out if a certificate was actually requested, so "require" is
    1718             :          * useless.
    1719             :          */
    1720             :         if (strcmp(conn->sslcertmode, "require") == 0)
    1721             :         {
    1722             :             conn->status = CONNECTION_BAD;
    1723             :             libpq_append_conn_error(conn, "%s value \"%s\" is not supported (check OpenSSL version)",
    1724             :                                     "sslcertmode", conn->sslcertmode);
    1725             :             return false;
    1726             :         }
    1727             : #endif
    1728             :     }
    1729             :     else
    1730             :     {
    1731       26162 :         conn->sslcertmode = strdup(DefaultSSLCertMode);
    1732       26162 :         if (!conn->sslcertmode)
    1733           0 :             goto oom_error;
    1734             :     }
    1735             : 
    1736             :     /*
    1737             :      * validate gssencmode option
    1738             :      */
    1739       26506 :     if (conn->gssencmode)
    1740             :     {
    1741       26506 :         if (strcmp(conn->gssencmode, "disable") != 0 &&
    1742          24 :             strcmp(conn->gssencmode, "prefer") != 0 &&
    1743          12 :             strcmp(conn->gssencmode, "require") != 0)
    1744             :         {
    1745           0 :             conn->status = CONNECTION_BAD;
    1746           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"", "gssencmode", conn->gssencmode);
    1747           0 :             return false;
    1748             :         }
    1749             : #ifndef ENABLE_GSS
    1750       26506 :         if (strcmp(conn->gssencmode, "require") == 0)
    1751             :         {
    1752          12 :             conn->status = CONNECTION_BAD;
    1753          12 :             libpq_append_conn_error(conn, "gssencmode value \"%s\" invalid when GSSAPI support is not compiled in",
    1754             :                                     conn->gssencmode);
    1755          12 :             return false;
    1756             :         }
    1757             : #endif
    1758             :     }
    1759             :     else
    1760             :     {
    1761           0 :         conn->gssencmode = strdup(DefaultGSSMode);
    1762           0 :         if (!conn->gssencmode)
    1763           0 :             goto oom_error;
    1764             :     }
    1765             : 
    1766             :     /*
    1767             :      * validate target_session_attrs option, and set target_server_type
    1768             :      */
    1769       26494 :     if (conn->target_session_attrs)
    1770             :     {
    1771       26494 :         if (strcmp(conn->target_session_attrs, "any") == 0)
    1772       26464 :             conn->target_server_type = SERVER_TYPE_ANY;
    1773          30 :         else if (strcmp(conn->target_session_attrs, "read-write") == 0)
    1774           6 :             conn->target_server_type = SERVER_TYPE_READ_WRITE;
    1775          24 :         else if (strcmp(conn->target_session_attrs, "read-only") == 0)
    1776           6 :             conn->target_server_type = SERVER_TYPE_READ_ONLY;
    1777          18 :         else if (strcmp(conn->target_session_attrs, "primary") == 0)
    1778           6 :             conn->target_server_type = SERVER_TYPE_PRIMARY;
    1779          12 :         else if (strcmp(conn->target_session_attrs, "standby") == 0)
    1780           6 :             conn->target_server_type = SERVER_TYPE_STANDBY;
    1781           6 :         else if (strcmp(conn->target_session_attrs, "prefer-standby") == 0)
    1782           6 :             conn->target_server_type = SERVER_TYPE_PREFER_STANDBY;
    1783             :         else
    1784             :         {
    1785           0 :             conn->status = CONNECTION_BAD;
    1786           0 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1787             :                                     "target_session_attrs",
    1788             :                                     conn->target_session_attrs);
    1789           0 :             return false;
    1790             :         }
    1791             :     }
    1792             :     else
    1793           0 :         conn->target_server_type = SERVER_TYPE_ANY;
    1794             : 
    1795             :     /*
    1796             :      * validate load_balance_hosts option, and set load_balance_type
    1797             :      */
    1798       26494 :     if (conn->load_balance_hosts)
    1799             :     {
    1800       26494 :         if (strcmp(conn->load_balance_hosts, "disable") == 0)
    1801       26382 :             conn->load_balance_type = LOAD_BALANCE_DISABLE;
    1802         112 :         else if (strcmp(conn->load_balance_hosts, "random") == 0)
    1803         110 :             conn->load_balance_type = LOAD_BALANCE_RANDOM;
    1804             :         else
    1805             :         {
    1806           2 :             conn->status = CONNECTION_BAD;
    1807           2 :             libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
    1808             :                                     "load_balance_hosts",
    1809             :                                     conn->load_balance_hosts);
    1810           2 :             return false;
    1811             :         }
    1812             :     }
    1813             :     else
    1814           0 :         conn->load_balance_type = LOAD_BALANCE_DISABLE;
    1815             : 
    1816       26492 :     if (conn->load_balance_type == LOAD_BALANCE_RANDOM)
    1817             :     {
    1818         110 :         libpq_prng_init(conn);
    1819             : 
    1820             :         /*
    1821             :          * This is the "inside-out" variant of the Fisher-Yates shuffle
    1822             :          * algorithm. Notionally, we append each new value to the array and
    1823             :          * then swap it with a randomly-chosen array element (possibly
    1824             :          * including itself, else we fail to generate permutations with the
    1825             :          * last integer last).  The swap step can be optimized by combining it
    1826             :          * with the insertion.
    1827             :          */
    1828         330 :         for (i = 1; i < conn->nconnhost; i++)
    1829             :         {
    1830         220 :             int         j = pg_prng_uint64_range(&conn->prng_state, 0, i);
    1831         220 :             pg_conn_host temp = conn->connhost[j];
    1832             : 
    1833         220 :             conn->connhost[j] = conn->connhost[i];
    1834         220 :             conn->connhost[i] = temp;
    1835             :         }
    1836             :     }
    1837             : 
    1838             :     /*
    1839             :      * Resolve special "auto" client_encoding from the locale
    1840             :      */
    1841       26492 :     if (conn->client_encoding_initial &&
    1842        1452 :         strcmp(conn->client_encoding_initial, "auto") == 0)
    1843             :     {
    1844           4 :         free(conn->client_encoding_initial);
    1845           4 :         conn->client_encoding_initial = strdup(pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true)));
    1846           4 :         if (!conn->client_encoding_initial)
    1847           0 :             goto oom_error;
    1848             :     }
    1849             : 
    1850             :     /*
    1851             :      * Only if we get this far is it appropriate to try to connect. (We need a
    1852             :      * state flag, rather than just the boolean result of this function, in
    1853             :      * case someone tries to PQreset() the PGconn.)
    1854             :      */
    1855       26492 :     conn->options_valid = true;
    1856             : 
    1857       26492 :     return true;
    1858             : 
    1859           0 : oom_error:
    1860           0 :     conn->status = CONNECTION_BAD;
    1861           0 :     libpq_append_conn_error(conn, "out of memory");
    1862           0 :     return false;
    1863             : }
    1864             : 
    1865             : /*
    1866             :  *      PQconndefaults
    1867             :  *
    1868             :  * Construct a default connection options array, which identifies all the
    1869             :  * available options and shows any default values that are available from the
    1870             :  * environment etc.  On error (eg out of memory), NULL is returned.
    1871             :  *
    1872             :  * Using this function, an application may determine all possible options
    1873             :  * and their current default values.
    1874             :  *
    1875             :  * NOTE: as of PostgreSQL 7.0, the returned array is dynamically allocated
    1876             :  * and should be freed when no longer needed via PQconninfoFree().  (In prior
    1877             :  * versions, the returned array was static, but that's not thread-safe.)
    1878             :  * Pre-7.0 applications that use this function will see a small memory leak
    1879             :  * until they are updated to call PQconninfoFree.
    1880             :  */
    1881             : PQconninfoOption *
    1882         146 : PQconndefaults(void)
    1883             : {
    1884             :     PQExpBufferData errorBuf;
    1885             :     PQconninfoOption *connOptions;
    1886             : 
    1887             :     /* We don't actually report any errors here, but callees want a buffer */
    1888         146 :     initPQExpBuffer(&errorBuf);
    1889         146 :     if (PQExpBufferDataBroken(errorBuf))
    1890           0 :         return NULL;            /* out of memory already :-( */
    1891             : 
    1892         146 :     connOptions = conninfo_init(&errorBuf);
    1893         146 :     if (connOptions != NULL)
    1894             :     {
    1895             :         /* pass NULL errorBuf to ignore errors */
    1896         146 :         if (!conninfo_add_defaults(connOptions, NULL))
    1897             :         {
    1898           0 :             PQconninfoFree(connOptions);
    1899           0 :             connOptions = NULL;
    1900             :         }
    1901             :     }
    1902             : 
    1903         146 :     termPQExpBuffer(&errorBuf);
    1904         146 :     return connOptions;
    1905             : }
    1906             : 
    1907             : /* ----------------
    1908             :  *      PQsetdbLogin
    1909             :  *
    1910             :  * establishes a connection to a postgres backend through the postmaster
    1911             :  * at the specified host and port.
    1912             :  *
    1913             :  * returns a PGconn* which is needed for all subsequent libpq calls
    1914             :  *
    1915             :  * if the status field of the connection returned is CONNECTION_BAD,
    1916             :  * then only the errorMessage is likely to be useful.
    1917             :  * ----------------
    1918             :  */
    1919             : PGconn *
    1920           0 : PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
    1921             :              const char *pgtty, const char *dbName, const char *login,
    1922             :              const char *pwd)
    1923             : {
    1924             :     PGconn     *conn;
    1925             : 
    1926             :     /*
    1927             :      * Allocate memory for the conn structure.  Note that we also expect this
    1928             :      * to initialize conn->errorMessage to empty.  All subsequent steps during
    1929             :      * connection initialization will only append to that buffer.
    1930             :      */
    1931           0 :     conn = pqMakeEmptyPGconn();
    1932           0 :     if (conn == NULL)
    1933           0 :         return NULL;
    1934             : 
    1935             :     /*
    1936             :      * If the dbName parameter contains what looks like a connection string,
    1937             :      * parse it into conn struct using connectOptions1.
    1938             :      */
    1939           0 :     if (dbName && recognized_connection_string(dbName))
    1940             :     {
    1941           0 :         if (!connectOptions1(conn, dbName))
    1942           0 :             return conn;
    1943             :     }
    1944             :     else
    1945             :     {
    1946             :         /*
    1947             :          * Old-style path: first, parse an empty conninfo string in order to
    1948             :          * set up the same defaults that PQconnectdb() would use.
    1949             :          */
    1950           0 :         if (!connectOptions1(conn, ""))
    1951           0 :             return conn;
    1952             : 
    1953             :         /* Insert dbName parameter value into struct */
    1954           0 :         if (dbName && dbName[0] != '\0')
    1955             :         {
    1956           0 :             free(conn->dbName);
    1957           0 :             conn->dbName = strdup(dbName);
    1958           0 :             if (!conn->dbName)
    1959           0 :                 goto oom_error;
    1960             :         }
    1961             :     }
    1962             : 
    1963             :     /*
    1964             :      * Insert remaining parameters into struct, overriding defaults (as well
    1965             :      * as any conflicting data from dbName taken as a conninfo).
    1966             :      */
    1967           0 :     if (pghost && pghost[0] != '\0')
    1968             :     {
    1969           0 :         free(conn->pghost);
    1970           0 :         conn->pghost = strdup(pghost);
    1971           0 :         if (!conn->pghost)
    1972           0 :             goto oom_error;
    1973             :     }
    1974             : 
    1975           0 :     if (pgport && pgport[0] != '\0')
    1976             :     {
    1977           0 :         free(conn->pgport);
    1978           0 :         conn->pgport = strdup(pgport);
    1979           0 :         if (!conn->pgport)
    1980           0 :             goto oom_error;
    1981             :     }
    1982             : 
    1983           0 :     if (pgoptions && pgoptions[0] != '\0')
    1984             :     {
    1985           0 :         free(conn->pgoptions);
    1986           0 :         conn->pgoptions = strdup(pgoptions);
    1987           0 :         if (!conn->pgoptions)
    1988           0 :             goto oom_error;
    1989             :     }
    1990             : 
    1991           0 :     if (login && login[0] != '\0')
    1992             :     {
    1993           0 :         free(conn->pguser);
    1994           0 :         conn->pguser = strdup(login);
    1995           0 :         if (!conn->pguser)
    1996           0 :             goto oom_error;
    1997             :     }
    1998             : 
    1999           0 :     if (pwd && pwd[0] != '\0')
    2000             :     {
    2001           0 :         free(conn->pgpass);
    2002           0 :         conn->pgpass = strdup(pwd);
    2003           0 :         if (!conn->pgpass)
    2004           0 :             goto oom_error;
    2005             :     }
    2006             : 
    2007             :     /*
    2008             :      * Compute derived options
    2009             :      */
    2010           0 :     if (!pqConnectOptions2(conn))
    2011           0 :         return conn;
    2012             : 
    2013             :     /*
    2014             :      * Connect to the database
    2015             :      */
    2016           0 :     if (pqConnectDBStart(conn))
    2017           0 :         (void) pqConnectDBComplete(conn);
    2018             : 
    2019           0 :     return conn;
    2020             : 
    2021           0 : oom_error:
    2022           0 :     conn->status = CONNECTION_BAD;
    2023           0 :     libpq_append_conn_error(conn, "out of memory");
    2024           0 :     return conn;
    2025             : }
    2026             : 
    2027             : 
    2028             : /* ----------
    2029             :  * connectNoDelay -
    2030             :  * Sets the TCP_NODELAY socket option.
    2031             :  * Returns 1 if successful, 0 if not.
    2032             :  * ----------
    2033             :  */
    2034             : static int
    2035         590 : connectNoDelay(PGconn *conn)
    2036             : {
    2037             : #ifdef  TCP_NODELAY
    2038         590 :     int         on = 1;
    2039             : 
    2040         590 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY,
    2041             :                    (char *) &on,
    2042             :                    sizeof(on)) < 0)
    2043             :     {
    2044             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    2045             : 
    2046           0 :         libpq_append_conn_error(conn, "could not set socket to TCP no delay mode: %s",
    2047           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2048           0 :         return 0;
    2049             :     }
    2050             : #endif
    2051             : 
    2052         590 :     return 1;
    2053             : }
    2054             : 
    2055             : /* ----------
    2056             :  * Write currently connected IP address into host_addr (of len host_addr_len).
    2057             :  * If unable to, set it to the empty string.
    2058             :  * ----------
    2059             :  */
    2060             : static void
    2061       26532 : getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
    2062             : {
    2063       26532 :     struct sockaddr_storage *addr = &conn->raddr.addr;
    2064             : 
    2065       26532 :     if (addr->ss_family == AF_INET)
    2066             :     {
    2067         300 :         if (pg_inet_net_ntop(AF_INET,
    2068         300 :                              &((struct sockaddr_in *) addr)->sin_addr.s_addr,
    2069             :                              32,
    2070             :                              host_addr, host_addr_len) == NULL)
    2071           0 :             host_addr[0] = '\0';
    2072             :     }
    2073       26232 :     else if (addr->ss_family == AF_INET6)
    2074             :     {
    2075         290 :         if (pg_inet_net_ntop(AF_INET6,
    2076         290 :                              &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
    2077             :                              128,
    2078             :                              host_addr, host_addr_len) == NULL)
    2079           0 :             host_addr[0] = '\0';
    2080             :     }
    2081             :     else
    2082       25942 :         host_addr[0] = '\0';
    2083       26532 : }
    2084             : 
    2085             : /*
    2086             :  * emitHostIdentityInfo -
    2087             :  * Speculatively append "connection to server so-and-so failed: " to
    2088             :  * conn->errorMessage once we've identified the current connection target
    2089             :  * address.  This ensures that any subsequent error message will be properly
    2090             :  * attributed to the server we couldn't connect to.  conn->raddr must be
    2091             :  * valid, and the result of getHostaddr() must be supplied.
    2092             :  */
    2093             : static void
    2094       26532 : emitHostIdentityInfo(PGconn *conn, const char *host_addr)
    2095             : {
    2096       26532 :     if (conn->raddr.addr.ss_family == AF_UNIX)
    2097             :     {
    2098             :         char        service[NI_MAXHOST];
    2099             : 
    2100       25942 :         pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen,
    2101             :                            NULL, 0,
    2102             :                            service, sizeof(service),
    2103             :                            NI_NUMERICSERV);
    2104       25942 :         appendPQExpBuffer(&conn->errorMessage,
    2105       25942 :                           libpq_gettext("connection to server on socket \"%s\" failed: "),
    2106             :                           service);
    2107             :     }
    2108             :     else
    2109             :     {
    2110             :         const char *displayed_host;
    2111             :         const char *displayed_port;
    2112             : 
    2113             :         /* To which host and port were we actually connecting? */
    2114         590 :         if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
    2115         296 :             displayed_host = conn->connhost[conn->whichhost].hostaddr;
    2116             :         else
    2117         294 :             displayed_host = conn->connhost[conn->whichhost].host;
    2118         590 :         displayed_port = conn->connhost[conn->whichhost].port;
    2119         590 :         if (displayed_port == NULL || displayed_port[0] == '\0')
    2120           0 :             displayed_port = DEF_PGPORT_STR;
    2121             : 
    2122             :         /*
    2123             :          * If the user did not supply an IP address using 'hostaddr', and
    2124             :          * 'host' was missing or does not match our lookup, display the
    2125             :          * looked-up IP address.
    2126             :          */
    2127         590 :         if (conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS &&
    2128         294 :             host_addr[0] &&
    2129         294 :             strcmp(displayed_host, host_addr) != 0)
    2130         292 :             appendPQExpBuffer(&conn->errorMessage,
    2131         292 :                               libpq_gettext("connection to server at \"%s\" (%s), port %s failed: "),
    2132             :                               displayed_host, host_addr,
    2133             :                               displayed_port);
    2134             :         else
    2135         298 :             appendPQExpBuffer(&conn->errorMessage,
    2136         298 :                               libpq_gettext("connection to server at \"%s\", port %s failed: "),
    2137             :                               displayed_host,
    2138             :                               displayed_port);
    2139             :     }
    2140       26532 : }
    2141             : 
    2142             : /* ----------
    2143             :  * connectFailureMessage -
    2144             :  * create a friendly error message on connection failure,
    2145             :  * using the given errno value.  Use this for error cases that
    2146             :  * imply that there's no server there.
    2147             :  * ----------
    2148             :  */
    2149             : static void
    2150         418 : connectFailureMessage(PGconn *conn, int errorno)
    2151             : {
    2152             :     char        sebuf[PG_STRERROR_R_BUFLEN];
    2153             : 
    2154         418 :     appendPQExpBuffer(&conn->errorMessage,
    2155             :                       "%s\n",
    2156             :                       SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
    2157             : 
    2158         418 :     if (conn->raddr.addr.ss_family == AF_UNIX)
    2159         412 :         libpq_append_conn_error(conn, "\tIs the server running locally and accepting connections on that socket?");
    2160             :     else
    2161           6 :         libpq_append_conn_error(conn, "\tIs the server running on that host and accepting TCP/IP connections?");
    2162         418 : }
    2163             : 
    2164             : /*
    2165             :  * Should we use keepalives?  Returns 1 if yes, 0 if no, and -1 if
    2166             :  * conn->keepalives is set to a value which is not parseable as an
    2167             :  * integer.
    2168             :  */
    2169             : static int
    2170         590 : useKeepalives(PGconn *conn)
    2171             : {
    2172             :     int         val;
    2173             : 
    2174         590 :     if (conn->keepalives == NULL)
    2175         590 :         return 1;
    2176             : 
    2177           0 :     if (!pqParseIntParam(conn->keepalives, &val, conn, "keepalives"))
    2178           0 :         return -1;
    2179             : 
    2180           0 :     return val != 0 ? 1 : 0;
    2181             : }
    2182             : 
    2183             : #ifndef WIN32
    2184             : /*
    2185             :  * Set the keepalive idle timer.
    2186             :  */
    2187             : static int
    2188         590 : setKeepalivesIdle(PGconn *conn)
    2189             : {
    2190             :     int         idle;
    2191             : 
    2192         590 :     if (conn->keepalives_idle == NULL)
    2193         590 :         return 1;
    2194             : 
    2195           0 :     if (!pqParseIntParam(conn->keepalives_idle, &idle, conn,
    2196             :                          "keepalives_idle"))
    2197           0 :         return 0;
    2198           0 :     if (idle < 0)
    2199           0 :         idle = 0;
    2200             : 
    2201             : #ifdef PG_TCP_KEEPALIVE_IDLE
    2202           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE,
    2203             :                    (char *) &idle, sizeof(idle)) < 0)
    2204             :     {
    2205             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    2206             : 
    2207           0 :         libpq_append_conn_error(conn, "%s(%s) failed: %s",
    2208             :                                 "setsockopt",
    2209             :                                 PG_TCP_KEEPALIVE_IDLE_STR,
    2210           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2211           0 :         return 0;
    2212             :     }
    2213             : #endif
    2214             : 
    2215           0 :     return 1;
    2216             : }
    2217             : 
    2218             : /*
    2219             :  * Set the keepalive interval.
    2220             :  */
    2221             : static int
    2222         590 : setKeepalivesInterval(PGconn *conn)
    2223             : {
    2224             :     int         interval;
    2225             : 
    2226         590 :     if (conn->keepalives_interval == NULL)
    2227         590 :         return 1;
    2228             : 
    2229           0 :     if (!pqParseIntParam(conn->keepalives_interval, &interval, conn,
    2230             :                          "keepalives_interval"))
    2231           0 :         return 0;
    2232           0 :     if (interval < 0)
    2233           0 :         interval = 0;
    2234             : 
    2235             : #ifdef TCP_KEEPINTVL
    2236           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPINTVL,
    2237             :                    (char *) &interval, sizeof(interval)) < 0)
    2238             :     {
    2239             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    2240             : 
    2241           0 :         libpq_append_conn_error(conn, "%s(%s) failed: %s",
    2242             :                                 "setsockopt",
    2243             :                                 "TCP_KEEPINTVL",
    2244           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2245           0 :         return 0;
    2246             :     }
    2247             : #endif
    2248             : 
    2249           0 :     return 1;
    2250             : }
    2251             : 
    2252             : /*
    2253             :  * Set the count of lost keepalive packets that will trigger a connection
    2254             :  * break.
    2255             :  */
    2256             : static int
    2257         590 : setKeepalivesCount(PGconn *conn)
    2258             : {
    2259             :     int         count;
    2260             : 
    2261         590 :     if (conn->keepalives_count == NULL)
    2262         590 :         return 1;
    2263             : 
    2264           0 :     if (!pqParseIntParam(conn->keepalives_count, &count, conn,
    2265             :                          "keepalives_count"))
    2266           0 :         return 0;
    2267           0 :     if (count < 0)
    2268           0 :         count = 0;
    2269             : 
    2270             : #ifdef TCP_KEEPCNT
    2271           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPCNT,
    2272             :                    (char *) &count, sizeof(count)) < 0)
    2273             :     {
    2274             :         char        sebuf[PG_STRERROR_R_BUFLEN];
    2275             : 
    2276           0 :         libpq_append_conn_error(conn, "%s(%s) failed: %s",
    2277             :                                 "setsockopt",
    2278             :                                 "TCP_KEEPCNT",
    2279           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2280           0 :         return 0;
    2281             :     }
    2282             : #endif
    2283             : 
    2284           0 :     return 1;
    2285             : }
    2286             : #else                           /* WIN32 */
    2287             : #ifdef SIO_KEEPALIVE_VALS
    2288             : /*
    2289             :  * Enable keepalives and set the keepalive values on Win32,
    2290             :  * where they are always set in one batch.
    2291             :  *
    2292             :  * CAUTION: This needs to be signal safe, since it's used by PQcancel.
    2293             :  */
    2294             : int
    2295             : pqSetKeepalivesWin32(pgsocket sock, int idle, int interval)
    2296             : {
    2297             :     struct tcp_keepalive ka;
    2298             :     DWORD       retsize;
    2299             : 
    2300             :     if (idle <= 0)
    2301             :         idle = 2 * 60 * 60;     /* 2 hours = default */
    2302             :     if (interval <= 0)
    2303             :         interval = 1;           /* 1 second = default */
    2304             : 
    2305             :     ka.onoff = 1;
    2306             :     ka.keepalivetime = idle * 1000;
    2307             :     ka.keepaliveinterval = interval * 1000;
    2308             : 
    2309             :     if (WSAIoctl(sock,
    2310             :                  SIO_KEEPALIVE_VALS,
    2311             :                  (LPVOID) &ka,
    2312             :                  sizeof(ka),
    2313             :                  NULL,
    2314             :                  0,
    2315             :                  &retsize,
    2316             :                  NULL,
    2317             :                  NULL)
    2318             :         != 0)
    2319             :         return 0;
    2320             :     return 1;
    2321             : }
    2322             : 
    2323             : static int
    2324             : prepKeepalivesWin32(PGconn *conn)
    2325             : {
    2326             :     int         idle = -1;
    2327             :     int         interval = -1;
    2328             : 
    2329             :     if (conn->keepalives_idle &&
    2330             :         !pqParseIntParam(conn->keepalives_idle, &idle, conn,
    2331             :                          "keepalives_idle"))
    2332             :         return 0;
    2333             :     if (conn->keepalives_interval &&
    2334             :         !pqParseIntParam(conn->keepalives_interval, &interval, conn,
    2335             :                          "keepalives_interval"))
    2336             :         return 0;
    2337             : 
    2338             :     if (!pqSetKeepalivesWin32(conn->sock, idle, interval))
    2339             :     {
    2340             :         libpq_append_conn_error(conn, "%s(%s) failed: error code %d",
    2341             :                                 "WSAIoctl", "SIO_KEEPALIVE_VALS",
    2342             :                                 WSAGetLastError());
    2343             :         return 0;
    2344             :     }
    2345             :     return 1;
    2346             : }
    2347             : #endif                          /* SIO_KEEPALIVE_VALS */
    2348             : #endif                          /* WIN32 */
    2349             : 
    2350             : /*
    2351             :  * Set the TCP user timeout.
    2352             :  */
    2353             : static int
    2354         590 : setTCPUserTimeout(PGconn *conn)
    2355             : {
    2356             :     int         timeout;
    2357             : 
    2358         590 :     if (conn->pgtcp_user_timeout == NULL)
    2359         590 :         return 1;
    2360             : 
    2361           0 :     if (!pqParseIntParam(conn->pgtcp_user_timeout, &timeout, conn,
    2362             :                          "tcp_user_timeout"))
    2363           0 :         return 0;
    2364             : 
    2365           0 :     if (timeout < 0)
    2366           0 :         timeout = 0;
    2367             : 
    2368             : #ifdef TCP_USER_TIMEOUT
    2369           0 :     if (setsockopt(conn->sock, IPPROTO_TCP, TCP_USER_TIMEOUT,
    2370             :                    (char *) &timeout, sizeof(timeout)) < 0)
    2371             :     {
    2372             :         char        sebuf[256];
    2373             : 
    2374           0 :         libpq_append_conn_error(conn, "%s(%s) failed: %s",
    2375             :                                 "setsockopt",
    2376             :                                 "TCP_USER_TIMEOUT",
    2377           0 :                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    2378           0 :         return 0;
    2379             :     }
    2380             : #endif
    2381             : 
    2382           0 :     return 1;
    2383             : }
    2384             : 
    2385             : /* ----------
    2386             :  * pqConnectDBStart -
    2387             :  *      Begin the process of making a connection to the backend.
    2388             :  *
    2389             :  * Returns 1 if successful, 0 if not.
    2390             :  * ----------
    2391             :  */
    2392             : int
    2393       26494 : pqConnectDBStart(PGconn *conn)
    2394             : {
    2395       26494 :     if (!conn)
    2396           0 :         return 0;
    2397             : 
    2398       26494 :     if (!conn->options_valid)
    2399           0 :         goto connect_errReturn;
    2400             : 
    2401             :     /*
    2402             :      * Check for bad linking to backend-internal versions of src/common
    2403             :      * functions (see comments in link-canary.c for the reason we need this).
    2404             :      * Nobody but developers should see this message, so we don't bother
    2405             :      * translating it.
    2406             :      */
    2407       26494 :     if (!pg_link_canary_is_frontend())
    2408             :     {
    2409           0 :         appendPQExpBufferStr(&conn->errorMessage,
    2410             :                              "libpq is incorrectly linked to backend functions\n");
    2411           0 :         goto connect_errReturn;
    2412             :     }
    2413             : 
    2414             :     /* Ensure our buffers are empty */
    2415       26494 :     conn->inStart = conn->inCursor = conn->inEnd = 0;
    2416       26494 :     conn->outCount = 0;
    2417             : 
    2418             :     /*
    2419             :      * Set up to try to connect to the first host.  (Setting whichhost = -1 is
    2420             :      * a bit of a cheat, but PQconnectPoll will advance it to 0 before
    2421             :      * anything else looks at it.)
    2422             :      *
    2423             :      * Cancel requests are special though, they should only try one host and
    2424             :      * address, and these fields have already been set up in PQcancelCreate,
    2425             :      * so leave these fields alone for cancel requests.
    2426             :      */
    2427       26494 :     if (!conn->cancelRequest)
    2428             :     {
    2429       26484 :         conn->whichhost = -1;
    2430       26484 :         conn->try_next_host = true;
    2431       26484 :         conn->try_next_addr = false;
    2432             :     }
    2433             : 
    2434       26494 :     conn->status = CONNECTION_NEEDED;
    2435             : 
    2436             :     /* Also reset the target_server_type state if needed */
    2437       26494 :     if (conn->target_server_type == SERVER_TYPE_PREFER_STANDBY_PASS2)
    2438           0 :         conn->target_server_type = SERVER_TYPE_PREFER_STANDBY;
    2439             : 
    2440             :     /*
    2441             :      * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(),
    2442             :      * so that it can easily be re-executed if needed again during the
    2443             :      * asynchronous startup process.  However, we must run it once here,
    2444             :      * because callers expect a success return from this routine to mean that
    2445             :      * we are in PGRES_POLLING_WRITING connection state.
    2446             :      */
    2447       26494 :     if (PQconnectPoll(conn) == PGRES_POLLING_WRITING)
    2448       26090 :         return 1;
    2449             : 
    2450         404 : connect_errReturn:
    2451             : 
    2452             :     /*
    2453             :      * If we managed to open a socket, close it immediately rather than
    2454             :      * waiting till PQfinish.  (The application cannot have gotten the socket
    2455             :      * from PQsocket yet, so this doesn't risk breaking anything.)
    2456             :      */
    2457         404 :     pqDropConnection(conn, true);
    2458         404 :     conn->status = CONNECTION_BAD;
    2459         404 :     return 0;
    2460             : }
    2461             : 
    2462             : 
    2463             : /*
    2464             :  *      pqConnectDBComplete
    2465             :  *
    2466             :  * Block and complete a connection.
    2467             :  *
    2468             :  * Returns 1 on success, 0 on failure.
    2469             :  */
    2470             : int
    2471       23968 : pqConnectDBComplete(PGconn *conn)
    2472             : {
    2473       23968 :     PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
    2474       23968 :     pg_usec_time_t end_time = -1;
    2475       23968 :     int         timeout = 0;
    2476       23968 :     int         last_whichhost = -2;    /* certainly different from whichhost */
    2477       23968 :     int         last_whichaddr = -2;    /* certainly different from whichaddr */
    2478             : 
    2479       23968 :     if (conn == NULL || conn->status == CONNECTION_BAD)
    2480           0 :         return 0;
    2481             : 
    2482             :     /*
    2483             :      * Set up a time limit, if connect_timeout is greater than zero.
    2484             :      */
    2485       23968 :     if (conn->connect_timeout != NULL)
    2486             :     {
    2487           8 :         if (!pqParseIntParam(conn->connect_timeout, &timeout, conn,
    2488             :                              "connect_timeout"))
    2489             :         {
    2490             :             /* mark the connection as bad to report the parsing failure */
    2491           0 :             conn->status = CONNECTION_BAD;
    2492           0 :             return 0;
    2493             :         }
    2494             :     }
    2495             : 
    2496             :     for (;;)
    2497       50306 :     {
    2498       74274 :         int         ret = 0;
    2499             : 
    2500             :         /*
    2501             :          * (Re)start the connect_timeout timer if it's active and we are
    2502             :          * considering a different host than we were last time through.  If
    2503             :          * we've already succeeded, though, needn't recalculate.
    2504             :          */
    2505       74274 :         if (flag != PGRES_POLLING_OK &&
    2506       50784 :             timeout > 0 &&
    2507          28 :             (conn->whichhost != last_whichhost ||
    2508          20 :              conn->whichaddr != last_whichaddr))
    2509             :         {
    2510           8 :             end_time = PQgetCurrentTimeUSec() + (pg_usec_time_t) timeout * 1000000;
    2511           8 :             last_whichhost = conn->whichhost;
    2512           8 :             last_whichaddr = conn->whichaddr;
    2513             :         }
    2514             : 
    2515             :         /*
    2516             :          * Wait, if necessary.  Note that the initial state (just after
    2517             :          * PQconnectStart) is to wait for the socket to select for writing.
    2518             :          */
    2519       74274 :         switch (flag)
    2520             :         {
    2521       23490 :             case PGRES_POLLING_OK:
    2522       23490 :                 return 1;       /* success! */
    2523             : 
    2524       25222 :             case PGRES_POLLING_READING:
    2525       25222 :                 ret = pqWaitTimed(1, 0, conn, end_time);
    2526       25222 :                 if (ret == -1)
    2527             :                 {
    2528             :                     /* hard failure, eg select() problem, aborts everything */
    2529           0 :                     conn->status = CONNECTION_BAD;
    2530           0 :                     return 0;
    2531             :                 }
    2532       25222 :                 break;
    2533             : 
    2534       25084 :             case PGRES_POLLING_WRITING:
    2535       25084 :                 ret = pqWaitTimed(0, 1, conn, end_time);
    2536       25084 :                 if (ret == -1)
    2537             :                 {
    2538             :                     /* hard failure, eg select() problem, aborts everything */
    2539           0 :                     conn->status = CONNECTION_BAD;
    2540           0 :                     return 0;
    2541             :                 }
    2542       25084 :                 break;
    2543             : 
    2544         478 :             default:
    2545             :                 /* Just in case we failed to set it in PQconnectPoll */
    2546         478 :                 conn->status = CONNECTION_BAD;
    2547         478 :                 return 0;
    2548             :         }
    2549             : 
    2550       50306 :         if (ret == 1)           /* connect_timeout elapsed */
    2551             :         {
    2552             :             /*
    2553             :              * Give up on current server/address, try the next one.
    2554             :              */
    2555           0 :             conn->try_next_addr = true;
    2556           0 :             conn->status = CONNECTION_NEEDED;
    2557             :         }
    2558             : 
    2559             :         /*
    2560             :          * Now try to advance the state machine.
    2561             :          */
    2562       50306 :         if (conn->cancelRequest)
    2563           4 :             flag = PQcancelPoll((PGcancelConn *) conn);
    2564             :         else
    2565       50302 :             flag = PQconnectPoll(conn);
    2566             :     }
    2567             : }
    2568             : 
    2569             : /* ----------------
    2570             :  *      PQconnectPoll
    2571             :  *
    2572             :  * Poll an asynchronous connection.
    2573             :  *
    2574             :  * Returns a PostgresPollingStatusType.
    2575             :  * Before calling this function, use select(2) to determine when data
    2576             :  * has arrived..
    2577             :  *
    2578             :  * You must call PQfinish whether or not this fails.
    2579             :  *
    2580             :  * This function and PQconnectStart are intended to allow connections to be
    2581             :  * made without blocking the execution of your program on remote I/O. However,
    2582             :  * there are a number of caveats:
    2583             :  *
    2584             :  *   o  If you call PQtrace, ensure that the stream object into which you trace
    2585             :  *      will not block.
    2586             :  *   o  If you do not supply an IP address for the remote host (i.e. you
    2587             :  *      supply a host name instead) then PQconnectStart will block on
    2588             :  *      getaddrinfo.  You will be fine if using Unix sockets (i.e. by
    2589             :  *      supplying neither a host name nor a host address).
    2590             :  *   o  If your backend wants to use Kerberos authentication then you must
    2591             :  *      supply both a host name and a host address, otherwise this function
    2592             :  *      may block on gethostname.
    2593             :  *
    2594             :  * ----------------
    2595             :  */
    2596             : PostgresPollingStatusType
    2597       81038 : PQconnectPoll(PGconn *conn)
    2598             : {
    2599       81038 :     bool        reset_connection_state_machine = false;
    2600       81038 :     bool        need_new_connection = false;
    2601             :     PGresult   *res;
    2602             :     char        sebuf[PG_STRERROR_R_BUFLEN];
    2603             :     int         optval;
    2604             : 
    2605       81038 :     if (conn == NULL)
    2606           0 :         return PGRES_POLLING_FAILED;
    2607             : 
    2608             :     /* Get the new data */
    2609       81038 :     switch (conn->status)
    2610             :     {
    2611             :             /*
    2612             :              * We really shouldn't have been polled in these two cases, but we
    2613             :              * can handle it.
    2614             :              */
    2615           0 :         case CONNECTION_BAD:
    2616           0 :             return PGRES_POLLING_FAILED;
    2617           0 :         case CONNECTION_OK:
    2618           0 :             return PGRES_POLLING_OK;
    2619             : 
    2620             :             /* These are reading states */
    2621       26300 :         case CONNECTION_AWAITING_RESPONSE:
    2622             :         case CONNECTION_AUTH_OK:
    2623             :         case CONNECTION_CHECK_WRITABLE:
    2624             :         case CONNECTION_CONSUME:
    2625             :         case CONNECTION_CHECK_STANDBY:
    2626             :             {
    2627             :                 /* Load waiting data */
    2628       26300 :                 int         n = pqReadData(conn);
    2629             : 
    2630       26300 :                 if (n < 0)
    2631          20 :                     goto error_return;
    2632       26280 :                 if (n == 0)
    2633           2 :                     return PGRES_POLLING_READING;
    2634             : 
    2635       26278 :                 break;
    2636             :             }
    2637             : 
    2638             :             /* These are writing states, so we just proceed. */
    2639       27192 :         case CONNECTION_STARTED:
    2640             :         case CONNECTION_MADE:
    2641       27192 :             break;
    2642             : 
    2643             :             /* Special cases: proceed without waiting. */
    2644       27546 :         case CONNECTION_SSL_STARTUP:
    2645             :         case CONNECTION_NEEDED:
    2646             :         case CONNECTION_GSS_STARTUP:
    2647             :         case CONNECTION_CHECK_TARGET:
    2648       27546 :             break;
    2649             : 
    2650           0 :         default:
    2651           0 :             libpq_append_conn_error(conn, "invalid connection state, probably indicative of memory corruption");
    2652           0 :             goto error_return;
    2653             :     }
    2654             : 
    2655             : 
    2656       81016 : keep_going:                     /* We will come back to here until there is
    2657             :                                  * nothing left to do. */
    2658             : 
    2659             :     /* Time to advance to next address, or next host if no more addresses? */
    2660      159182 :     if (conn->try_next_addr)
    2661             :     {
    2662         418 :         if (conn->whichaddr < conn->naddr)
    2663             :         {
    2664         418 :             conn->whichaddr++;
    2665         418 :             reset_connection_state_machine = true;
    2666             :         }
    2667             :         else
    2668           0 :             conn->try_next_host = true;
    2669         418 :         conn->try_next_addr = false;
    2670             :     }
    2671             : 
    2672             :     /* Time to advance to next connhost[] entry? */
    2673      159182 :     if (conn->try_next_host)
    2674             :     {
    2675             :         pg_conn_host *ch;
    2676             :         struct addrinfo hint;
    2677             :         struct addrinfo *addrlist;
    2678             :         int         thisport;
    2679             :         int         ret;
    2680             :         char        portstr[MAXPGPATH];
    2681             : 
    2682       27150 :         if (conn->whichhost + 1 < conn->nconnhost)
    2683       26518 :             conn->whichhost++;
    2684             :         else
    2685             :         {
    2686             :             /*
    2687             :              * Oops, no more hosts.
    2688             :              *
    2689             :              * If we are trying to connect in "prefer-standby" mode, then drop
    2690             :              * the standby requirement and start over. Don't do this for
    2691             :              * cancel requests though, since we are certain the list of
    2692             :              * servers won't change as the target_server_type option is not
    2693             :              * applicable to those connections.
    2694             :              *
    2695             :              * Otherwise, an appropriate error message is already set up, so
    2696             :              * we just need to set the right status.
    2697             :              */
    2698         632 :             if (conn->target_server_type == SERVER_TYPE_PREFER_STANDBY &&
    2699           2 :                 conn->nconnhost > 0 &&
    2700           2 :                 !conn->cancelRequest)
    2701             :             {
    2702           2 :                 conn->target_server_type = SERVER_TYPE_PREFER_STANDBY_PASS2;
    2703           2 :                 conn->whichhost = 0;
    2704             :             }
    2705             :             else
    2706         630 :                 goto error_return;
    2707             :         }
    2708             : 
    2709             :         /* Drop any address info for previous host */
    2710       26520 :         release_conn_addrinfo(conn);
    2711             : 
    2712             :         /*
    2713             :          * Look up info for the new host.  On failure, log the problem in
    2714             :          * conn->errorMessage, then loop around to try the next host.  (Note
    2715             :          * we don't clear try_next_host until we've succeeded.)
    2716             :          */
    2717       26520 :         ch = &conn->connhost[conn->whichhost];
    2718             : 
    2719             :         /* Initialize hint structure */
    2720      185640 :         MemSet(&hint, 0, sizeof(hint));
    2721       26520 :         hint.ai_socktype = SOCK_STREAM;
    2722       26520 :         hint.ai_family = AF_UNSPEC;
    2723             : 
    2724             :         /* Figure out the port number we're going to use. */
    2725       26520 :         if (ch->port == NULL || ch->port[0] == '\0')
    2726           0 :             thisport = DEF_PGPORT;
    2727             :         else
    2728             :         {
    2729       26520 :             if (!pqParseIntParam(ch->port, &thisport, conn, "port"))
    2730           0 :                 goto error_return;
    2731             : 
    2732       26520 :             if (thisport < 1 || thisport > 65535)
    2733             :             {
    2734           6 :                 libpq_append_conn_error(conn, "invalid port number: \"%s\"", ch->port);
    2735           6 :                 goto keep_going;
    2736             :             }
    2737             :         }
    2738       26514 :         snprintf(portstr, sizeof(portstr), "%d", thisport);
    2739             : 
    2740             :         /* Use pg_getaddrinfo_all() to resolve the address */
    2741       26514 :         switch (ch->type)
    2742             :         {
    2743         292 :             case CHT_HOST_NAME:
    2744         292 :                 ret = pg_getaddrinfo_all(ch->host, portstr, &hint,
    2745             :                                          &addrlist);
    2746         292 :                 if (ret || !addrlist)
    2747             :                 {
    2748           0 :                     libpq_append_conn_error(conn, "could not translate host name \"%s\" to address: %s",
    2749             :                                             ch->host, gai_strerror(ret));
    2750           0 :                     goto keep_going;
    2751             :                 }
    2752         292 :                 break;
    2753             : 
    2754         290 :             case CHT_HOST_ADDRESS:
    2755         290 :                 hint.ai_flags = AI_NUMERICHOST;
    2756         290 :                 ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint,
    2757             :                                          &addrlist);
    2758         290 :                 if (ret || !addrlist)
    2759             :                 {
    2760           0 :                     libpq_append_conn_error(conn, "could not parse network address \"%s\": %s",
    2761             :                                             ch->hostaddr, gai_strerror(ret));
    2762           0 :                     goto keep_going;
    2763             :                 }
    2764         290 :                 break;
    2765             : 
    2766       25932 :             case CHT_UNIX_SOCKET:
    2767       25932 :                 hint.ai_family = AF_UNIX;
    2768       25932 :                 UNIXSOCK_PATH(portstr, thisport, ch->host);
    2769       25932 :                 if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
    2770             :                 {
    2771           0 :                     libpq_append_conn_error(conn, "Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
    2772             :                                             portstr,
    2773             :                                             (int) (UNIXSOCK_PATH_BUFLEN - 1));
    2774           0 :                     goto keep_going;
    2775             :                 }
    2776             : 
    2777             :                 /*
    2778             :                  * NULL hostname tells pg_getaddrinfo_all to parse the service
    2779             :                  * name as a Unix-domain socket path.
    2780             :                  */
    2781       25932 :                 ret = pg_getaddrinfo_all(NULL, portstr, &hint,
    2782             :                                          &addrlist);
    2783       25932 :                 if (ret || !addrlist)
    2784             :                 {
    2785           0 :                     libpq_append_conn_error(conn, "could not translate Unix-domain socket path \"%s\" to address: %s",
    2786             :                                             portstr, gai_strerror(ret));
    2787           0 :                     goto keep_going;
    2788             :                 }
    2789       25932 :                 break;
    2790             :         }
    2791             : 
    2792             :         /*
    2793             :          * Store a copy of the addrlist in private memory so we can perform
    2794             :          * randomization for load balancing.
    2795             :          */
    2796       26514 :         ret = store_conn_addrinfo(conn, addrlist);
    2797       26514 :         pg_freeaddrinfo_all(hint.ai_family, addrlist);
    2798       26514 :         if (ret)
    2799           0 :             goto error_return;  /* message already logged */
    2800             : 
    2801             :         /*
    2802             :          * If random load balancing is enabled we shuffle the addresses.
    2803             :          */
    2804       26514 :         if (conn->load_balance_type == LOAD_BALANCE_RANDOM)
    2805             :         {
    2806             :             /*
    2807             :              * This is the "inside-out" variant of the Fisher-Yates shuffle
    2808             :              * algorithm. Notionally, we append each new value to the array
    2809             :              * and then swap it with a randomly-chosen array element (possibly
    2810             :              * including itself, else we fail to generate permutations with
    2811             :              * the last integer last).  The swap step can be optimized by
    2812             :              * combining it with the insertion.
    2813             :              *
    2814             :              * We don't need to initialize conn->prng_state here, because that
    2815             :              * already happened in pqConnectOptions2.
    2816             :              */
    2817         120 :             for (int i = 1; i < conn->naddr; i++)
    2818             :             {
    2819           0 :                 int         j = pg_prng_uint64_range(&conn->prng_state, 0, i);
    2820           0 :                 AddrInfo    temp = conn->addr[j];
    2821             : 
    2822           0 :                 conn->addr[j] = conn->addr[i];
    2823           0 :                 conn->addr[i] = temp;
    2824             :             }
    2825             :         }
    2826             : 
    2827       26514 :         reset_connection_state_machine = true;
    2828       26514 :         conn->try_next_host = false;
    2829             :     }
    2830             : 
    2831             :     /* Reset connection state machine? */
    2832      158546 :     if (reset_connection_state_machine)
    2833             :     {
    2834             :         /*
    2835             :          * (Re) initialize our connection control variables for a set of
    2836             :          * connection attempts to a single server address.  These variables
    2837             :          * must persist across individual connection attempts, but we must
    2838             :          * reset them when we start to consider a new server.
    2839             :          */
    2840       26932 :         conn->pversion = PG_PROTOCOL(3, 0);
    2841       26932 :         conn->send_appname = true;
    2842       26932 :         conn->failed_enc_methods = 0;
    2843       26932 :         conn->current_enc_method = 0;
    2844       26932 :         conn->allowed_enc_methods = 0;
    2845       26932 :         reset_connection_state_machine = false;
    2846       26932 :         need_new_connection = true;
    2847             :     }
    2848             : 
    2849             :     /* Force a new connection (perhaps to the same server as before)? */
    2850      158546 :     if (need_new_connection)
    2851             :     {
    2852             :         /* Drop any existing connection */
    2853       26938 :         pqDropConnection(conn, true);
    2854             : 
    2855             :         /* Reset all state obtained from old server */
    2856       26938 :         pqDropServerData(conn);
    2857             : 
    2858             :         /* Drop any PGresult we might have, too */
    2859       26938 :         conn->asyncStatus = PGASYNC_IDLE;
    2860       26938 :         conn->xactStatus = PQTRANS_IDLE;
    2861       26938 :         conn->pipelineStatus = PQ_PIPELINE_OFF;
    2862       26938 :         pqClearAsyncResult(conn);
    2863             : 
    2864             :         /* Reset conn->status to put the state machine in the right state */
    2865       26938 :         conn->status = CONNECTION_NEEDED;
    2866             : 
    2867       26938 :         need_new_connection = false;
    2868             :     }
    2869             : 
    2870             :     /*
    2871             :      * Decide what to do next, if server rejects SSL or GSS negotiation, but
    2872             :      * the connection is still valid.  If there are no options left, error out
    2873             :      * with 'msg'.
    2874             :      */
    2875             : #define ENCRYPTION_NEGOTIATION_FAILED(msg) \
    2876             :     do { \
    2877             :         switch (encryption_negotiation_failed(conn)) \
    2878             :         { \
    2879             :             case 0: \
    2880             :                 libpq_append_conn_error(conn, (msg)); \
    2881             :                 goto error_return; \
    2882             :             case 1: \
    2883             :                 conn->status = CONNECTION_MADE; \
    2884             :                 return PGRES_POLLING_WRITING; \
    2885             :             case 2: \
    2886             :                 need_new_connection = true; \
    2887             :                 goto keep_going; \
    2888             :         } \
    2889             :     } while(0);
    2890             : 
    2891             :     /*
    2892             :      * Decide what to do next, if connection fails.  If there are no options
    2893             :      * left, return with an error.  The error message has already been written
    2894             :      * to the connection's error buffer.
    2895             :      */
    2896             : #define CONNECTION_FAILED() \
    2897             :     do { \
    2898             :         if (connection_failed(conn)) \
    2899             :         { \
    2900             :             need_new_connection = true; \
    2901             :             goto keep_going; \
    2902             :         } \
    2903             :         else \
    2904             :             goto error_return; \
    2905             :     } while(0);
    2906             : 
    2907             :     /* Now try to advance the state machine for this connection */
    2908      158546 :     switch (conn->status)
    2909             :     {
    2910       26948 :         case CONNECTION_NEEDED:
    2911             :             {
    2912             :                 /*
    2913             :                  * Try to initiate a connection to one of the addresses
    2914             :                  * returned by pg_getaddrinfo_all().  conn->whichaddr is the
    2915             :                  * next one to try.
    2916             :                  *
    2917             :                  * The extra level of braces here is historical.  It's not
    2918             :                  * worth reindenting this whole switch case to remove 'em.
    2919             :                  */
    2920             :                 {
    2921             :                     char        host_addr[NI_MAXHOST];
    2922             :                     int         sock_type;
    2923             :                     AddrInfo   *addr_cur;
    2924             : 
    2925             :                     /*
    2926             :                      * Advance to next possible host, if we've tried all of
    2927             :                      * the addresses for the current host.
    2928             :                      */
    2929       26948 :                     if (conn->whichaddr == conn->naddr)
    2930             :                     {
    2931         416 :                         conn->try_next_host = true;
    2932       26358 :                         goto keep_going;
    2933             :                     }
    2934       26532 :                     addr_cur = &conn->addr[conn->whichaddr];
    2935             : 
    2936             :                     /* Remember current address for possible use later */
    2937       26532 :                     memcpy(&conn->raddr, &addr_cur->addr, sizeof(SockAddr));
    2938             : 
    2939             : #ifdef ENABLE_GSS
    2940             : 
    2941             :                     /*
    2942             :                      * Before establishing the connection, check if it's
    2943             :                      * doomed to fail because gssencmode='require' but GSSAPI
    2944             :                      * is not available.
    2945             :                      */
    2946             :                     if (conn->gssencmode[0] == 'r')
    2947             :                     {
    2948             :                         if (conn->raddr.addr.ss_family == AF_UNIX)
    2949             :                         {
    2950             :                             libpq_append_conn_error(conn,
    2951             :                                                     "GSSAPI encryption required but it is not supported over a local socket");
    2952             :                             goto error_return;
    2953             :                         }
    2954             :                         if (conn->gcred == GSS_C_NO_CREDENTIAL)
    2955             :                         {
    2956             :                             if (!pg_GSS_have_cred_cache(&conn->gcred))
    2957             :                             {
    2958             :                                 libpq_append_conn_error(conn,
    2959             :                                                         "GSSAPI encryption required but no credential cache");
    2960             :                                 goto error_return;
    2961             :                             }
    2962             :                         }
    2963             :                     }
    2964             : #endif
    2965             : 
    2966             :                     /*
    2967             :                      * Choose the encryption method to try first.  Do this
    2968             :                      * before establishing the connection, so that if none of
    2969             :                      * the modes allowed by the connections options are
    2970             :                      * available, we can error out before establishing the
    2971             :                      * connection.
    2972             :                      */
    2973       26532 :                     if (!init_allowed_encryption_methods(conn))
    2974           0 :                         goto error_return;
    2975             : 
    2976             :                     /*
    2977             :                      * Set connip, too.  Note we purposely ignore strdup
    2978             :                      * failure; not a big problem if it fails.
    2979             :                      */
    2980       26532 :                     if (conn->connip != NULL)
    2981             :                     {
    2982           8 :                         free(conn->connip);
    2983           8 :                         conn->connip = NULL;
    2984             :                     }
    2985       26532 :                     getHostaddr(conn, host_addr, NI_MAXHOST);
    2986       26532 :                     if (host_addr[0])
    2987         590 :                         conn->connip = strdup(host_addr);
    2988             : 
    2989             :                     /* Try to create the socket */
    2990       26532 :                     sock_type = SOCK_STREAM;
    2991             : #ifdef SOCK_CLOEXEC
    2992             : 
    2993             :                     /*
    2994             :                      * Atomically mark close-on-exec, if possible on this
    2995             :                      * platform, so that there isn't a window where a
    2996             :                      * subprogram executed by another thread inherits the
    2997             :                      * socket.  See fallback code below.
    2998             :                      */
    2999       26532 :                     sock_type |= SOCK_CLOEXEC;
    3000             : #endif
    3001             : #ifdef SOCK_NONBLOCK
    3002             : 
    3003             :                     /*
    3004             :                      * We might as well skip a system call for nonblocking
    3005             :                      * mode too, if we can.
    3006             :                      */
    3007       26532 :                     sock_type |= SOCK_NONBLOCK;
    3008             : #endif
    3009       26532 :                     conn->sock = socket(addr_cur->family, sock_type, 0);
    3010       26532 :                     if (conn->sock == PGINVALID_SOCKET)
    3011             :                     {
    3012           0 :                         int         errorno = SOCK_ERRNO;
    3013             : 
    3014             :                         /*
    3015             :                          * Silently ignore socket() failure if we have more
    3016             :                          * addresses to try; this reduces useless chatter in
    3017             :                          * cases where the address list includes both IPv4 and
    3018             :                          * IPv6 but kernel only accepts one family.
    3019             :                          */
    3020           0 :                         if (conn->whichaddr < conn->naddr ||
    3021           0 :                             conn->whichhost + 1 < conn->nconnhost)
    3022             :                         {
    3023           0 :                             conn->try_next_addr = true;
    3024           0 :                             goto keep_going;
    3025             :                         }
    3026           0 :                         emitHostIdentityInfo(conn, host_addr);
    3027           0 :                         libpq_append_conn_error(conn, "could not create socket: %s",
    3028             :                                                 SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)));
    3029           0 :                         goto error_return;
    3030             :                     }
    3031             : 
    3032             :                     /*
    3033             :                      * Once we've identified a target address, all errors
    3034             :                      * except the preceding socket()-failure case should be
    3035             :                      * prefixed with host-identity information.  (If the
    3036             :                      * connection succeeds, the contents of conn->errorMessage
    3037             :                      * won't matter, so this is harmless.)
    3038             :                      */
    3039       26532 :                     emitHostIdentityInfo(conn, host_addr);
    3040             : 
    3041             :                     /*
    3042             :                      * Select socket options: no delay of outgoing data for
    3043             :                      * TCP sockets, nonblock mode, close-on-exec.  Try the
    3044             :                      * next address if any of this fails.
    3045             :                      */
    3046       26532 :                     if (addr_cur->family != AF_UNIX)
    3047             :                     {
    3048         590 :                         if (!connectNoDelay(conn))
    3049             :                         {
    3050             :                             /* error message already created */
    3051           0 :                             conn->try_next_addr = true;
    3052           0 :                             goto keep_going;
    3053             :                         }
    3054             :                     }
    3055             : #ifndef SOCK_NONBLOCK
    3056             :                     if (!pg_set_noblock(conn->sock))
    3057             :                     {
    3058             :                         libpq_append_conn_error(conn, "could not set socket to nonblocking mode: %s",
    3059             :                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3060             :                         conn->try_next_addr = true;
    3061             :                         goto keep_going;
    3062             :                     }
    3063             : #endif
    3064             : 
    3065             : #ifndef SOCK_CLOEXEC
    3066             : #ifdef F_SETFD
    3067             :                     if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1)
    3068             :                     {
    3069             :                         libpq_append_conn_error(conn, "could not set socket to close-on-exec mode: %s",
    3070             :                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3071             :                         conn->try_next_addr = true;
    3072             :                         goto keep_going;
    3073             :                     }
    3074             : #endif                          /* F_SETFD */
    3075             : #endif
    3076             : 
    3077       26532 :                     if (addr_cur->family != AF_UNIX)
    3078             :                     {
    3079             : #ifndef WIN32
    3080         590 :                         int         on = 1;
    3081             : #endif
    3082         590 :                         int         usekeepalives = useKeepalives(conn);
    3083         590 :                         int         err = 0;
    3084             : 
    3085         590 :                         if (usekeepalives < 0)
    3086             :                         {
    3087             :                             /* error is already reported */
    3088           0 :                             err = 1;
    3089             :                         }
    3090         590 :                         else if (usekeepalives == 0)
    3091             :                         {
    3092             :                             /* Do nothing */
    3093             :                         }
    3094             : #ifndef WIN32
    3095         590 :                         else if (setsockopt(conn->sock,
    3096             :                                             SOL_SOCKET, SO_KEEPALIVE,
    3097             :                                             (char *) &on, sizeof(on)) < 0)
    3098             :                         {
    3099           0 :                             libpq_append_conn_error(conn, "%s(%s) failed: %s",
    3100             :                                                     "setsockopt",
    3101             :                                                     "SO_KEEPALIVE",
    3102           0 :                                                     SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3103           0 :                             err = 1;
    3104             :                         }
    3105         590 :                         else if (!setKeepalivesIdle(conn)
    3106         590 :                                  || !setKeepalivesInterval(conn)
    3107         590 :                                  || !setKeepalivesCount(conn))
    3108           0 :                             err = 1;
    3109             : #else                           /* WIN32 */
    3110             : #ifdef SIO_KEEPALIVE_VALS
    3111             :                         else if (!prepKeepalivesWin32(conn))
    3112             :                             err = 1;
    3113             : #endif                          /* SIO_KEEPALIVE_VALS */
    3114             : #endif                          /* WIN32 */
    3115         590 :                         else if (!setTCPUserTimeout(conn))
    3116           0 :                             err = 1;
    3117             : 
    3118         590 :                         if (err)
    3119             :                         {
    3120           0 :                             conn->try_next_addr = true;
    3121           0 :                             goto keep_going;
    3122             :                         }
    3123             :                     }
    3124             : 
    3125             :                     /*----------
    3126             :                      * We have three methods of blocking SIGPIPE during
    3127             :                      * send() calls to this socket:
    3128             :                      *
    3129             :                      *  - setsockopt(sock, SO_NOSIGPIPE)
    3130             :                      *  - send(sock, ..., MSG_NOSIGNAL)
    3131             :                      *  - setting the signal mask to SIG_IGN during send()
    3132             :                      *
    3133             :                      * The third method requires three syscalls per send,
    3134             :                      * so we prefer either of the first two, but they are
    3135             :                      * less portable.  The state is tracked in the following
    3136             :                      * members of PGconn:
    3137             :                      *
    3138             :                      * conn->sigpipe_so      - we have set up SO_NOSIGPIPE
    3139             :                      * conn->sigpipe_flag    - we're specifying MSG_NOSIGNAL
    3140             :                      *
    3141             :                      * If we can use SO_NOSIGPIPE, then set sigpipe_so here
    3142             :                      * and we're done.  Otherwise, set sigpipe_flag so that
    3143             :                      * we will try MSG_NOSIGNAL on sends.  If we get an error
    3144             :                      * with MSG_NOSIGNAL, we'll clear that flag and revert to
    3145             :                      * signal masking.
    3146             :                      *----------
    3147             :                      */
    3148       26532 :                     conn->sigpipe_so = false;
    3149             : #ifdef MSG_NOSIGNAL
    3150       26532 :                     conn->sigpipe_flag = true;
    3151             : #else
    3152             :                     conn->sigpipe_flag = false;
    3153             : #endif                          /* MSG_NOSIGNAL */
    3154             : 
    3155             : #ifdef SO_NOSIGPIPE
    3156             :                     optval = 1;
    3157             :                     if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE,
    3158             :                                    (char *) &optval, sizeof(optval)) == 0)
    3159             :                     {
    3160             :                         conn->sigpipe_so = true;
    3161             :                         conn->sigpipe_flag = false;
    3162             :                     }
    3163             : #endif                          /* SO_NOSIGPIPE */
    3164             : 
    3165             :                     /*
    3166             :                      * Start/make connection.  This should not block, since we
    3167             :                      * are in nonblock mode.  If it does, well, too bad.
    3168             :                      */
    3169       26532 :                     if (connect(conn->sock, (struct sockaddr *) &addr_cur->addr.addr,
    3170             :                                 addr_cur->addr.salen) < 0)
    3171             :                     {
    3172        1002 :                         if (SOCK_ERRNO == EINPROGRESS ||
    3173             : #ifdef WIN32
    3174             :                             SOCK_ERRNO == EWOULDBLOCK ||
    3175             : #endif
    3176         412 :                             SOCK_ERRNO == EINTR)
    3177             :                         {
    3178             :                             /*
    3179             :                              * This is fine - we're in non-blocking mode, and
    3180             :                              * the connection is in progress.  Tell caller to
    3181             :                              * wait for write-ready on socket.
    3182             :                              */
    3183         590 :                             conn->status = CONNECTION_STARTED;
    3184         590 :                             return PGRES_POLLING_WRITING;
    3185             :                         }
    3186             :                         /* otherwise, trouble */
    3187             :                     }
    3188             :                     else
    3189             :                     {
    3190             :                         /*
    3191             :                          * Hm, we're connected already --- seems the "nonblock
    3192             :                          * connection" wasn't.  Advance the state machine and
    3193             :                          * go do the next stuff.
    3194             :                          */
    3195       25530 :                         conn->status = CONNECTION_STARTED;
    3196       25530 :                         goto keep_going;
    3197             :                     }
    3198             : 
    3199             :                     /*
    3200             :                      * This connection failed.  Add the error report to
    3201             :                      * conn->errorMessage, then try the next address if any.
    3202             :                      */
    3203         412 :                     connectFailureMessage(conn, SOCK_ERRNO);
    3204         412 :                     conn->try_next_addr = true;
    3205         412 :                     goto keep_going;
    3206             :                 }
    3207             :             }
    3208             : 
    3209       26120 :         case CONNECTION_STARTED:
    3210             :             {
    3211       26120 :                 socklen_t   optlen = sizeof(optval);
    3212             : 
    3213             :                 /*
    3214             :                  * Write ready, since we've made it here, so the connection
    3215             :                  * has been made ... or has failed.
    3216             :                  */
    3217             : 
    3218             :                 /*
    3219             :                  * Now check (using getsockopt) that there is not an error
    3220             :                  * state waiting for us on the socket.
    3221             :                  */
    3222             : 
    3223       26120 :                 if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR,
    3224             :                                (char *) &optval, &optlen) == -1)
    3225             :                 {
    3226           0 :                     libpq_append_conn_error(conn, "could not get socket error status: %s",
    3227           0 :                                             SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3228           0 :                     goto error_return;
    3229             :                 }
    3230       26120 :                 else if (optval != 0)
    3231             :                 {
    3232             :                     /*
    3233             :                      * When using a nonblocking connect, we will typically see
    3234             :                      * connect failures at this point, so provide a friendly
    3235             :                      * error message.
    3236             :                      */
    3237           6 :                     connectFailureMessage(conn, optval);
    3238             : 
    3239             :                     /*
    3240             :                      * Try the next address if any, just as in the case where
    3241             :                      * connect() returned failure immediately.
    3242             :                      */
    3243           6 :                     conn->try_next_addr = true;
    3244           6 :                     goto keep_going;
    3245             :                 }
    3246             : 
    3247             :                 /* Fill in the client address */
    3248       26114 :                 conn->laddr.salen = sizeof(conn->laddr.addr);
    3249       26114 :                 if (getsockname(conn->sock,
    3250       26114 :                                 (struct sockaddr *) &conn->laddr.addr,
    3251             :                                 &conn->laddr.salen) < 0)
    3252             :                 {
    3253           0 :                     libpq_append_conn_error(conn, "could not get client address from socket: %s",
    3254           0 :                                             SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3255           0 :                     goto error_return;
    3256             :                 }
    3257             : 
    3258             :                 /*
    3259             :                  * Implement requirepeer check, if requested and it's a
    3260             :                  * Unix-domain socket.
    3261             :                  */
    3262       26114 :                 if (conn->requirepeer && conn->requirepeer[0] &&
    3263           0 :                     conn->raddr.addr.ss_family == AF_UNIX)
    3264             :                 {
    3265             : #ifndef WIN32
    3266             :                     char       *remote_username;
    3267             : #endif
    3268             :                     uid_t       uid;
    3269             :                     gid_t       gid;
    3270             : 
    3271           0 :                     errno = 0;
    3272           0 :                     if (getpeereid(conn->sock, &uid, &gid) != 0)
    3273             :                     {
    3274             :                         /*
    3275             :                          * Provide special error message if getpeereid is a
    3276             :                          * stub
    3277             :                          */
    3278           0 :                         if (errno == ENOSYS)
    3279           0 :                             libpq_append_conn_error(conn, "requirepeer parameter is not supported on this platform");
    3280             :                         else
    3281           0 :                             libpq_append_conn_error(conn, "could not get peer credentials: %s",
    3282           0 :                                                     strerror_r(errno, sebuf, sizeof(sebuf)));
    3283           0 :                         goto error_return;
    3284             :                     }
    3285             : 
    3286             : #ifndef WIN32
    3287           0 :                     remote_username = pg_fe_getusername(uid,
    3288             :                                                         &conn->errorMessage);
    3289           0 :                     if (remote_username == NULL)
    3290           0 :                         goto error_return;  /* message already logged */
    3291             : 
    3292           0 :                     if (strcmp(remote_username, conn->requirepeer) != 0)
    3293             :                     {
    3294           0 :                         libpq_append_conn_error(conn, "requirepeer specifies \"%s\", but actual peer user name is \"%s\"",
    3295             :                                                 conn->requirepeer, remote_username);
    3296           0 :                         free(remote_username);
    3297           0 :                         goto error_return;
    3298             :                     }
    3299           0 :                     free(remote_username);
    3300             : #else                           /* WIN32 */
    3301             :                     /* should have failed with ENOSYS above */
    3302             :                     Assert(false);
    3303             : #endif                          /* WIN32 */
    3304             :                 }
    3305             : 
    3306             :                 /*
    3307             :                  * Make sure we can write before advancing to next step.
    3308             :                  */
    3309       26114 :                 conn->status = CONNECTION_MADE;
    3310       26114 :                 return PGRES_POLLING_WRITING;
    3311             :             }
    3312             : 
    3313       26602 :         case CONNECTION_MADE:
    3314             :             {
    3315             :                 char       *startpacket;
    3316             :                 int         packetlen;
    3317             : 
    3318             : #ifdef ENABLE_GSS
    3319             : 
    3320             :                 /*
    3321             :                  * If GSSAPI encryption is enabled, send a packet to the
    3322             :                  * server asking for GSSAPI Encryption and proceed with GSSAPI
    3323             :                  * handshake.  We will come back here after GSSAPI encryption
    3324             :                  * has been established, with conn->gctx set.
    3325             :                  */
    3326             :                 if (conn->current_enc_method == ENC_GSSAPI && !conn->gctx)
    3327             :                 {
    3328             :                     ProtocolVersion pv = pg_hton32(NEGOTIATE_GSS_CODE);
    3329             : 
    3330             :                     if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
    3331             :                     {
    3332             :                         libpq_append_conn_error(conn, "could not send GSSAPI negotiation packet: %s",
    3333             :                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3334             :                         goto error_return;
    3335             :                     }
    3336             : 
    3337             :                     /* Ok, wait for response */
    3338             :                     conn->status = CONNECTION_GSS_STARTUP;
    3339             :                     return PGRES_POLLING_READING;
    3340             :                 }
    3341             : #endif
    3342             : 
    3343             : #ifdef USE_SSL
    3344             : 
    3345             :                 /*
    3346             :                  * If SSL is enabled, start the SSL negotiation. We will come
    3347             :                  * back here after SSL encryption has been established, with
    3348             :                  * ssl_in_use set.
    3349             :                  */
    3350       26602 :                 if (conn->current_enc_method == ENC_SSL && !conn->ssl_in_use)
    3351             :                 {
    3352             :                     /*
    3353             :                      * If traditional postgres SSL negotiation is used, send
    3354             :                      * the SSL request.  In direct negotiation, jump straight
    3355             :                      * into the SSL handshake.
    3356             :                      */
    3357         558 :                     if (conn->sslnegotiation[0] == 'p')
    3358             :                     {
    3359             :                         ProtocolVersion pv;
    3360             : 
    3361             :                         /*
    3362             :                          * Send the SSL request packet.
    3363             :                          *
    3364             :                          * Theoretically, this could block, but it really
    3365             :                          * shouldn't since we only got here if the socket is
    3366             :                          * write-ready.
    3367             :                          */
    3368         548 :                         pv = pg_hton32(NEGOTIATE_SSL_CODE);
    3369         548 :                         if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
    3370             :                         {
    3371           0 :                             libpq_append_conn_error(conn, "could not send SSL negotiation packet: %s",
    3372           0 :                                                     SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3373           0 :                             goto error_return;
    3374             :                         }
    3375             :                         /* Ok, wait for response */
    3376         548 :                         conn->status = CONNECTION_SSL_STARTUP;
    3377         548 :                         return PGRES_POLLING_READING;
    3378             :                     }
    3379             :                     else
    3380             :                     {
    3381             :                         Assert(conn->sslnegotiation[0] == 'd');
    3382          10 :                         conn->status = CONNECTION_SSL_STARTUP;
    3383          10 :                         return PGRES_POLLING_WRITING;
    3384             :                     }
    3385             :                 }
    3386             : #endif                          /* USE_SSL */
    3387             : 
    3388             :                 /*
    3389             :                  * For cancel requests this is as far as we need to go in the
    3390             :                  * connection establishment. Now we can actually send our
    3391             :                  * cancellation request.
    3392             :                  */
    3393       26044 :                 if (conn->cancelRequest)
    3394             :                 {
    3395             :                     CancelRequestPacket cancelpacket;
    3396             : 
    3397          10 :                     packetlen = sizeof(cancelpacket);
    3398          10 :                     cancelpacket.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE);
    3399          10 :                     cancelpacket.backendPID = pg_hton32(conn->be_pid);
    3400          10 :                     cancelpacket.cancelAuthCode = pg_hton32(conn->be_key);
    3401          10 :                     if (pqPacketSend(conn, 0, &cancelpacket, packetlen) != STATUS_OK)
    3402             :                     {
    3403           0 :                         libpq_append_conn_error(conn, "could not send cancel packet: %s",
    3404           0 :                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3405           0 :                         goto error_return;
    3406             :                     }
    3407          10 :                     conn->status = CONNECTION_AWAITING_RESPONSE;
    3408          10 :                     return PGRES_POLLING_READING;
    3409             :                 }
    3410             : 
    3411             :                 /*
    3412             :                  * We have now established encryption, or we are happy to
    3413             :                  * proceed without.
    3414             :                  */
    3415             : 
    3416             :                 /* Build the startup packet. */
    3417       26034 :                 startpacket = pqBuildStartupPacket3(conn, &packetlen,
    3418             :                                                     EnvironmentOptions);
    3419       26034 :                 if (!startpacket)
    3420             :                 {
    3421           0 :                     libpq_append_conn_error(conn, "out of memory");
    3422           0 :                     goto error_return;
    3423             :                 }
    3424             : 
    3425             :                 /*
    3426             :                  * Send the startup packet.
    3427             :                  *
    3428             :                  * Theoretically, this could block, but it really shouldn't
    3429             :                  * since we only got here if the socket is write-ready.
    3430             :                  */
    3431       26034 :                 if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK)
    3432             :                 {
    3433           0 :                     libpq_append_conn_error(conn, "could not send startup packet: %s",
    3434           0 :                                             SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    3435           0 :                     free(startpacket);
    3436           0 :                     goto error_return;
    3437             :                 }
    3438             : 
    3439       26034 :                 free(startpacket);
    3440             : 
    3441       26034 :                 conn->status = CONNECTION_AWAITING_RESPONSE;
    3442       26034 :                 return PGRES_POLLING_READING;
    3443             :             }
    3444             : 
    3445             :             /*
    3446             :              * Handle SSL negotiation: wait for postmaster messages and
    3447             :              * respond as necessary.
    3448             :              */
    3449        1052 :         case CONNECTION_SSL_STARTUP:
    3450             :             {
    3451             : #ifdef USE_SSL
    3452             :                 PostgresPollingStatusType pollres;
    3453             : 
    3454             :                 /*
    3455             :                  * On first time through with traditional SSL negotiation, get
    3456             :                  * the postmaster's response to our SSLRequest packet. With
    3457             :                  * sslnegotiation='direct', go straight to initiating SSL.
    3458             :                  */
    3459        1052 :                 if (!conn->ssl_in_use && conn->sslnegotiation[0] == 'p')
    3460             :                 {
    3461             :                     /*
    3462             :                      * We use pqReadData here since it has the logic to
    3463             :                      * distinguish no-data-yet from connection closure. Since
    3464             :                      * conn->ssl isn't set, a plain recv() will occur.
    3465             :                      */
    3466             :                     char        SSLok;
    3467             :                     int         rdresult;
    3468             : 
    3469         548 :                     rdresult = pqReadData(conn);
    3470         548 :                     if (rdresult < 0)
    3471             :                     {
    3472             :                         /* errorMessage is already filled in */
    3473           8 :                         goto error_return;
    3474             :                     }
    3475         548 :                     if (rdresult == 0)
    3476             :                     {
    3477             :                         /* caller failed to wait for data */
    3478         292 :                         return PGRES_POLLING_READING;
    3479             :                     }
    3480         548 :                     if (pqGetc(&SSLok, conn) < 0)
    3481             :                     {
    3482             :                         /* should not happen really */
    3483           0 :                         return PGRES_POLLING_READING;
    3484             :                     }
    3485         548 :                     if (SSLok == 'S')
    3486             :                     {
    3487         248 :                         if (conn->Pfdebug)
    3488           0 :                             pqTraceOutputCharResponse(conn, "SSLResponse",
    3489             :                                                       SSLok);
    3490             :                         /* mark byte consumed */
    3491         248 :                         conn->inStart = conn->inCursor;
    3492             :                     }
    3493         300 :                     else if (SSLok == 'N')
    3494             :                     {
    3495         296 :                         if (conn->Pfdebug)
    3496           0 :                             pqTraceOutputCharResponse(conn, "SSLResponse",
    3497             :                                                       SSLok);
    3498             :                         /* mark byte consumed */
    3499         296 :                         conn->inStart = conn->inCursor;
    3500             : 
    3501             :                         /*
    3502             :                          * The connection is still valid, so if it's OK to
    3503             :                          * continue without SSL, we can proceed using this
    3504             :                          * connection.  Otherwise return with an error.
    3505             :                          */
    3506         592 :                         ENCRYPTION_NEGOTIATION_FAILED(libpq_gettext("server does not support SSL, but SSL was required"));
    3507             :                     }
    3508           4 :                     else if (SSLok == 'E')
    3509             :                     {
    3510             :                         /*
    3511             :                          * Server failure of some sort, such as failure to
    3512             :                          * fork a backend process.  Don't bother retrieving
    3513             :                          * the error message; we should not trust it as the
    3514             :                          * server has not been authenticated yet.
    3515             :                          */
    3516           4 :                         libpq_append_conn_error(conn, "server sent an error response during SSL exchange");
    3517           4 :                         goto error_return;
    3518             :                     }
    3519             :                     else
    3520             :                     {
    3521           0 :                         libpq_append_conn_error(conn, "received invalid response to SSL negotiation: %c",
    3522             :                                                 SSLok);
    3523           0 :                         goto error_return;
    3524             :                     }
    3525             :                 }
    3526             : 
    3527             :                 /*
    3528             :                  * Begin or continue the SSL negotiation process.
    3529             :                  */
    3530         752 :                 pollres = pqsecure_open_client(conn);
    3531         752 :                 if (pollres == PGRES_POLLING_OK)
    3532             :                 {
    3533             :                     /*
    3534             :                      * At this point we should have no data already buffered.
    3535             :                      * If we do, it was received before we performed the SSL
    3536             :                      * handshake, so it wasn't encrypted and indeed may have
    3537             :                      * been injected by a man-in-the-middle.
    3538             :                      */
    3539         200 :                     if (conn->inCursor != conn->inEnd)
    3540             :                     {
    3541           0 :                         libpq_append_conn_error(conn, "received unencrypted data after SSL response");
    3542           0 :                         goto error_return;
    3543             :                     }
    3544             : 
    3545             :                     /* SSL handshake done, ready to send startup packet */
    3546         200 :                     conn->status = CONNECTION_MADE;
    3547         200 :                     return PGRES_POLLING_WRITING;
    3548             :                 }
    3549         552 :                 if (pollres == PGRES_POLLING_FAILED)
    3550             :                 {
    3551             :                     /*
    3552             :                      * SSL handshake failed.  We will retry with a plaintext
    3553             :                      * connection, if permitted by sslmode.
    3554             :                      */
    3555          58 :                     CONNECTION_FAILED();
    3556             :                 }
    3557             :                 /* Else, return POLLING_READING or POLLING_WRITING status */
    3558         494 :                 return pollres;
    3559             : #else                           /* !USE_SSL */
    3560             :                 /* can't get here */
    3561             :                 goto error_return;
    3562             : #endif                          /* USE_SSL */
    3563             :             }
    3564             : 
    3565           0 :         case CONNECTION_GSS_STARTUP:
    3566             :             {
    3567             : #ifdef ENABLE_GSS
    3568             :                 PostgresPollingStatusType pollres;
    3569             : 
    3570             :                 /*
    3571             :                  * If we haven't yet, get the postmaster's response to our
    3572             :                  * negotiation packet
    3573             :                  */
    3574             :                 if (!conn->gctx)
    3575             :                 {
    3576             :                     char        gss_ok;
    3577             :                     int         rdresult = pqReadData(conn);
    3578             : 
    3579             :                     if (rdresult < 0)
    3580             :                         /* pqReadData fills in error message */
    3581             :                         goto error_return;
    3582             :                     else if (rdresult == 0)
    3583             :                         /* caller failed to wait for data */
    3584             :                         return PGRES_POLLING_READING;
    3585             :                     if (pqGetc(&gss_ok, conn) < 0)
    3586             :                         /* shouldn't happen... */
    3587             :                         return PGRES_POLLING_READING;
    3588             : 
    3589             :                     if (gss_ok == 'E')
    3590             :                     {
    3591             :                         /*
    3592             :                          * Server failure of some sort, possibly protocol
    3593             :                          * version support failure.  Don't bother retrieving
    3594             :                          * the error message; we should not trust it anyway as
    3595             :                          * the server has not authenticated yet.
    3596             :                          *
    3597             :                          * Note that unlike on an error response to
    3598             :                          * SSLRequest, we allow falling back to SSL or
    3599             :                          * plaintext connection here.  GSS support was
    3600             :                          * introduced in PostgreSQL version 12, so an error
    3601             :                          * response might mean that we are connecting to a
    3602             :                          * pre-v12 server.
    3603             :                          */
    3604             :                         libpq_append_conn_error(conn, "server sent an error response during GSS encryption exchange");
    3605             :                         CONNECTION_FAILED();
    3606             :                     }
    3607             : 
    3608             :                     /* mark byte consumed */
    3609             :                     conn->inStart = conn->inCursor;
    3610             : 
    3611             :                     if (gss_ok == 'N')
    3612             :                     {
    3613             :                         if (conn->Pfdebug)
    3614             :                             pqTraceOutputCharResponse(conn, "GSSENCResponse",
    3615             :                                                       gss_ok);
    3616             : 
    3617             :                         /*
    3618             :                          * The connection is still valid, so if it's OK to
    3619             :                          * continue without GSS, we can proceed using this
    3620             :                          * connection.  Otherwise return with an error.
    3621             :                          */
    3622             :                         ENCRYPTION_NEGOTIATION_FAILED(libpq_gettext("server doesn't support GSSAPI encryption, but it was required"));
    3623             :                     }
    3624             :                     else if (gss_ok != 'G')
    3625             :                     {
    3626             :                         libpq_append_conn_error(conn, "received invalid response to GSSAPI negotiation: %c",
    3627             :                                                 gss_ok);
    3628             :                         goto error_return;
    3629             :                     }
    3630             : 
    3631             :                     if (conn->Pfdebug)
    3632             :                         pqTraceOutputCharResponse(conn, "GSSENCResponse",
    3633             :                                                   gss_ok);
    3634             :                 }
    3635             : 
    3636             :                 /* Begin or continue GSSAPI negotiation */
    3637             :                 pollres = pqsecure_open_gss(conn);
    3638             :                 if (pollres == PGRES_POLLING_OK)
    3639             :                 {
    3640             :                     /*
    3641             :                      * At this point we should have no data already buffered.
    3642             :                      * If we do, it was received before we performed the GSS
    3643             :                      * handshake, so it wasn't encrypted and indeed may have
    3644             :                      * been injected by a man-in-the-middle.
    3645             :                      */
    3646             :                     if (conn->inCursor != conn->inEnd)
    3647             :                     {
    3648             :                         libpq_append_conn_error(conn, "received unencrypted data after GSSAPI encryption response");
    3649             :                         goto error_return;
    3650             :                     }
    3651             : 
    3652             :                     /* All set for startup packet */
    3653             :                     conn->status = CONNECTION_MADE;
    3654             :                     return PGRES_POLLING_WRITING;
    3655             :                 }
    3656             :                 else if (pollres == PGRES_POLLING_FAILED)
    3657             :                 {
    3658             :                     /*
    3659             :                      * GSS handshake failed.  We will retry with an SSL or
    3660             :                      * plaintext connection, if permitted by the options.
    3661             :                      */
    3662             :                     CONNECTION_FAILED();
    3663             :                 }
    3664             :                 /* Else, return POLLING_READING or POLLING_WRITING status */
    3665             :                 return pollres;
    3666             : #else                           /* !ENABLE_GSS */
    3667             :                 /* unreachable */
    3668           0 :                 goto error_return;
    3669             : #endif                          /* ENABLE_GSS */
    3670             :             }
    3671             : 
    3672             :             /*
    3673             :              * Handle authentication exchange: wait for postmaster messages
    3674             :              * and respond as necessary.
    3675             :              */
    3676       26564 :         case CONNECTION_AWAITING_RESPONSE:
    3677             :             {
    3678             :                 char        beresp;
    3679             :                 int         msgLength;
    3680             :                 int         avail;
    3681             :                 AuthRequest areq;
    3682             :                 int         res;
    3683             : 
    3684             :                 /*
    3685             :                  * Scan the message from current point (note that if we find
    3686             :                  * the message is incomplete, we will return without advancing
    3687             :                  * inStart, and resume here next time).
    3688             :                  */
    3689       26564 :                 conn->inCursor = conn->inStart;
    3690             : 
    3691             :                 /* Read type byte */
    3692       26564 :                 if (pqGetc(&beresp, conn))
    3693             :                 {
    3694             :                     /* We'll come back when there is more data */
    3695         244 :                     return PGRES_POLLING_READING;
    3696             :                 }
    3697             : 
    3698             :                 /*
    3699             :                  * Validate message type: we expect only an authentication
    3700             :                  * request, NegotiateProtocolVersion, or an error here.
    3701             :                  * Anything else probably means it's not Postgres on the other
    3702             :                  * end at all.
    3703             :                  */
    3704       26320 :                 if (beresp != PqMsg_AuthenticationRequest &&
    3705         310 :                     beresp != PqMsg_ErrorResponse &&
    3706           0 :                     beresp != PqMsg_NegotiateProtocolVersion)
    3707             :                 {
    3708           0 :                     libpq_append_conn_error(conn, "expected authentication request from server, but received %c",
    3709             :                                             beresp);
    3710         152 :                     goto error_return;
    3711             :                 }
    3712             : 
    3713             :                 /* Read message length word */
    3714       26320 :                 if (pqGetInt(&msgLength, 4, conn))
    3715             :                 {
    3716             :                     /* We'll come back when there is more data */
    3717           0 :                     return PGRES_POLLING_READING;
    3718             :                 }
    3719             : 
    3720             :                 /*
    3721             :                  * Try to validate message length before using it.
    3722             :                  *
    3723             :                  * Authentication requests can't be very large, although GSS
    3724             :                  * auth requests may not be that small.  Same for
    3725             :                  * NegotiateProtocolVersion.
    3726             :                  *
    3727             :                  * Errors can be a little larger, but not huge.  If we see a
    3728             :                  * large apparent length in an error, it means we're really
    3729             :                  * talking to a pre-3.0-protocol server; cope.  (Before
    3730             :                  * version 14, the server also used the old protocol for
    3731             :                  * errors that happened before processing the startup packet.)
    3732             :                  */
    3733       26320 :                 if (beresp == PqMsg_AuthenticationRequest &&
    3734       26010 :                     (msgLength < 8 || msgLength > 2000))
    3735             :                 {
    3736           0 :                     libpq_append_conn_error(conn, "received invalid authentication request");
    3737           0 :                     goto error_return;
    3738             :                 }
    3739       26320 :                 if (beresp == PqMsg_NegotiateProtocolVersion &&
    3740           0 :                     (msgLength < 8 || msgLength > 2000))
    3741             :                 {
    3742           0 :                     libpq_append_conn_error(conn, "received invalid protocol negotiation message");
    3743           0 :                     goto error_return;
    3744             :                 }
    3745             : 
    3746             : #define MAX_ERRLEN 30000
    3747       26320 :                 if (beresp == PqMsg_ErrorResponse &&
    3748         310 :                     (msgLength < 8 || msgLength > MAX_ERRLEN))
    3749             :                 {
    3750             :                     /* Handle error from a pre-3.0 server */
    3751           0 :                     conn->inCursor = conn->inStart + 1; /* reread data */
    3752           0 :                     if (pqGets_append(&conn->errorMessage, conn))
    3753             :                     {
    3754             :                         /*
    3755             :                          * We may not have authenticated the server yet, so
    3756             :                          * don't let the buffer grow forever.
    3757             :                          */
    3758           0 :                         avail = conn->inEnd - conn->inCursor;
    3759           0 :                         if (avail > MAX_ERRLEN)
    3760             :                         {
    3761           0 :                             libpq_append_conn_error(conn, "received invalid error message");
    3762           0 :                             goto error_return;
    3763             :                         }
    3764             : 
    3765             :                         /* We'll come back when there is more data */
    3766           0 :                         return PGRES_POLLING_READING;
    3767             :                     }
    3768             :                     /* OK, we read the message; mark data consumed */
    3769           0 :                     pqParseDone(conn, conn->inCursor);
    3770             : 
    3771             :                     /*
    3772             :                      * Before 7.2, the postmaster didn't always end its
    3773             :                      * messages with a newline, so add one if needed to
    3774             :                      * conform to libpq conventions.
    3775             :                      */
    3776           0 :                     if (conn->errorMessage.len == 0 ||
    3777           0 :                         conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
    3778             :                     {
    3779           0 :                         appendPQExpBufferChar(&conn->errorMessage, '\n');
    3780             :                     }
    3781             : 
    3782           0 :                     goto error_return;
    3783             :                 }
    3784             : #undef MAX_ERRLEN
    3785             : 
    3786             :                 /*
    3787             :                  * Can't process if message body isn't all here yet.
    3788             :                  *
    3789             :                  * After this check passes, any further EOF during parsing
    3790             :                  * implies that the server sent a bad/truncated message.
    3791             :                  * Reading more bytes won't help in that case, so don't return
    3792             :                  * PGRES_POLLING_READING after this point.
    3793             :                  */
    3794       26320 :                 msgLength -= 4;
    3795       26320 :                 avail = conn->inEnd - conn->inCursor;
    3796       26320 :                 if (avail < msgLength)
    3797             :                 {
    3798             :                     /*
    3799             :                      * Before returning, try to enlarge the input buffer if
    3800             :                      * needed to hold the whole message; see notes in
    3801             :                      * pqParseInput3.
    3802             :                      */
    3803           0 :                     if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength,
    3804             :                                              conn))
    3805           0 :                         goto error_return;
    3806             :                     /* We'll come back when there is more data */
    3807           0 :                     return PGRES_POLLING_READING;
    3808             :                 }
    3809             : 
    3810             :                 /* Handle errors. */
    3811       26320 :                 if (beresp == PqMsg_ErrorResponse)
    3812             :                 {
    3813         310 :                     if (pqGetErrorNotice3(conn, true))
    3814             :                     {
    3815           0 :                         libpq_append_conn_error(conn, "received invalid error message");
    3816           0 :                         goto error_return;
    3817             :                     }
    3818             :                     /* OK, we read the message; mark data consumed */
    3819         310 :                     pqParseDone(conn, conn->inCursor);
    3820             : 
    3821             :                     /*
    3822             :                      * If error is "cannot connect now", try the next host if
    3823             :                      * any (but we don't want to consider additional addresses
    3824             :                      * for this host, nor is there much point in changing SSL
    3825             :                      * or GSS mode).  This is helpful when dealing with
    3826             :                      * standby servers that might not be in hot-standby state.
    3827             :                      */
    3828         310 :                     if (strcmp(conn->last_sqlstate,
    3829             :                                ERRCODE_CANNOT_CONNECT_NOW) == 0)
    3830             :                     {
    3831         214 :                         conn->try_next_host = true;
    3832       26168 :                         goto keep_going;
    3833             :                     }
    3834             : 
    3835             :                     /* Check to see if we should mention pgpassfile */
    3836          96 :                     pgpassfileWarning(conn);
    3837             : 
    3838          96 :                     CONNECTION_FAILED();
    3839             :                 }
    3840       26010 :                 else if (beresp == PqMsg_NegotiateProtocolVersion)
    3841             :                 {
    3842           0 :                     if (pqGetNegotiateProtocolVersion3(conn))
    3843             :                     {
    3844           0 :                         libpq_append_conn_error(conn, "received invalid protocol negotiation message");
    3845           0 :                         goto error_return;
    3846             :                     }
    3847             :                     /* OK, we read the message; mark data consumed */
    3848           0 :                     pqParseDone(conn, conn->inCursor);
    3849           0 :                     goto error_return;
    3850             :                 }
    3851             : 
    3852             :                 /* It is an authentication request. */
    3853       26010 :                 conn->auth_req_received = true;
    3854             : 
    3855             :                 /* Get the type of request. */
    3856       26010 :                 if (pqGetInt((int *) &areq, 4, conn))
    3857             :                 {
    3858             :                     /* can't happen because we checked the length already */
    3859           0 :                     libpq_append_conn_error(conn, "received invalid authentication request");
    3860           0 :                     goto error_return;
    3861             :                 }
    3862       26010 :                 msgLength -= 4;
    3863             : 
    3864             :                 /*
    3865             :                  * Process the rest of the authentication request message, and
    3866             :                  * respond to it if necessary.
    3867             :                  *
    3868             :                  * Note that conn->pghost must be non-NULL if we are going to
    3869             :                  * avoid the Kerberos code doing a hostname look-up.
    3870             :                  */
    3871       26010 :                 res = pg_fe_sendauth(areq, msgLength, conn);
    3872             : 
    3873             :                 /*
    3874             :                  * OK, we have processed the message; mark data consumed.  We
    3875             :                  * don't call pqParseDone here because we already traced this
    3876             :                  * message inside pg_fe_sendauth.
    3877             :                  */
    3878       26010 :                 conn->inStart = conn->inCursor;
    3879             : 
    3880       26010 :                 if (res != STATUS_OK)
    3881          60 :                     goto error_return;
    3882             : 
    3883             :                 /*
    3884             :                  * Just make sure that any data sent by pg_fe_sendauth is
    3885             :                  * flushed out.  Although this theoretically could block, it
    3886             :                  * really shouldn't since we don't send large auth responses.
    3887             :                  */
    3888       25950 :                 if (pqFlush(conn))
    3889           0 :                     goto error_return;
    3890             : 
    3891       25950 :                 if (areq == AUTH_REQ_OK)
    3892             :                 {
    3893             :                     /* We are done with authentication exchange */
    3894       25638 :                     conn->status = CONNECTION_AUTH_OK;
    3895             : 
    3896             :                     /*
    3897             :                      * Set asyncStatus so that PQgetResult will think that
    3898             :                      * what comes back next is the result of a query.  See
    3899             :                      * below.
    3900             :                      */
    3901       25638 :                     conn->asyncStatus = PGASYNC_BUSY;
    3902             :                 }
    3903             : 
    3904             :                 /* Look to see if we have more data yet. */
    3905       25950 :                 goto keep_going;
    3906             :             }
    3907             : 
    3908       25664 :         case CONNECTION_AUTH_OK:
    3909             :             {
    3910             :                 /*
    3911             :                  * Now we expect to hear from the backend. A ReadyForQuery
    3912             :                  * message indicates that startup is successful, but we might
    3913             :                  * also get an Error message indicating failure. (Notice
    3914             :                  * messages indicating nonfatal warnings are also allowed by
    3915             :                  * the protocol, as are ParameterStatus and BackendKeyData
    3916             :                  * messages.) Easiest way to handle this is to let
    3917             :                  * PQgetResult() read the messages. We just have to fake it
    3918             :                  * out about the state of the connection, by setting
    3919             :                  * asyncStatus = PGASYNC_BUSY (done above).
    3920             :                  */
    3921             : 
    3922       25664 :                 if (PQisBusy(conn))
    3923          26 :                     return PGRES_POLLING_READING;
    3924             : 
    3925       25638 :                 res = PQgetResult(conn);
    3926             : 
    3927             :                 /*
    3928             :                  * NULL return indicating we have gone to IDLE state is
    3929             :                  * expected
    3930             :                  */
    3931       25638 :                 if (res)
    3932             :                 {
    3933          42 :                     if (res->resultStatus != PGRES_FATAL_ERROR)
    3934           0 :                         libpq_append_conn_error(conn, "unexpected message from server during startup");
    3935          42 :                     else if (conn->send_appname &&
    3936          42 :                              (conn->appname || conn->fbappname))
    3937             :                     {
    3938             :                         /*
    3939             :                          * If we tried to send application_name, check to see
    3940             :                          * if the error is about that --- pre-9.0 servers will
    3941             :                          * reject it at this stage of the process.  If so,
    3942             :                          * close the connection and retry without sending
    3943             :                          * application_name.  We could possibly get a false
    3944             :                          * SQLSTATE match here and retry uselessly, but there
    3945             :                          * seems no great harm in that; we'll just get the
    3946             :                          * same error again if it's unrelated.
    3947             :                          */
    3948             :                         const char *sqlstate;
    3949             : 
    3950          42 :                         sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
    3951          42 :                         if (sqlstate &&
    3952          42 :                             strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
    3953             :                         {
    3954           0 :                             PQclear(res);
    3955           0 :                             conn->send_appname = false;
    3956           0 :                             need_new_connection = true;
    3957           0 :                             goto keep_going;
    3958             :                         }
    3959             :                     }
    3960             : 
    3961             :                     /*
    3962             :                      * if the resultStatus is FATAL, then conn->errorMessage
    3963             :                      * already has a copy of the error; needn't copy it back.
    3964             :                      * But add a newline if it's not there already, since
    3965             :                      * postmaster error messages may not have one.
    3966             :                      */
    3967          42 :                     if (conn->errorMessage.len <= 0 ||
    3968          42 :                         conn->errorMessage.data[conn->errorMessage.len - 1] != '\n')
    3969           0 :                         appendPQExpBufferChar(&conn->errorMessage, '\n');
    3970          42 :                     PQclear(res);
    3971          42 :                     goto error_return;
    3972             :                 }
    3973             : 
    3974             :                 /* Almost there now ... */
    3975       25596 :                 conn->status = CONNECTION_CHECK_TARGET;
    3976       25596 :                 goto keep_going;
    3977             :             }
    3978             : 
    3979       25596 :         case CONNECTION_CHECK_TARGET:
    3980             :             {
    3981             :                 /*
    3982             :                  * If a read-write, read-only, primary, or standby connection
    3983             :                  * is required, see if we have one.
    3984             :                  */
    3985       25596 :                 if (conn->target_server_type == SERVER_TYPE_READ_WRITE ||
    3986       25586 :                     conn->target_server_type == SERVER_TYPE_READ_ONLY)
    3987           8 :                 {
    3988             :                     bool        read_only_server;
    3989             : 
    3990             :                     /*
    3991             :                      * If the server didn't report
    3992             :                      * "default_transaction_read_only" or "in_hot_standby" at
    3993             :                      * startup, we must determine its state by sending the
    3994             :                      * query "SHOW transaction_read_only".  This GUC exists in
    3995             :                      * all server versions that support 3.0 protocol.
    3996             :                      */
    3997          20 :                     if (conn->default_transaction_read_only == PG_BOOL_UNKNOWN ||
    3998          20 :                         conn->in_hot_standby == PG_BOOL_UNKNOWN)
    3999             :                     {
    4000             :                         /*
    4001             :                          * We use PQsendQueryContinue so that
    4002             :                          * conn->errorMessage does not get cleared.  We need
    4003             :                          * to preserve any error messages related to previous
    4004             :                          * hosts we have tried and failed to connect to.
    4005             :                          */
    4006           0 :                         conn->status = CONNECTION_OK;
    4007           0 :                         if (!PQsendQueryContinue(conn,
    4008             :                                                  "SHOW transaction_read_only"))
    4009           0 :                             goto error_return;
    4010             :                         /* We'll return to this state when we have the answer */
    4011           0 :                         conn->status = CONNECTION_CHECK_WRITABLE;
    4012           0 :                         return PGRES_POLLING_READING;
    4013             :                     }
    4014             : 
    4015             :                     /* OK, we can make the test */
    4016          20 :                     read_only_server =
    4017          40 :                         (conn->default_transaction_read_only == PG_BOOL_YES ||
    4018          20 :                          conn->in_hot_standby == PG_BOOL_YES);
    4019             : 
    4020          20 :                     if ((conn->target_server_type == SERVER_TYPE_READ_WRITE) ?
    4021             :                         read_only_server : !read_only_server)
    4022             :                     {
    4023             :                         /* Wrong server state, reject and try the next host */
    4024          12 :                         if (conn->target_server_type == SERVER_TYPE_READ_WRITE)
    4025           6 :                             libpq_append_conn_error(conn, "session is read-only");
    4026             :                         else
    4027           6 :                             libpq_append_conn_error(conn, "session is not read-only");
    4028             : 
    4029             :                         /* Close connection politely. */
    4030          12 :                         conn->status = CONNECTION_OK;
    4031          12 :                         sendTerminateConn(conn);
    4032             : 
    4033             :                         /*
    4034             :                          * Try next host if any, but we don't want to consider
    4035             :                          * additional addresses for this host.
    4036             :                          */
    4037          12 :                         conn->try_next_host = true;
    4038          12 :                         goto keep_going;
    4039             :                     }
    4040             :                 }
    4041       25576 :                 else if (conn->target_server_type == SERVER_TYPE_PRIMARY ||
    4042       25566 :                          conn->target_server_type == SERVER_TYPE_STANDBY ||
    4043       25556 :                          conn->target_server_type == SERVER_TYPE_PREFER_STANDBY)
    4044             :                 {
    4045             :                     /*
    4046             :                      * If the server didn't report "in_hot_standby" at
    4047             :                      * startup, we must determine its state by sending the
    4048             :                      * query "SELECT pg_catalog.pg_is_in_recovery()".  Servers
    4049             :                      * before 9.0 don't have that function, but by the same
    4050             :                      * token they don't have any standby mode, so we may just
    4051             :                      * assume the result.
    4052             :                      */
    4053          30 :                     if (conn->sversion < 90000)
    4054           0 :                         conn->in_hot_standby = PG_BOOL_NO;
    4055             : 
    4056          30 :                     if (conn->in_hot_standby == PG_BOOL_UNKNOWN)
    4057             :                     {
    4058             :                         /*
    4059             :                          * We use PQsendQueryContinue so that
    4060             :                          * conn->errorMessage does not get cleared.  We need
    4061             :                          * to preserve any error messages related to previous
    4062             :                          * hosts we have tried and failed to connect to.
    4063             :                          */
    4064           0 :                         conn->status = CONNECTION_OK;
    4065           0 :                         if (!PQsendQueryContinue(conn,
    4066             :                                                  "SELECT pg_catalog.pg_is_in_recovery()"))
    4067           0 :                             goto error_return;
    4068             :                         /* We'll return to this state when we have the answer */
    4069           0 :                         conn->status = CONNECTION_CHECK_STANDBY;
    4070           0 :                         return PGRES_POLLING_READING;
    4071             :                     }
    4072             : 
    4073             :                     /* OK, we can make the test */
    4074          60 :                     if ((conn->target_server_type == SERVER_TYPE_PRIMARY) ?
    4075          10 :                         (conn->in_hot_standby == PG_BOOL_YES) :
    4076          20 :                         (conn->in_hot_standby == PG_BOOL_NO))
    4077             :                     {
    4078             :                         /* Wrong server state, reject and try the next host */
    4079          18 :                         if (conn->target_server_type == SERVER_TYPE_PRIMARY)
    4080           6 :                             libpq_append_conn_error(conn, "server is in hot standby mode");
    4081             :                         else
    4082          12 :                             libpq_append_conn_error(conn, "server is not in hot standby mode");
    4083             : 
    4084             :                         /* Close connection politely. */
    4085          18 :                         conn->status = CONNECTION_OK;
    4086          18 :                         sendTerminateConn(conn);
    4087             : 
    4088             :                         /*
    4089             :                          * Try next host if any, but we don't want to consider
    4090             :                          * additional addresses for this host.
    4091             :                          */
    4092          18 :                         conn->try_next_host = true;
    4093          18 :                         goto keep_going;
    4094             :                     }
    4095             :                 }
    4096             : 
    4097             :                 /*
    4098             :                  * For non cancel requests we can release the address list
    4099             :                  * now. For cancel requests we never actually resolve
    4100             :                  * addresses and instead the addrinfo exists for the lifetime
    4101             :                  * of the connection.
    4102             :                  */
    4103       25566 :                 if (!conn->cancelRequest)
    4104       25566 :                     release_conn_addrinfo(conn);
    4105             : 
    4106             :                 /*
    4107             :                  * Contents of conn->errorMessage are no longer interesting
    4108             :                  * (and it seems some clients expect it to be empty after a
    4109             :                  * successful connection).
    4110             :                  */
    4111       25566 :                 pqClearConnErrorState(conn);
    4112             : 
    4113             :                 /* We are open for business! */
    4114       25566 :                 conn->status = CONNECTION_OK;
    4115       25566 :                 return PGRES_POLLING_OK;
    4116             :             }
    4117             : 
    4118           0 :         case CONNECTION_CONSUME:
    4119             :             {
    4120             :                 /*
    4121             :                  * This state just makes sure the connection is idle after
    4122             :                  * we've obtained the result of a SHOW or SELECT query.  Once
    4123             :                  * we're clear, return to CONNECTION_CHECK_TARGET state to
    4124             :                  * decide what to do next.  We must transiently set status =
    4125             :                  * CONNECTION_OK in order to use the result-consuming
    4126             :                  * subroutines.
    4127             :                  */
    4128           0 :                 conn->status = CONNECTION_OK;
    4129           0 :                 if (!PQconsumeInput(conn))
    4130           0 :                     goto error_return;
    4131             : 
    4132           0 :                 if (PQisBusy(conn))
    4133             :                 {
    4134           0 :                     conn->status = CONNECTION_CONSUME;
    4135           0 :                     return PGRES_POLLING_READING;
    4136             :                 }
    4137             : 
    4138             :                 /* Call PQgetResult() again until we get a NULL result */
    4139           0 :                 res = PQgetResult(conn);
    4140           0 :                 if (res != NULL)
    4141             :                 {
    4142           0 :                     PQclear(res);
    4143           0 :                     conn->status = CONNECTION_CONSUME;
    4144           0 :                     return PGRES_POLLING_READING;
    4145             :                 }
    4146             : 
    4147           0 :                 conn->status = CONNECTION_CHECK_TARGET;
    4148           0 :                 goto keep_going;
    4149             :             }
    4150             : 
    4151           0 :         case CONNECTION_CHECK_WRITABLE:
    4152             :             {
    4153             :                 /*
    4154             :                  * Waiting for result of "SHOW transaction_read_only".  We
    4155             :                  * must transiently set status = CONNECTION_OK in order to use
    4156             :                  * the result-consuming subroutines.
    4157             :                  */
    4158           0 :                 conn->status = CONNECTION_OK;
    4159           0 :                 if (!PQconsumeInput(conn))
    4160           0 :                     goto error_return;
    4161             : 
    4162           0 :                 if (PQisBusy(conn))
    4163             :                 {
    4164           0 :                     conn->status = CONNECTION_CHECK_WRITABLE;
    4165           0 :                     return PGRES_POLLING_READING;
    4166             :                 }
    4167             : 
    4168           0 :                 res = PQgetResult(conn);
    4169           0 :                 if (res && PQresultStatus(res) == PGRES_TUPLES_OK &&
    4170           0 :                     PQntuples(res) == 1)
    4171             :                 {
    4172           0 :                     char       *val = PQgetvalue(res, 0, 0);
    4173             : 
    4174             :                     /*
    4175             :                      * "transaction_read_only = on" proves that at least one
    4176             :                      * of default_transaction_read_only and in_hot_standby is
    4177             :                      * on, but we don't actually know which.  We don't care
    4178             :                      * though for the purpose of identifying a read-only
    4179             :                      * session, so satisfy the CONNECTION_CHECK_TARGET code by
    4180             :                      * claiming they are both on.  On the other hand, if it's
    4181             :                      * a read-write session, they are certainly both off.
    4182             :                      */
    4183           0 :                     if (strncmp(val, "on", 2) == 0)
    4184             :                     {
    4185           0 :                         conn->default_transaction_read_only = PG_BOOL_YES;
    4186           0 :                         conn->in_hot_standby = PG_BOOL_YES;
    4187             :                     }
    4188             :                     else
    4189             :                     {
    4190           0 :                         conn->default_transaction_read_only = PG_BOOL_NO;
    4191           0 :                         conn->in_hot_standby = PG_BOOL_NO;
    4192             :                     }
    4193           0 :                     PQclear(res);
    4194             : 
    4195             :                     /* Finish reading messages before continuing */
    4196           0 :                     conn->status = CONNECTION_CONSUME;
    4197           0 :                     goto keep_going;
    4198             :                 }
    4199             : 
    4200             :                 /* Something went wrong with "SHOW transaction_read_only". */
    4201           0 :                 PQclear(res);
    4202             : 
    4203             :                 /* Append error report to conn->errorMessage. */
    4204           0 :                 libpq_append_conn_error(conn, "\"%s\" failed",
    4205             :                                         "SHOW transaction_read_only");
    4206             : 
    4207             :                 /* Close connection politely. */
    4208           0 :                 conn->status = CONNECTION_OK;
    4209           0 :                 sendTerminateConn(conn);
    4210             : 
    4211             :                 /* Try next host. */
    4212           0 :                 conn->try_next_host = true;
    4213           0 :                 goto keep_going;
    4214             :             }
    4215             : 
    4216           0 :         case CONNECTION_CHECK_STANDBY:
    4217             :             {
    4218             :                 /*
    4219             :                  * Waiting for result of "SELECT pg_is_in_recovery()".  We
    4220             :                  * must transiently set status = CONNECTION_OK in order to use
    4221             :                  * the result-consuming subroutines.
    4222             :                  */
    4223           0 :                 conn->status = CONNECTION_OK;
    4224           0 :                 if (!PQconsumeInput(conn))
    4225           0 :                     goto error_return;
    4226             : 
    4227           0 :                 if (PQisBusy(conn))
    4228             :                 {
    4229           0 :                     conn->status = CONNECTION_CHECK_STANDBY;
    4230           0 :                     return PGRES_POLLING_READING;
    4231             :                 }
    4232             : 
    4233           0 :                 res = PQgetResult(conn);
    4234           0 :                 if (res && PQresultStatus(res) == PGRES_TUPLES_OK &&
    4235           0 :                     PQntuples(res) == 1)
    4236             :                 {
    4237           0 :                     char       *val = PQgetvalue(res, 0, 0);
    4238             : 
    4239           0 :                     if (strncmp(val, "t", 1) == 0)
    4240           0 :                         conn->in_hot_standby = PG_BOOL_YES;
    4241             :                     else
    4242           0 :                         conn->in_hot_standby = PG_BOOL_NO;
    4243           0 :                     PQclear(res);
    4244             : 
    4245             :                     /* Finish reading messages before continuing */
    4246           0 :                     conn->status = CONNECTION_CONSUME;
    4247           0 :                     goto keep_going;
    4248             :                 }
    4249             : 
    4250             :                 /* Something went wrong with "SELECT pg_is_in_recovery()". */
    4251           0 :                 PQclear(res);
    4252             : 
    4253             :                 /* Append error report to conn->errorMessage. */
    4254           0 :                 libpq_append_conn_error(conn, "\"%s\" failed",
    4255             :                                         "SELECT pg_is_in_recovery()");
    4256             : 
    4257             :                 /* Close connection politely. */
    4258           0 :                 conn->status = CONNECTION_OK;
    4259           0 :                 sendTerminateConn(conn);
    4260             : 
    4261             :                 /* Try next host. */
    4262           0 :                 conn->try_next_host = true;
    4263           0 :                 goto keep_going;
    4264             :             }
    4265             : 
    4266           0 :         default:
    4267           0 :             libpq_append_conn_error(conn,
    4268             :                                     "invalid connection state %d, probably indicative of memory corruption",
    4269           0 :                                     conn->status);
    4270           0 :             goto error_return;
    4271             :     }
    4272             : 
    4273             :     /* Unreachable */
    4274             : 
    4275         908 : error_return:
    4276             : 
    4277             :     /*
    4278             :      * We used to close the socket at this point, but that makes it awkward
    4279             :      * for those above us if they wish to remove this socket from their own
    4280             :      * records (an fd_set for example).  We'll just have this socket closed
    4281             :      * when PQfinish is called (which is compulsory even after an error, since
    4282             :      * the connection structure must be freed).
    4283             :      */
    4284         908 :     conn->status = CONNECTION_BAD;
    4285         908 :     return PGRES_POLLING_FAILED;
    4286             : }
    4287             : 
    4288             : /*
    4289             :  * Initialize the state machine for negotiating encryption
    4290             :  */
    4291             : static bool
    4292       26532 : init_allowed_encryption_methods(PGconn *conn)
    4293             : {
    4294       26532 :     if (conn->raddr.addr.ss_family == AF_UNIX)
    4295             :     {
    4296             :         /* Don't request SSL or GSSAPI over Unix sockets */
    4297       25942 :         conn->allowed_enc_methods &= ~(ENC_SSL | ENC_GSSAPI);
    4298             : 
    4299             :         /*
    4300             :          * XXX: we probably should not do this. sslmode=require works
    4301             :          * differently
    4302             :          */
    4303       25942 :         if (conn->gssencmode[0] == 'r')
    4304             :         {
    4305           0 :             libpq_append_conn_error(conn,
    4306             :                                     "GSSAPI encryption required but it is not supported over a local socket");
    4307           0 :             conn->allowed_enc_methods = 0;
    4308           0 :             conn->current_enc_method = ENC_ERROR;
    4309           0 :             return false;
    4310             :         }
    4311             : 
    4312       25942 :         conn->allowed_enc_methods = ENC_PLAINTEXT;
    4313       25942 :         conn->current_enc_method = ENC_PLAINTEXT;
    4314       25942 :         return true;
    4315             :     }
    4316             : 
    4317             :     /* initialize based on sslmode and gssencmode */
    4318         590 :     conn->allowed_enc_methods = 0;
    4319             : 
    4320             : #ifdef USE_SSL
    4321             :     /* sslmode anything but 'disable', and GSSAPI not required */
    4322         590 :     if (conn->sslmode[0] != 'd' && conn->gssencmode[0] != 'r')
    4323             :     {
    4324         578 :         conn->allowed_enc_methods |= ENC_SSL;
    4325             :     }
    4326             : #endif
    4327             : 
    4328             : #ifdef ENABLE_GSS
    4329             :     if (conn->gssencmode[0] != 'd')
    4330             :         conn->allowed_enc_methods |= ENC_GSSAPI;
    4331             : #endif
    4332             : 
    4333         590 :     if ((conn->sslmode[0] == 'd' || conn->sslmode[0] == 'p' || conn->sslmode[0] == 'a') &&
    4334         348 :         (conn->gssencmode[0] == 'd' || conn->gssencmode[0] == 'p'))
    4335             :     {
    4336         348 :         conn->allowed_enc_methods |= ENC_PLAINTEXT;
    4337             :     }
    4338             : 
    4339         590 :     return select_next_encryption_method(conn, false);
    4340             : }
    4341             : 
    4342             : /*
    4343             :  * Out-of-line portion of the ENCRYPTION_NEGOTIATION_FAILED() macro in the
    4344             :  * PQconnectPoll state machine.
    4345             :  *
    4346             :  * Return value:
    4347             :  *  0: connection failed and we are out of encryption methods to try. return an error
    4348             :  *  1: Retry with next connection method. The TCP connection is still valid and in
    4349             :  *     known state, so we can proceed with the negotiating next method without
    4350             :  *     reconnecting.
    4351             :  *  2: Disconnect, and retry with next connection method.
    4352             :  *
    4353             :  * conn->current_enc_method is updated to the next method to try.
    4354             :  */
    4355             : #if defined(USE_SSL) || defined(ENABLE_GSS)
    4356             : static int
    4357         296 : encryption_negotiation_failed(PGconn *conn)
    4358             : {
    4359             :     Assert((conn->failed_enc_methods & conn->current_enc_method) == 0);
    4360         296 :     conn->failed_enc_methods |= conn->current_enc_method;
    4361             : 
    4362         296 :     if (select_next_encryption_method(conn, true))
    4363             :     {
    4364             :         /* An existing connection cannot be reused for direct SSL */
    4365         292 :         if (conn->current_enc_method == ENC_SSL && conn->sslnegotiation[0] == 'd')
    4366           0 :             return 2;
    4367             :         else
    4368         292 :             return 1;
    4369             :     }
    4370             :     else
    4371           4 :         return 0;
    4372             : }
    4373             : #endif
    4374             : 
    4375             : /*
    4376             :  * Out-of-line portion of the CONNECTION_FAILED() macro
    4377             :  *
    4378             :  * Returns true, if we should reconnect and retry with a different encryption
    4379             :  * method.  conn->current_enc_method is updated to the next method to try.
    4380             :  */
    4381             : static bool
    4382         154 : connection_failed(PGconn *conn)
    4383             : {
    4384             :     Assert((conn->failed_enc_methods & conn->current_enc_method) == 0);
    4385         154 :     conn->failed_enc_methods |= conn->current_enc_method;
    4386             : 
    4387         154 :     return select_next_encryption_method(conn, false);
    4388             : }
    4389             : 
    4390             : /*
    4391             :  * Choose the next encryption method to try. If this is a retry,
    4392             :  * conn->failed_enc_methods has already been updated. The function sets
    4393             :  * conn->current_enc_method to the next method to try. Returns false if no
    4394             :  * encryption methods remain.
    4395             :  */
    4396             : static bool
    4397        1040 : select_next_encryption_method(PGconn *conn, bool have_valid_connection)
    4398             : {
    4399             :     int         remaining_methods;
    4400             : 
    4401             : #define SELECT_NEXT_METHOD(method) \
    4402             :     do { \
    4403             :         if ((remaining_methods & method) != 0) \
    4404             :         { \
    4405             :             conn->current_enc_method = method; \
    4406             :             return true; \
    4407             :         } \
    4408             :     } while (false)
    4409             : 
    4410        1040 :     remaining_methods = conn->allowed_enc_methods & ~conn->failed_enc_methods;
    4411             : 
    4412             :     /*
    4413             :      * Try GSSAPI before SSL
    4414             :      */
    4415             : #ifdef ENABLE_GSS
    4416             :     if ((remaining_methods & ENC_GSSAPI) != 0)
    4417             :     {
    4418             :         /*
    4419             :          * If GSSAPI encryption is enabled, then call pg_GSS_have_cred_cache()
    4420             :          * which will return true if we can acquire credentials (and give us a
    4421             :          * handle to use in conn->gcred), and then send a packet to the server
    4422             :          * asking for GSSAPI Encryption (and skip past SSL negotiation and
    4423             :          * regular startup below).
    4424             :          */
    4425             :         if (!conn->gctx)
    4426             :         {
    4427             :             if (!pg_GSS_have_cred_cache(&conn->gcred))
    4428             :             {
    4429             :                 conn->allowed_enc_methods &= ~ENC_GSSAPI;
    4430             :                 remaining_methods &= ~ENC_GSSAPI;
    4431             : 
    4432             :                 if (conn->gssencmode[0] == 'r')
    4433             :                 {
    4434             :                     libpq_append_conn_error(conn,
    4435             :                                             "GSSAPI encryption required but no credential cache");
    4436             :                 }
    4437             :             }
    4438             :         }
    4439             :     }
    4440             : 
    4441             :     SELECT_NEXT_METHOD(ENC_GSSAPI);
    4442             : #endif
    4443             : 
    4444             :     /*
    4445             :      * The order between SSL encryption and plaintext depends on sslmode. With
    4446             :      * sslmode=allow, try plaintext connection before SSL. With
    4447             :      * sslmode=prefer, it's the other way round. With other modes, we only try
    4448             :      * plaintext or SSL connections so the order they're listed here doesn't
    4449             :      * matter.
    4450             :      */
    4451        1040 :     if (conn->sslmode[0] == 'a')
    4452          14 :         SELECT_NEXT_METHOD(ENC_PLAINTEXT);
    4453             : 
    4454        1030 :     SELECT_NEXT_METHOD(ENC_SSL);
    4455             : 
    4456         464 :     if (conn->sslmode[0] != 'a')
    4457         464 :         SELECT_NEXT_METHOD(ENC_PLAINTEXT);
    4458             : 
    4459             :     /* No more options */
    4460         152 :     conn->current_enc_method = ENC_ERROR;
    4461         152 :     return false;
    4462             : #undef SELECT_NEXT_METHOD
    4463             : }
    4464             : 
    4465             : /*
    4466             :  * internal_ping
    4467             :  *      Determine if a server is running and if we can connect to it.
    4468             :  *
    4469             :  * The argument is a connection that's been started, but not completed.
    4470             :  */
    4471             : static PGPing
    4472         632 : internal_ping(PGconn *conn)
    4473             : {
    4474             :     /* Say "no attempt" if we never got to PQconnectPoll */
    4475         632 :     if (!conn || !conn->options_valid)
    4476           0 :         return PQPING_NO_ATTEMPT;
    4477             : 
    4478             :     /* Attempt to complete the connection */
    4479         632 :     if (conn->status != CONNECTION_BAD)
    4480         370 :         (void) pqConnectDBComplete(conn);
    4481             : 
    4482             :     /* Definitely OK if we succeeded */
    4483         632 :     if (conn->status != CONNECTION_BAD)
    4484         178 :         return PQPING_OK;
    4485             : 
    4486             :     /*
    4487             :      * Here begins the interesting part of "ping": determine the cause of the
    4488             :      * failure in sufficient detail to decide what to return.  We do not want
    4489             :      * to report that the server is not up just because we didn't have a valid
    4490             :      * password, for example.  In fact, any sort of authentication request
    4491             :      * implies the server is up.  (We need this check since the libpq side of
    4492             :      * things might have pulled the plug on the connection before getting an
    4493             :      * error as such from the postmaster.)
    4494             :      */
    4495         454 :     if (conn->auth_req_received)
    4496           0 :         return PQPING_OK;
    4497             : 
    4498             :     /*
    4499             :      * If we failed to get any ERROR response from the postmaster, report
    4500             :      * PQPING_NO_RESPONSE.  This result could be somewhat misleading for a
    4501             :      * pre-7.4 server, since it won't send back a SQLSTATE, but those are long
    4502             :      * out of support.  Another corner case where the server could return a
    4503             :      * failure without a SQLSTATE is fork failure, but PQPING_NO_RESPONSE
    4504             :      * isn't totally unreasonable for that anyway.  We expect that every other
    4505             :      * failure case in a modern server will produce a report with a SQLSTATE.
    4506             :      *
    4507             :      * NOTE: whenever we get around to making libpq generate SQLSTATEs for
    4508             :      * client-side errors, we should either not store those into
    4509             :      * last_sqlstate, or add an extra flag so we can tell client-side errors
    4510             :      * apart from server-side ones.
    4511             :      */
    4512         454 :     if (strlen(conn->last_sqlstate) != 5)
    4513         264 :         return PQPING_NO_RESPONSE;
    4514             : 
    4515             :     /*
    4516             :      * Report PQPING_REJECT if server says it's not accepting connections.
    4517             :      */
    4518         190 :     if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0)
    4519         190 :         return PQPING_REJECT;
    4520             : 
    4521             :     /*
    4522             :      * Any other SQLSTATE can be taken to indicate that the server is up.
    4523             :      * Presumably it didn't like our username, password, or database name; or
    4524             :      * perhaps it had some transient failure, but that should not be taken as
    4525             :      * meaning "it's down".
    4526             :      */
    4527           0 :     return PQPING_OK;
    4528             : }
    4529             : 
    4530             : 
    4531             : /*
    4532             :  * pqMakeEmptyPGconn
    4533             :  *   - create a PGconn data structure with (as yet) no interesting data
    4534             :  */
    4535             : PGconn *
    4536       26570 : pqMakeEmptyPGconn(void)
    4537             : {
    4538             :     PGconn     *conn;
    4539             : 
    4540             : #ifdef WIN32
    4541             : 
    4542             :     /*
    4543             :      * Make sure socket support is up and running in this process.
    4544             :      *
    4545             :      * Note: the Windows documentation says that we should eventually do a
    4546             :      * matching WSACleanup() call, but experience suggests that that is at
    4547             :      * least as likely to cause problems as fix them.  So we don't.
    4548             :      */
    4549             :     static bool wsastartup_done = false;
    4550             : 
    4551             :     if (!wsastartup_done)
    4552             :     {
    4553             :         WSADATA     wsaData;
    4554             : 
    4555             :         if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    4556             :             return NULL;
    4557             :         wsastartup_done = true;
    4558             :     }
    4559             : 
    4560             :     /* Forget any earlier error */
    4561             :     WSASetLastError(0);
    4562             : #endif                          /* WIN32 */
    4563             : 
    4564       26570 :     conn = (PGconn *) malloc(sizeof(PGconn));
    4565       26570 :     if (conn == NULL)
    4566           0 :         return conn;
    4567             : 
    4568             :     /* Zero all pointers and booleans */
    4569       26570 :     MemSet(conn, 0, sizeof(PGconn));
    4570             : 
    4571             :     /* install default notice hooks */
    4572       26570 :     conn->noticeHooks.noticeRec = defaultNoticeReceiver;
    4573       26570 :     conn->noticeHooks.noticeProc = defaultNoticeProcessor;
    4574             : 
    4575       26570 :     conn->status = CONNECTION_BAD;
    4576       26570 :     conn->asyncStatus = PGASYNC_IDLE;
    4577       26570 :     conn->pipelineStatus = PQ_PIPELINE_OFF;
    4578       26570 :     conn->xactStatus = PQTRANS_IDLE;
    4579       26570 :     conn->options_valid = false;
    4580       26570 :     conn->nonblocking = false;
    4581       26570 :     conn->client_encoding = PG_SQL_ASCII;
    4582       26570 :     conn->std_strings = false;   /* unless server says differently */
    4583       26570 :     conn->default_transaction_read_only = PG_BOOL_UNKNOWN;
    4584       26570 :     conn->in_hot_standby = PG_BOOL_UNKNOWN;
    4585       26570 :     conn->scram_sha_256_iterations = SCRAM_SHA_256_DEFAULT_ITERATIONS;
    4586       26570 :     conn->verbosity = PQERRORS_DEFAULT;
    4587       26570 :     conn->show_context = PQSHOW_CONTEXT_ERRORS;
    4588       26570 :     conn->sock = PGINVALID_SOCKET;
    4589       26570 :     conn->Pfdebug = NULL;
    4590             : 
    4591             :     /*
    4592             :      * We try to send at least 8K at a time, which is the usual size of pipe
    4593             :      * buffers on Unix systems.  That way, when we are sending a large amount
    4594             :      * of data, we avoid incurring extra kernel context swaps for partial
    4595             :      * bufferloads.  The output buffer is initially made 16K in size, and we
    4596             :      * try to dump it after accumulating 8K.
    4597             :      *
    4598             :      * With the same goal of minimizing context swaps, the input buffer will
    4599             :      * be enlarged anytime it has less than 8K free, so we initially allocate
    4600             :      * twice that.
    4601             :      */
    4602       26570 :     conn->inBufSize = 16 * 1024;
    4603       26570 :     conn->inBuffer = (char *) malloc(conn->inBufSize);
    4604       26570 :     conn->outBufSize = 16 * 1024;
    4605       26570 :     conn->outBuffer = (char *) malloc(conn->outBufSize);
    4606       26570 :     conn->rowBufLen = 32;
    4607       26570 :     conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue));
    4608       26570 :     initPQExpBuffer(&conn->errorMessage);
    4609       26570 :     initPQExpBuffer(&conn->workBuffer);
    4610             : 
    4611       26570 :     if (conn->inBuffer == NULL ||
    4612       26570 :         conn->outBuffer == NULL ||
    4613       26570 :         conn->rowBuf == NULL ||
    4614       26570 :         PQExpBufferBroken(&conn->errorMessage) ||
    4615       26570 :         PQExpBufferBroken(&conn->workBuffer))
    4616             :     {
    4617             :         /* out of memory already :-( */
    4618           0 :         freePGconn(conn);
    4619           0 :         conn = NULL;
    4620             :     }
    4621             : 
    4622       26570 :     return conn;
    4623             : }
    4624             : 
    4625             : /*
    4626             :  * freePGconn
    4627             :  *   - free an idle (closed) PGconn data structure
    4628             :  *
    4629             :  * NOTE: this should not overlap any functionality with pqClosePGconn().
    4630             :  * Clearing/resetting of transient state belongs there; what we do here is
    4631             :  * release data that is to be held for the life of the PGconn structure.
    4632             :  * If a value ought to be cleared/freed during PQreset(), do it there not here.
    4633             :  */
    4634             : static void
    4635       26168 : freePGconn(PGconn *conn)
    4636             : {
    4637             :     /* let any event procs clean up their state data */
    4638       26168 :     for (int i = 0; i < conn->nEvents; i++)
    4639             :     {
    4640             :         PGEventConnDestroy evt;
    4641             : 
    4642           0 :         evt.conn = conn;
    4643           0 :         (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt,
    4644           0 :                                     conn->events[i].passThrough);
    4645           0 :         free(conn->events[i].name);
    4646             :     }
    4647             : 
    4648       26168 :     release_conn_addrinfo(conn);
    4649       26168 :     pqReleaseConnHosts(conn);
    4650             : 
    4651       26168 :     free(conn->client_encoding_initial);
    4652       26168 :     free(conn->events);
    4653       26168 :     free(conn->pghost);
    4654       26168 :     free(conn->pghostaddr);
    4655       26168 :     free(conn->pgport);
    4656       26168 :     free(conn->connect_timeout);
    4657       26168 :     free(conn->pgtcp_user_timeout);
    4658       26168 :     free(conn->pgoptions);
    4659       26168 :     free(conn->appname);
    4660       26168 :     free(conn->fbappname);
    4661       26168 :     free(conn->dbName);
    4662       26168 :     free(conn->replication);
    4663       26168 :     free(conn->pguser);
    4664       26168 :     if (conn->pgpass)
    4665             :     {
    4666         318 :         explicit_bzero(conn->pgpass, strlen(conn->pgpass));
    4667         318 :         free(conn->pgpass);
    4668             :     }
    4669       26168 :     free(conn->pgpassfile);
    4670       26168 :     free(conn->channel_binding);
    4671       26168 :     free(conn->keepalives);
    4672       26168 :     free(conn->keepalives_idle);
    4673       26168 :     free(conn->keepalives_interval);
    4674       26168 :     free(conn->keepalives_count);
    4675       26168 :     free(conn->sslmode);
    4676       26168 :     free(conn->sslnegotiation);
    4677       26168 :     free(conn->sslcert);
    4678       26168 :     free(conn->sslkey);
    4679       26168 :     if (conn->sslpassword)
    4680             :     {
    4681           6 :         explicit_bzero(conn->sslpassword, strlen(conn->sslpassword));
    4682           6 :         free(conn->sslpassword);
    4683             :     }
    4684       26168 :     free(conn->sslcertmode);
    4685       26168 :     free(conn->sslrootcert);
    4686       26168 :     free(conn->sslcrl);
    4687       26168 :     free(conn->sslcrldir);
    4688       26168 :     free(conn->sslcompression);
    4689       26168 :     free(conn->sslsni);
    4690       26168 :     free(conn->requirepeer);
    4691       26168 :     free(conn->require_auth);
    4692       26168 :     free(conn->ssl_min_protocol_version);
    4693       26168 :     free(conn->ssl_max_protocol_version);
    4694       26168 :     free(conn->gssencmode);
    4695       26168 :     free(conn->krbsrvname);
    4696       26168 :     free(conn->gsslib);
    4697       26168 :     free(conn->gssdelegation);
    4698       26168 :     free(conn->connip);
    4699             :     /* Note that conn->Pfdebug is not ours to close or free */
    4700       26168 :     free(conn->write_err_msg);
    4701       26168 :     free(conn->inBuffer);
    4702       26168 :     free(conn->outBuffer);
    4703       26168 :     free(conn->rowBuf);
    4704       26168 :     free(conn->target_session_attrs);
    4705       26168 :     free(conn->load_balance_hosts);
    4706       26168 :     termPQExpBuffer(&conn->errorMessage);
    4707       26168 :     termPQExpBuffer(&conn->workBuffer);
    4708             : 
    4709       26168 :     free(conn);
    4710       26168 : }
    4711             : 
    4712             : /*
    4713             :  * pqReleaseConnHosts
    4714             :  *   - Free the host list in the PGconn.
    4715             :  */
    4716             : void
    4717       26176 : pqReleaseConnHosts(PGconn *conn)
    4718             : {
    4719       26176 :     if (conn->connhost)
    4720             :     {
    4721       52610 :         for (int i = 0; i < conn->nconnhost; ++i)
    4722             :         {
    4723       26438 :             free(conn->connhost[i].host);
    4724       26438 :             free(conn->connhost[i].hostaddr);
    4725       26438 :             free(conn->connhost[i].port);
    4726       26438 :             if (conn->connhost[i].password != NULL)
    4727             :             {
    4728          14 :                 explicit_bzero(conn->connhost[i].password,
    4729          14 :                                strlen(conn->connhost[i].password));
    4730          14 :                 free(conn->connhost[i].password);
    4731             :             }
    4732             :         }
    4733       26172 :         free(conn->connhost);
    4734             :     }
    4735       26176 : }
    4736             : 
    4737             : /*
    4738             :  * store_conn_addrinfo
    4739             :  *   - copy addrinfo to PGconn object
    4740             :  *
    4741             :  * Copies the addrinfos from addrlist to the PGconn object such that the
    4742             :  * addrinfos can be manipulated by libpq. Returns a positive integer on
    4743             :  * failure, otherwise zero.
    4744             :  */
    4745             : static int
    4746       26514 : store_conn_addrinfo(PGconn *conn, struct addrinfo *addrlist)
    4747             : {
    4748       26514 :     struct addrinfo *ai = addrlist;
    4749             : 
    4750       26514 :     conn->whichaddr = 0;
    4751             : 
    4752       26514 :     conn->naddr = 0;
    4753       53318 :     while (ai)
    4754             :     {
    4755       26804 :         ai = ai->ai_next;
    4756       26804 :         conn->naddr++;
    4757             :     }
    4758             : 
    4759       26514 :     conn->addr = calloc(conn->naddr, sizeof(AddrInfo));
    4760       26514 :     if (conn->addr == NULL)
    4761             :     {
    4762           0 :         libpq_append_conn_error(conn, "out of memory");
    4763           0 :         return 1;
    4764             :     }
    4765             : 
    4766       26514 :     ai = addrlist;
    4767       53318 :     for (int i = 0; i < conn->naddr; i++)
    4768             :     {
    4769       26804 :         conn->addr[i].family = ai->ai_family;
    4770             : 
    4771       26804 :         memcpy(&conn->addr[i].addr.addr, ai->ai_addr,
    4772       26804 :                ai->ai_addrlen);
    4773       26804 :         conn->addr[i].addr.salen = ai->ai_addrlen;
    4774       26804 :         ai = ai->ai_next;
    4775             :     }
    4776             : 
    4777       26514 :     return 0;
    4778             : }
    4779             : 
    4780             : /*
    4781             :  * release_conn_addrinfo
    4782             :  *   - Free any addrinfo list in the PGconn.
    4783             :  */
    4784             : static void
    4785      104414 : release_conn_addrinfo(PGconn *conn)
    4786             : {
    4787      104414 :     if (conn->addr)
    4788             :     {
    4789       26502 :         free(conn->addr);
    4790       26502 :         conn->addr = NULL;
    4791             :     }
    4792      104414 : }
    4793             : 
    4794             : /*
    4795             :  * sendTerminateConn
    4796             :  *   - Send a terminate message to backend.
    4797             :  */
    4798             : static void
    4799       26200 : sendTerminateConn(PGconn *conn)
    4800             : {
    4801             :     /*
    4802             :      * The Postgres cancellation protocol does not have a notion of a
    4803             :      * Terminate message, so don't send one.
    4804             :      */
    4805       26200 :     if (conn->cancelRequest)
    4806          10 :         return;
    4807             : 
    4808             :     /*
    4809             :      * Note that the protocol doesn't allow us to send Terminate messages
    4810             :      * during the startup phase.
    4811             :      */
    4812       26190 :     if (conn->sock != PGINVALID_SOCKET && conn->status == CONNECTION_OK)
    4813             :     {
    4814             :         /*
    4815             :          * Try to send "close connection" message to backend. Ignore any
    4816             :          * error.
    4817             :          */
    4818       25044 :         pqPutMsgStart(PqMsg_Terminate, conn);
    4819       25044 :         pqPutMsgEnd(conn);
    4820       25044 :         (void) pqFlush(conn);
    4821             :     }
    4822             : }
    4823             : 
    4824             : /*
    4825             :  * pqClosePGconn
    4826             :  *   - properly close a connection to the backend
    4827             :  *
    4828             :  * This should reset or release all transient state, but NOT the connection
    4829             :  * parameters.  On exit, the PGconn should be in condition to start a fresh
    4830             :  * connection with the same parameters (see PQreset()).
    4831             :  */
    4832             : void
    4833       26170 : pqClosePGconn(PGconn *conn)
    4834             : {
    4835             :     /*
    4836             :      * If possible, send Terminate message to close the connection politely.
    4837             :      */
    4838       26170 :     sendTerminateConn(conn);
    4839             : 
    4840             :     /*
    4841             :      * Must reset the blocking status so a possible reconnect will work.
    4842             :      *
    4843             :      * Don't call PQsetnonblocking() because it will fail if it's unable to
    4844             :      * flush the connection.
    4845             :      */
    4846       26170 :     conn->nonblocking = false;
    4847             : 
    4848             :     /*
    4849             :      * Close the connection, reset all transient state, flush I/O buffers.
    4850             :      * Note that this includes clearing conn's error state; we're no longer
    4851             :      * interested in any failures associated with the old connection, and we
    4852             :      * want a clean slate for any new connection attempt.
    4853             :      */
    4854       26170 :     pqDropConnection(conn, true);
    4855       26170 :     conn->status = CONNECTION_BAD;   /* Well, not really _bad_ - just absent */
    4856       26170 :     conn->asyncStatus = PGASYNC_IDLE;
    4857       26170 :     conn->xactStatus = PQTRANS_IDLE;
    4858       26170 :     conn->pipelineStatus = PQ_PIPELINE_OFF;
    4859       26170 :     pqClearAsyncResult(conn);   /* deallocate result */
    4860       26170 :     pqClearConnErrorState(conn);
    4861             : 
    4862             :     /*
    4863             :      * Release addrinfo, but since cancel requests never change their addrinfo
    4864             :      * we don't do that. Otherwise we would have to rebuild it during a
    4865             :      * PQcancelReset.
    4866             :      */
    4867       26170 :     if (!conn->cancelRequest)
    4868       26160 :         release_conn_addrinfo(conn);
    4869             : 
    4870             :     /* Reset all state obtained from server, too */
    4871       26170 :     pqDropServerData(conn);
    4872       26170 : }
    4873             : 
    4874             : /*
    4875             :  * PQfinish: properly close a connection to the backend. Also frees
    4876             :  * the PGconn data structure so it shouldn't be re-used after this.
    4877             :  */
    4878             : void
    4879       26168 : PQfinish(PGconn *conn)
    4880             : {
    4881       26168 :     if (conn)
    4882             :     {
    4883       26168 :         pqClosePGconn(conn);
    4884       26168 :         freePGconn(conn);
    4885             :     }
    4886       26168 : }
    4887             : 
    4888             : /*
    4889             :  * PQreset: resets the connection to the backend by closing the
    4890             :  * existing connection and creating a new one.
    4891             :  */
    4892             : void
    4893           0 : PQreset(PGconn *conn)
    4894             : {
    4895           0 :     if (conn)
    4896             :     {
    4897           0 :         pqClosePGconn(conn);
    4898             : 
    4899           0 :         if (pqConnectDBStart(conn) && pqConnectDBComplete(conn))
    4900             :         {
    4901             :             /*
    4902             :              * Notify event procs of successful reset.
    4903             :              */
    4904             :             int         i;
    4905             : 
    4906           0 :             for (i = 0; i < conn->nEvents; i++)
    4907             :             {
    4908             :                 PGEventConnReset evt;
    4909             : 
    4910           0 :                 evt.conn = conn;
    4911           0 :                 (void) conn->events[i].proc(PGEVT_CONNRESET, &evt,
    4912           0 :                                             conn->events[i].passThrough);
    4913             :             }
    4914             :         }
    4915             :     }
    4916           0 : }
    4917             : 
    4918             : 
    4919             : /*
    4920             :  * PQresetStart:
    4921             :  * resets the connection to the backend
    4922             :  * closes the existing connection and makes a new one
    4923             :  * Returns 1 on success, 0 on failure.
    4924             :  */
    4925             : int
    4926           0 : PQresetStart(PGconn *conn)
    4927             : {
    4928           0 :     if (conn)
    4929             :     {
    4930           0 :         pqClosePGconn(conn);
    4931             : 
    4932           0 :         return pqConnectDBStart(conn);
    4933             :     }
    4934             : 
    4935           0 :     return 0;
    4936             : }
    4937             : 
    4938             : 
    4939             : /*
    4940             :  * PQresetPoll:
    4941             :  * resets the connection to the backend
    4942             :  * closes the existing connection and makes a new one
    4943             :  */
    4944             : PostgresPollingStatusType
    4945           0 : PQresetPoll(PGconn *conn)
    4946             : {
    4947           0 :     if (conn)
    4948             :     {
    4949           0 :         PostgresPollingStatusType status = PQconnectPoll(conn);
    4950             : 
    4951           0 :         if (status == PGRES_POLLING_OK)
    4952             :         {
    4953             :             /*
    4954             :              * Notify event procs of successful reset.
    4955             :              */
    4956             :             int         i;
    4957             : 
    4958           0 :             for (i = 0; i < conn->nEvents; i++)
    4959             :             {
    4960             :                 PGEventConnReset evt;
    4961             : 
    4962           0 :                 evt.conn = conn;
    4963           0 :                 (void) conn->events[i].proc(PGEVT_CONNRESET, &evt,
    4964           0 :                                             conn->events[i].passThrough);
    4965             :             }
    4966             :         }
    4967             : 
    4968           0 :         return status;
    4969             :     }
    4970             : 
    4971           0 :     return PGRES_POLLING_FAILED;
    4972             : }
    4973             : 
    4974             : /*
    4975             :  * pqPacketSend() -- convenience routine to send a message to server.
    4976             :  *
    4977             :  * pack_type: the single-byte message type code.  (Pass zero for startup
    4978             :  * packets, which have no message type code.)
    4979             :  *
    4980             :  * buf, buf_len: contents of message.  The given length includes only what
    4981             :  * is in buf; the message type and message length fields are added here.
    4982             :  *
    4983             :  * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise.
    4984             :  * SIDE_EFFECTS: may block.
    4985             :  */
    4986             : int
    4987       26756 : pqPacketSend(PGconn *conn, char pack_type,
    4988             :              const void *buf, size_t buf_len)
    4989             : {
    4990             :     /* Start the message. */
    4991       26756 :     if (pqPutMsgStart(pack_type, conn))
    4992           0 :         return STATUS_ERROR;
    4993             : 
    4994             :     /* Send the message body. */
    4995       26756 :     if (pqPutnchar(buf, buf_len, conn))
    4996           0 :         return STATUS_ERROR;
    4997             : 
    4998             :     /* Finish the message. */
    4999       26756 :     if (pqPutMsgEnd(conn))
    5000           0 :         return STATUS_ERROR;
    5001             : 
    5002             :     /* Flush to ensure backend gets it. */
    5003       26756 :     if (pqFlush(conn))
    5004           0 :         return STATUS_ERROR;
    5005             : 
    5006       26756 :     return STATUS_OK;
    5007             : }
    5008             : 
    5009             : #ifdef USE_LDAP
    5010             : 
    5011             : #define LDAP_URL    "ldap://"
    5012             : #define LDAP_DEF_PORT   389
    5013             : #define PGLDAP_TIMEOUT 2
    5014             : 
    5015             : #define ld_is_sp_tab(x) ((x) == ' ' || (x) == '\t')
    5016             : #define ld_is_nl_cr(x) ((x) == '\r' || (x) == '\n')
    5017             : 
    5018             : 
    5019             : /*
    5020             :  *      ldapServiceLookup
    5021             :  *
    5022             :  * Search the LDAP URL passed as first argument, treat the result as a
    5023             :  * string of connection options that are parsed and added to the array of
    5024             :  * options passed as second argument.
    5025             :  *
    5026             :  * LDAP URLs must conform to RFC 1959 without escape sequences.
    5027             :  *  ldap://host:port/dn?attributes?scope?filter?extensions
    5028             :  *
    5029             :  * Returns
    5030             :  *  0 if the lookup was successful,
    5031             :  *  1 if the connection to the LDAP server could be established but
    5032             :  *    the search was unsuccessful,
    5033             :  *  2 if a connection could not be established, and
    5034             :  *  3 if a fatal error occurred.
    5035             :  *
    5036             :  * An error message is appended to *errorMessage for return codes 1 and 3.
    5037             :  */
    5038             : static int
    5039           2 : ldapServiceLookup(const char *purl, PQconninfoOption *options,
    5040             :                   PQExpBuffer errorMessage)
    5041             : {
    5042           2 :     int         port = LDAP_DEF_PORT,
    5043             :                 scope,
    5044             :                 rc,
    5045             :                 size,
    5046             :                 state,
    5047             :                 oldstate,
    5048             :                 i;
    5049             : #ifndef WIN32
    5050             :     int         msgid;
    5051             : #endif
    5052             :     bool        found_keyword;
    5053             :     char       *url,
    5054             :                *hostname,
    5055             :                *portstr,
    5056             :                *endptr,
    5057             :                *dn,
    5058             :                *scopestr,
    5059             :                *filter,
    5060             :                *result,
    5061             :                *p,
    5062           2 :                *p1 = NULL,
    5063           2 :                *optname = NULL,
    5064           2 :                *optval = NULL;
    5065           2 :     char       *attrs[2] = {NULL, NULL};
    5066           2 :     LDAP       *ld = NULL;
    5067             :     LDAPMessage *res,
    5068             :                *entry;
    5069             :     struct berval **values;
    5070           2 :     LDAP_TIMEVAL time = {PGLDAP_TIMEOUT, 0};
    5071             : 
    5072           2 :     if ((url = strdup(purl)) == NULL)
    5073             :     {
    5074           0 :         libpq_append_error(errorMessage, "out of memory");
    5075           0 :         return 3;
    5076             :     }
    5077             : 
    5078             :     /*
    5079             :      * Parse URL components, check for correctness.  Basically, url has '\0'
    5080             :      * placed at component boundaries and variables are pointed at each
    5081             :      * component.
    5082             :      */
    5083             : 
    5084           2 :     if (pg_strncasecmp(url, LDAP_URL, strlen(LDAP_URL)) != 0)
    5085             :     {
    5086           0 :         libpq_append_error(errorMessage,
    5087             :                            "invalid LDAP URL \"%s\": scheme must be ldap://", purl);
    5088           0 :         free(url);
    5089           0 :         return 3;
    5090             :     }
    5091             : 
    5092             :     /* hostname */
    5093           2 :     hostname = url + strlen(LDAP_URL);
    5094           2 :     if (*hostname == '/')       /* no hostname? */
    5095           0 :         hostname = DefaultHost; /* the default */
    5096             : 
    5097             :     /* dn, "distinguished name" */
    5098           2 :     p = strchr(url + strlen(LDAP_URL), '/');
    5099           2 :     if (p == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    5100             :     {
    5101           0 :         libpq_append_error(errorMessage,
    5102             :                            "invalid LDAP URL \"%s\": missing distinguished name",
    5103             :                            purl);
    5104           0 :         free(url);
    5105           0 :         return 3;
    5106             :     }
    5107           2 :     *p = '\0';                  /* terminate hostname */
    5108           2 :     dn = p + 1;
    5109             : 
    5110             :     /* attribute */
    5111           2 :     if ((p = strchr(dn, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    5112             :     {
    5113           0 :         libpq_append_error(errorMessage,
    5114             :                            "invalid LDAP URL \"%s\": must have exactly one attribute",
    5115             :                            purl);
    5116           0 :         free(url);
    5117           0 :         return 3;
    5118             :     }
    5119           2 :     *p = '\0';
    5120           2 :     attrs[0] = p + 1;
    5121             : 
    5122             :     /* scope */
    5123           2 :     if ((p = strchr(attrs[0], '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    5124             :     {
    5125           0 :         libpq_append_error(errorMessage,
    5126             :                            "invalid LDAP URL \"%s\": must have search scope (base/one/sub)",
    5127             :                            purl);
    5128           0 :         free(url);
    5129           0 :         return 3;
    5130             :     }
    5131           2 :     *p = '\0';
    5132           2 :     scopestr = p + 1;
    5133             : 
    5134             :     /* filter */
    5135           2 :     if ((p = strchr(scopestr, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
    5136             :     {
    5137           0 :         libpq_append_error(errorMessage,
    5138             :                            "invalid LDAP URL \"%s\": no filter",
    5139             :                            purl);
    5140           0 :         free(url);
    5141           0 :         return 3;
    5142             :     }
    5143           2 :     *p = '\0';
    5144           2 :     filter = p + 1;
    5145           2 :     if ((p = strchr(filter, '?')) != NULL)
    5146           0 :         *p = '\0';
    5147             : 
    5148             :     /* port number? */
    5149           2 :     if ((p1 = strchr(hostname, ':')) != NULL)
    5150             :     {
    5151             :         long        lport;
    5152             : 
    5153           2 :         *p1 = '\0';
    5154           2 :         portstr = p1 + 1;
    5155           2 :         errno = 0;
    5156           2 :         lport = strtol(portstr, &endptr, 10);
    5157           2 :         if (*portstr == '\0' || *endptr != '\0' || errno || lport < 0 || lport > 65535)
    5158             :         {
    5159           0 :             libpq_append_error(errorMessage,
    5160             :                                "invalid LDAP URL \"%s\": invalid port number",
    5161             :                                purl);
    5162           0 :             free(url);
    5163           0 :             return 3;
    5164             :         }
    5165           2 :         port = (int) lport;
    5166             :     }
    5167             : 
    5168             :     /* Allow only one attribute */
    5169           2 :     if (strchr(attrs[0], ',') != NULL)
    5170             :     {
    5171           0 :         libpq_append_error(errorMessage,
    5172             :                            "invalid LDAP URL \"%s\": must have exactly one attribute",
    5173             :                            purl);
    5174           0 :         free(url);
    5175           0 :         return 3;
    5176             :     }
    5177             : 
    5178             :     /* set scope */
    5179           2 :     if (pg_strcasecmp(scopestr, "base") == 0)
    5180           0 :         scope = LDAP_SCOPE_BASE;
    5181           2 :     else if (pg_strcasecmp(scopestr, "one") == 0)
    5182           2 :         scope = LDAP_SCOPE_ONELEVEL;
    5183           0 :     else if (pg_strcasecmp(scopestr, "sub") == 0)
    5184           0 :         scope = LDAP_SCOPE_SUBTREE;
    5185             :     else
    5186             :     {
    5187           0 :         libpq_append_error(errorMessage,
    5188             :                            "invalid LDAP URL \"%s\": must have search scope (base/one/sub)",
    5189             :                            purl);
    5190           0 :         free(url);
    5191           0 :         return 3;
    5192             :     }
    5193             : 
    5194             :     /* initialize LDAP structure */
    5195           2 :     if ((ld = ldap_init(hostname, port)) == NULL)
    5196             :     {
    5197           0 :         libpq_append_error(errorMessage, "could not create LDAP structure");
    5198           0 :         free(url);
    5199           0 :         return 3;
    5200             :     }
    5201             : 
    5202             :     /*
    5203             :      * Perform an explicit anonymous bind.
    5204             :      *
    5205             :      * LDAP does not require that an anonymous bind is performed explicitly,
    5206             :      * but we want to distinguish between the case where LDAP bind does not
    5207             :      * succeed within PGLDAP_TIMEOUT seconds (return 2 to continue parsing the
    5208             :      * service control file) and the case where querying the LDAP server fails
    5209             :      * (return 1 to end parsing).
    5210             :      *
    5211             :      * Unfortunately there is no way of setting a timeout that works for both
    5212             :      * Windows and OpenLDAP.
    5213             :      */
    5214             : #ifdef WIN32
    5215             :     /* the nonstandard ldap_connect function performs an anonymous bind */
    5216             :     if (ldap_connect(ld, &time) != LDAP_SUCCESS)
    5217             :     {
    5218             :         /* error or timeout in ldap_connect */
    5219             :         free(url);
    5220             :         ldap_unbind(ld);
    5221             :         return 2;
    5222             :     }
    5223             : #else                           /* !WIN32 */
    5224             :     /* in OpenLDAP, use the LDAP_OPT_NETWORK_TIMEOUT option */
    5225           2 :     if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
    5226             :     {
    5227           0 :         free(url);
    5228           0 :         ldap_unbind(ld);
    5229           0 :         return 3;
    5230             :     }
    5231             : 
    5232             :     /* anonymous bind */
    5233           2 :     if ((msgid = ldap_simple_bind(ld, NULL, NULL)) == -1)
    5234             :     {
    5235             :         /* error or network timeout */
    5236           2 :         free(url);
    5237           2 :         ldap_unbind(ld);
    5238           2 :         return 2;
    5239             :     }
    5240             : 
    5241             :     /* wait some time for the connection to succeed */
    5242           0 :     res = NULL;
    5243           0 :     if ((rc = ldap_result(ld, msgid, LDAP_MSG_ALL, &time, &res)) == -1 ||
    5244           0 :         res == NULL)
    5245             :     {
    5246             :         /* error or timeout */
    5247           0 :         if (res != NULL)
    5248           0 :             ldap_msgfree(res);
    5249           0 :         free(url);
    5250           0 :         ldap_unbind(ld);
    5251           0 :         return 2;
    5252             :     }
    5253           0 :     ldap_msgfree(res);
    5254             : 
    5255             :     /* reset timeout */
    5256           0 :     time.tv_sec = -1;
    5257           0 :     if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS)
    5258             :     {
    5259           0 :         free(url);
    5260           0 :         ldap_unbind(ld);
    5261           0 :         return 3;
    5262             :     }
    5263             : #endif                          /* WIN32 */
    5264             : 
    5265             :     /* search */
    5266           0 :     res = NULL;
    5267           0 :     if ((rc = ldap_search_st(ld, dn, scope, filter, attrs, 0, &time, &res))
    5268             :         != LDAP_SUCCESS)
    5269             :     {
    5270           0 :         if (res != NULL)
    5271           0 :             ldap_msgfree(res);
    5272           0 :         libpq_append_error(errorMessage, "lookup on LDAP server failed: %s", ldap_err2string(rc));
    5273           0 :         ldap_unbind(ld);
    5274           0 :         free(url);
    5275           0 :         return 1;
    5276             :     }
    5277             : 
    5278             :     /* complain if there was not exactly one result */
    5279           0 :     if ((rc = ldap_count_entries(ld, res)) != 1)
    5280             :     {
    5281           0 :         if (rc > 1)
    5282           0 :             libpq_append_error(errorMessage, "more than one entry found on LDAP lookup");
    5283             :         else
    5284           0 :             libpq_append_error(errorMessage, "no entry found on LDAP lookup");
    5285           0 :         ldap_msgfree(res);
    5286           0 :         ldap_unbind(ld);
    5287           0 :         free(url);
    5288           0 :         return 1;
    5289             :     }
    5290             : 
    5291             :     /* get entry */
    5292           0 :     if ((entry = ldap_first_entry(ld, res)) == NULL)
    5293             :     {
    5294             :         /* should never happen */
    5295           0 :         libpq_append_error(errorMessage, "no entry found on LDAP lookup");
    5296           0 :         ldap_msgfree(res);
    5297           0 :         ldap_unbind(ld);
    5298           0 :         free(url);
    5299           0 :         return 1;
    5300             :     }
    5301             : 
    5302             :     /* get values */
    5303           0 :     if ((values = ldap_get_values_len(ld, entry, attrs[0])) == NULL)
    5304             :     {
    5305           0 :         libpq_append_error(errorMessage, "attribute has no values on LDAP lookup");
    5306           0 :         ldap_msgfree(res);
    5307           0 :         ldap_unbind(ld);
    5308           0 :         free(url);
    5309           0 :         return 1;
    5310             :     }
    5311             : 
    5312           0 :     ldap_msgfree(res);
    5313           0 :     free(url);
    5314             : 
    5315           0 :     if (values[0] == NULL)
    5316             :     {
    5317           0 :         libpq_append_error(errorMessage, "attribute has no values on LDAP lookup");
    5318           0 :         ldap_value_free_len(values);
    5319           0 :         ldap_unbind(ld);
    5320           0 :         return 1;
    5321             :     }
    5322             : 
    5323             :     /* concatenate values into a single string with newline terminators */
    5324           0 :     size = 1;                   /* for the trailing null */
    5325           0 :     for (i = 0; values[i] != NULL; i++)
    5326           0 :         size += values[i]->bv_len + 1;
    5327           0 :     if ((result = malloc(size)) == NULL)
    5328             :     {
    5329           0 :         libpq_append_error(errorMessage, "out of memory");
    5330           0 :         ldap_value_free_len(values);
    5331           0 :         ldap_unbind(ld);
    5332           0 :         return 3;
    5333             :     }
    5334           0 :     p = result;
    5335           0 :     for (i = 0; values[i] != NULL; i++)
    5336             :     {
    5337           0 :         memcpy(p, values[i]->bv_val, values[i]->bv_len);
    5338           0 :         p += values[i]->bv_len;
    5339           0 :         *(p++) = '\n';
    5340             :     }
    5341           0 :     *p = '\0';
    5342             : 
    5343           0 :     ldap_value_free_len(values);
    5344           0 :     ldap_unbind(ld);
    5345             : 
    5346             :     /* parse result string */
    5347           0 :     oldstate = state = 0;
    5348           0 :     for (p = result; *p != '\0'; ++p)
    5349             :     {
    5350           0 :         switch (state)
    5351             :         {
    5352           0 :             case 0:             /* between entries */
    5353           0 :                 if (!ld_is_sp_tab(*p) && !ld_is_nl_cr(*p))
    5354             :                 {
    5355           0 :                     optname = p;
    5356           0 :                     state = 1;
    5357             :                 }
    5358           0 :                 break;
    5359           0 :             case 1:             /* in option name */
    5360           0 :                 if (ld_is_sp_tab(*p))
    5361             :                 {
    5362           0 :                     *p = '\0';
    5363           0 :                     state = 2;
    5364             :                 }
    5365           0 :                 else if (ld_is_nl_cr(*p))
    5366             :                 {
    5367           0 :                     libpq_append_error(errorMessage,
    5368             :                                        "missing \"=\" after \"%s\" in connection info string",
    5369             :                                        optname);
    5370           0 :                     free(result);
    5371           0 :                     return 3;
    5372             :                 }
    5373           0 :                 else if (*p == '=')
    5374             :                 {
    5375           0 :                     *p = '\0';
    5376           0 :                     state = 3;
    5377             :                 }
    5378           0 :                 break;
    5379           0 :             case 2:             /* after option name */
    5380           0 :                 if (*p == '=')
    5381             :                 {
    5382           0 :                     state = 3;
    5383             :                 }
    5384           0 :                 else if (!ld_is_sp_tab(*p))
    5385             :                 {
    5386           0 :                     libpq_append_error(errorMessage,
    5387             :                                        "missing \"=\" after \"%s\" in connection info string",
    5388             :                                        optname);
    5389           0 :                     free(result);
    5390           0 :                     return 3;
    5391             :                 }
    5392           0 :                 break;
    5393           0 :             case 3:             /* before option value */
    5394           0 :                 if (*p == '\'')
    5395             :                 {
    5396           0 :                     optval = p + 1;
    5397           0 :                     p1 = p + 1;
    5398           0 :                     state = 5;
    5399             :                 }
    5400           0 :                 else if (ld_is_nl_cr(*p))
    5401             :                 {
    5402           0 :                     optval = optname + strlen(optname); /* empty */
    5403           0 :                     state = 0;
    5404             :                 }
    5405           0 :                 else if (!ld_is_sp_tab(*p))
    5406             :                 {
    5407           0 :                     optval = p;
    5408           0 :                     state = 4;
    5409             :                 }
    5410           0 :                 break;
    5411           0 :             case 4:             /* in unquoted option value */
    5412           0 :                 if (ld_is_sp_tab(*p) || ld_is_nl_cr(*p))
    5413             :                 {
    5414           0 :                     *p = '\0';
    5415           0 :                     state = 0;
    5416             :                 }
    5417           0 :                 break;
    5418           0 :             case 5:             /* in quoted option value */
    5419           0 :                 if (*p == '\'')
    5420             :                 {
    5421           0 :                     *p1 = '\0';
    5422           0 :                     state = 0;
    5423             :                 }
    5424           0 :                 else if (*p == '\\')
    5425           0 :                     state = 6;
    5426             :                 else
    5427           0 :                     *(p1++) = *p;
    5428           0 :                 break;
    5429           0 :             case 6:             /* in quoted option value after escape */
    5430           0 :                 *(p1++) = *p;
    5431           0 :                 state = 5;
    5432           0 :                 break;
    5433             :         }
    5434             : 
    5435           0 :         if (state == 0 && oldstate != 0)
    5436             :         {
    5437           0 :             found_keyword = false;
    5438           0 :             for (i = 0; options[i].keyword; i++)
    5439             :             {
    5440           0 :                 if (strcmp(options[i].keyword, optname) == 0)
    5441             :                 {
    5442           0 :                     if (options[i].val == NULL)
    5443             :                     {
    5444           0 :                         options[i].val = strdup(optval);
    5445           0 :                         if (!options[i].val)
    5446             :                         {
    5447           0 :                             libpq_append_error(errorMessage, "out of memory");
    5448           0 :                             free(result);
    5449           0 :                             return 3;
    5450             :                         }
    5451             :                     }
    5452           0 :                     found_keyword = true;
    5453           0 :                     break;
    5454             :                 }
    5455             :             }
    5456           0 :             if (!found_keyword)
    5457             :             {
    5458           0 :                 libpq_append_error(errorMessage, "invalid connection option \"%s\"", optname);
    5459           0 :                 free(result);
    5460           0 :                 return 1;
    5461             :             }
    5462           0 :             optname = NULL;
    5463           0 :             optval = NULL;
    5464             :         }
    5465           0 :         oldstate = state;
    5466             :     }
    5467             : 
    5468           0 :     free(result);
    5469             : 
    5470           0 :     if (state == 5 || state == 6)
    5471             :     {
    5472           0 :         libpq_append_error(errorMessage,
    5473             :                            "unterminated quoted string in connection info string");
    5474           0 :         return 3;
    5475             :     }
    5476             : 
    5477           0 :     return 0;
    5478             : }
    5479             : 
    5480             : #endif                          /* USE_LDAP */
    5481             : 
    5482             : /*
    5483             :  * parseServiceInfo: if a service name has been given, look it up and absorb
    5484             :  * connection options from it into *options.
    5485             :  *
    5486             :  * Returns 0 on success, nonzero on failure.  On failure, if errorMessage
    5487             :  * isn't null, also store an error message there.  (Note: the only reason
    5488             :  * this function and related ones don't dump core on errorMessage == NULL
    5489             :  * is the undocumented fact that appendPQExpBuffer does nothing when passed
    5490             :  * a null PQExpBuffer pointer.)
    5491             :  */
    5492             : static int
    5493       26704 : parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
    5494             : {
    5495       26704 :     const char *service = conninfo_getval(options, "service");
    5496             :     char        serviceFile[MAXPGPATH];
    5497             :     char       *env;
    5498       26704 :     bool        group_found = false;
    5499             :     int         status;
    5500             :     struct stat stat_buf;
    5501             : 
    5502             :     /*
    5503             :      * We have to special-case the environment variable PGSERVICE here, since
    5504             :      * this is and should be called before inserting environment defaults for
    5505             :      * other connection options.
    5506             :      */
    5507       26704 :     if (service == NULL)
    5508       26702 :         service = getenv("PGSERVICE");
    5509             : 
    5510             :     /* If no service name given, nothing to do */
    5511       26704 :     if (service == NULL)
    5512       26702 :         return 0;
    5513             : 
    5514             :     /*
    5515             :      * Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that
    5516             :      * exists).
    5517             :      */
    5518           2 :     if ((env = getenv("PGSERVICEFILE")) != NULL)
    5519           2 :         strlcpy(serviceFile, env, sizeof(serviceFile));
    5520             :     else
    5521             :     {
    5522             :         char        homedir[MAXPGPATH];
    5523             : 
    5524           0 :         if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
    5525           0 :             goto next_file;
    5526           0 :         snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf");
    5527           0 :         if (stat(serviceFile, &stat_buf) != 0)
    5528           0 :             goto next_file;
    5529             :     }
    5530             : 
    5531           2 :     status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
    5532           2 :     if (group_found || status != 0)
    5533           2 :         return status;
    5534             : 
    5535           0 : next_file:
    5536             : 
    5537             :     /*
    5538             :      * This could be used by any application so we can't use the binary
    5539             :      * location to find our config files.
    5540             :      */
    5541           0 :     snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
    5542           0 :              getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
    5543           0 :     if (stat(serviceFile, &stat_buf) != 0)
    5544           0 :         goto last_file;
    5545             : 
    5546           0 :     status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
    5547           0 :     if (status != 0)
    5548           0 :         return status;
    5549             : 
    5550           0 : last_file:
    5551           0 :     if (!group_found)
    5552             :     {
    5553           0 :         libpq_append_error(errorMessage, "definition of service \"%s\" not found", service);
    5554           0 :         return 3;
    5555             :     }
    5556             : 
    5557           0 :     return 0;
    5558             : }
    5559             : 
    5560             : static int
    5561           2 : parseServiceFile(const char *serviceFile,
    5562             :                  const char *service,
    5563             :                  PQconninfoOption *options,
    5564             :                  PQExpBuffer errorMessage,
    5565             :                  bool *group_found)
    5566             : {
    5567           2 :     int         result = 0,
    5568           2 :                 linenr = 0,
    5569             :                 i;
    5570             :     FILE       *f;
    5571             :     char       *line;
    5572             :     char        buf[1024];
    5573             : 
    5574           2 :     *group_found = false;
    5575             : 
    5576           2 :     f = fopen(serviceFile, "r");
    5577           2 :     if (f == NULL)
    5578             :     {
    5579           0 :         libpq_append_error(errorMessage, "service file \"%s\" not found", serviceFile);
    5580           0 :         return 1;
    5581             :     }
    5582             : 
    5583          16 :     while ((line = fgets(buf, sizeof(buf), f)) != NULL)
    5584             :     {
    5585             :         int         len;
    5586             : 
    5587          14 :         linenr++;
    5588             : 
    5589          14 :         if (strlen(line) >= sizeof(buf) - 1)
    5590             :         {
    5591           0 :             libpq_append_error(errorMessage,
    5592             :                                "line %d too long in service file \"%s\"",
    5593             :                                linenr,
    5594             :                                serviceFile);
    5595           0 :             result = 2;
    5596           0 :             goto exit;
    5597             :         }
    5598             : 
    5599             :         /* ignore whitespace at end of line, especially the newline */
    5600          14 :         len = strlen(line);
    5601          28 :         while (len > 0 && isspace((unsigned char) line[len - 1]))
    5602          14 :             line[--len] = '\0';
    5603             : 
    5604             :         /* ignore leading whitespace too */
    5605          14 :         while (*line && isspace((unsigned char) line[0]))
    5606           0 :             line++;
    5607             : 
    5608             :         /* ignore comments and empty lines */
    5609          14 :         if (line[0] == '\0' || line[0] == '#')
    5610          10 :             continue;
    5611             : 
    5612             :         /* Check for right groupname */
    5613           4 :         if (line[0] == '[')
    5614             :         {
    5615           2 :             if (*group_found)
    5616             :             {
    5617             :                 /* end of desired group reached; return success */
    5618           0 :                 goto exit;
    5619             :             }
    5620             : 
    5621           2 :             if (strncmp(line + 1, service, strlen(service)) == 0 &&
    5622           2 :                 line[strlen(service) + 1] == ']')
    5623           2 :                 *group_found = true;
    5624             :             else
    5625           0 :                 *group_found = false;
    5626             :         }
    5627             :         else
    5628             :         {
    5629           2 :             if (*group_found)
    5630             :             {
    5631             :                 /*
    5632             :                  * Finally, we are in the right group and can parse the line
    5633             :                  */
    5634             :                 char       *key,
    5635             :                            *val;
    5636             :                 bool        found_keyword;
    5637             : 
    5638             : #ifdef USE_LDAP
    5639           2 :                 if (strncmp(line, "ldap", 4) == 0)
    5640             :                 {
    5641           2 :                     int         rc = ldapServiceLookup(line, options, errorMessage);
    5642             : 
    5643             :                     /* if rc = 2, go on reading for fallback */
    5644           2 :                     switch (rc)
    5645             :                     {
    5646           0 :                         case 0:
    5647           0 :                             goto exit;
    5648           0 :                         case 1:
    5649             :                         case 3:
    5650           0 :                             result = 3;
    5651           0 :                             goto exit;
    5652           2 :                         case 2:
    5653           2 :                             continue;
    5654             :                     }
    5655             :                 }
    5656             : #endif
    5657             : 
    5658           0 :                 key = line;
    5659           0 :                 val = strchr(line, '=');
    5660           0 :                 if (val == NULL)
    5661             :                 {
    5662           0 :                     libpq_append_error(errorMessage,
    5663             :                                        "syntax error in service file \"%s\", line %d",
    5664             :                                        serviceFile,
    5665             :                                        linenr);
    5666           0 :                     result = 3;
    5667           0 :                     goto exit;
    5668             :                 }
    5669           0 :                 *val++ = '\0';
    5670             : 
    5671           0 :                 if (strcmp(key, "service") == 0)
    5672             :                 {
    5673           0 :                     libpq_append_error(errorMessage,
    5674             :                                        "nested service specifications not supported in service file \"%s\", line %d",
    5675             :                                        serviceFile,
    5676             :                                        linenr);
    5677           0 :                     result = 3;
    5678           0 :                     goto exit;
    5679             :                 }
    5680             : 
    5681             :                 /*
    5682             :                  * Set the parameter --- but don't override any previous
    5683             :                  * explicit setting.
    5684             :                  */
    5685           0 :                 found_keyword = false;
    5686           0 :                 for (i = 0; options[i].keyword; i++)
    5687             :                 {
    5688           0 :                     if (strcmp(options[i].keyword, key) == 0)
    5689             :                     {
    5690           0 :                         if (options[i].val == NULL)
    5691           0 :                             options[i].val = strdup(val);
    5692           0 :                         if (!options[i].val)
    5693             :                         {
    5694           0 :                             libpq_append_error(errorMessage, "out of memory");
    5695           0 :                             result = 3;
    5696           0 :                             goto exit;
    5697             :                         }
    5698           0 :                         found_keyword = true;
    5699           0 :                         break;
    5700             :                     }
    5701             :                 }
    5702             : 
    5703           0 :                 if (!found_keyword)
    5704             :                 {
    5705           0 :                     libpq_append_error(errorMessage,
    5706             :                                        "syntax error in service file \"%s\", line %d",
    5707             :                                        serviceFile,
    5708             :                                        linenr);
    5709           0 :                     result = 3;
    5710           0 :                     goto exit;
    5711             :                 }
    5712             :             }
    5713             :         }
    5714             :     }
    5715             : 
    5716           2 : exit:
    5717           2 :     fclose(f);
    5718             : 
    5719           2 :     return result;
    5720             : }
    5721             : 
    5722             : 
    5723             : /*
    5724             :  *      PQconninfoParse
    5725             :  *
    5726             :  * Parse a string like PQconnectdb() would do and return the
    5727             :  * resulting connection options array.  NULL is returned on failure.
    5728             :  * The result contains only options specified directly in the string,
    5729             :  * not any possible default values.
    5730             :  *
    5731             :  * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd
    5732             :  * string on failure (use PQfreemem to free it).  In out-of-memory conditions
    5733             :  * both *errmsg and the result could be NULL.
    5734             :  *
    5735             :  * NOTE: the returned array is dynamically allocated and should
    5736             :  * be freed when no longer needed via PQconninfoFree().
    5737             :  */
    5738             : PQconninfoOption *
    5739        2154 : PQconninfoParse(const char *conninfo, char **errmsg)
    5740             : {
    5741             :     PQExpBufferData errorBuf;
    5742             :     PQconninfoOption *connOptions;
    5743             : 
    5744        2154 :     if (errmsg)
    5745        2152 :         *errmsg = NULL;         /* default */
    5746        2154 :     initPQExpBuffer(&errorBuf);
    5747        2154 :     if (PQExpBufferDataBroken(errorBuf))
    5748           0 :         return NULL;            /* out of memory already :-( */
    5749        2154 :     connOptions = parse_connection_string(conninfo, &errorBuf, false);
    5750        2154 :     if (connOptions == NULL && errmsg)
    5751          50 :         *errmsg = errorBuf.data;
    5752             :     else
    5753        2104 :         termPQExpBuffer(&errorBuf);
    5754        2154 :     return connOptions;
    5755             : }
    5756             : 
    5757             : /*
    5758             :  * Build a working copy of the constant PQconninfoOptions array.
    5759             :  */
    5760             : static PQconninfoOption *
    5761       47770 : conninfo_init(PQExpBuffer errorMessage)
    5762             : {
    5763             :     PQconninfoOption *options;
    5764             :     PQconninfoOption *opt_dest;
    5765             :     const internalPQconninfoOption *cur_opt;
    5766             : 
    5767             :     /*
    5768             :      * Get enough memory for all options in PQconninfoOptions, even if some
    5769             :      * end up being filtered out.
    5770             :      */
    5771       47770 :     options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
    5772       47770 :     if (options == NULL)
    5773             :     {
    5774           0 :         libpq_append_error(errorMessage, "out of memory");
    5775           0 :         return NULL;
    5776             :     }
    5777       47770 :     opt_dest = options;
    5778             : 
    5779     2006340 :     for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++)
    5780             :     {
    5781             :         /* Only copy the public part of the struct, not the full internal */
    5782     1958570 :         memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption));
    5783     1958570 :         opt_dest++;
    5784             :     }
    5785      382160 :     MemSet(opt_dest, 0, sizeof(PQconninfoOption));
    5786             : 
    5787       47770 :     return options;
    5788             : }
    5789             : 
    5790             : /*
    5791             :  * Connection string parser
    5792             :  *
    5793             :  * Returns a malloc'd PQconninfoOption array, if parsing is successful.
    5794             :  * Otherwise, NULL is returned and an error message is added to errorMessage.
    5795             :  *
    5796             :  * If use_defaults is true, default values are filled in (from a service file,
    5797             :  * environment variables, etc).
    5798             :  */
    5799             : static PQconninfoOption *
    5800       22104 : parse_connection_string(const char *connstr, PQExpBuffer errorMessage,
    5801             :                         bool use_defaults)
    5802             : {
    5803             :     /* Parse as URI if connection string matches URI prefix */
    5804       22104 :     if (uri_prefix_length(connstr) != 0)
    5805         124 :         return conninfo_uri_parse(connstr, errorMessage, use_defaults);
    5806             : 
    5807             :     /* Parse as default otherwise */
    5808       21980 :     return conninfo_parse(connstr, errorMessage, use_defaults);
    5809             : }
    5810             : 
    5811             : /*
    5812             :  * Checks if connection string starts with either of the valid URI prefix
    5813             :  * designators.
    5814             :  *
    5815             :  * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix.
    5816             :  *
    5817             :  * XXX this is duplicated in psql/common.c.
    5818             :  */
    5819             : static int
    5820       46100 : uri_prefix_length(const char *connstr)
    5821             : {
    5822       46100 :     if (strncmp(connstr, uri_designator,
    5823             :                 sizeof(uri_designator) - 1) == 0)
    5824         172 :         return sizeof(uri_designator) - 1;
    5825             : 
    5826       45928 :     if (strncmp(connstr, short_uri_designator,
    5827             :                 sizeof(short_uri_designator) - 1) == 0)
    5828          76 :         return sizeof(short_uri_designator) - 1;
    5829             : 
    5830       45852 :     return 0;
    5831             : }
    5832             : 
    5833             : /*
    5834             :  * Recognized connection string either starts with a valid URI prefix or
    5835             :  * contains a "=" in it.
    5836             :  *
    5837             :  * Must be consistent with parse_connection_string: anything for which this
    5838             :  * returns true should at least look like it's parseable by that routine.
    5839             :  *
    5840             :  * XXX this is duplicated in psql/common.c
    5841             :  */
    5842             : static bool
    5843       23872 : recognized_connection_string(const char *connstr)
    5844             : {
    5845       23872 :     return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL;
    5846             : }
    5847             : 
    5848             : /*
    5849             :  * Subroutine for parse_connection_string
    5850             :  *
    5851             :  * Deal with a string containing key=value pairs.
    5852             :  */
    5853             : static PQconninfoOption *
    5854       21980 : conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
    5855             :                bool use_defaults)
    5856             : {
    5857             :     char       *pname;
    5858             :     char       *pval;
    5859             :     char       *buf;
    5860             :     char       *cp;
    5861             :     char       *cp2;
    5862             :     PQconninfoOption *options;
    5863             : 
    5864             :     /* Make a working copy of PQconninfoOptions */
    5865       21980 :     options = conninfo_init(errorMessage);
    5866       21980 :     if (options == NULL)
    5867           0 :         return NULL;
    5868             : 
    5869             :     /* Need a modifiable copy of the input string */
    5870       21980 :     if ((buf = strdup(conninfo)) == NULL)
    5871             :     {
    5872           0 :         libpq_append_error(errorMessage, "out of memory");
    5873           0 :         PQconninfoFree(options);
    5874           0 :         return NULL;
    5875             :     }
    5876       21980 :     cp = buf;
    5877             : 
    5878       88504 :     while (*cp)
    5879             :     {
    5880             :         /* Skip blanks before the parameter name */
    5881       66548 :         if (isspace((unsigned char) *cp))
    5882             :         {
    5883         432 :             cp++;
    5884         432 :             continue;
    5885             :         }
    5886             : 
    5887             :         /* Get the parameter name */
    5888       66116 :         pname = cp;
    5889      396004 :         while (*cp)
    5890             :         {
    5891      395986 :             if (*cp == '=')
    5892       66098 :                 break;
    5893      329888 :             if (isspace((unsigned char) *cp))
    5894             :             {
    5895           0 :                 *cp++ = '\0';
    5896           0 :                 while (*cp)
    5897             :                 {
    5898           0 :                     if (!isspace((unsigned char) *cp))
    5899           0 :                         break;
    5900           0 :                     cp++;
    5901             :                 }
    5902           0 :                 break;
    5903             :             }
    5904      329888 :             cp++;
    5905             :         }
    5906             : 
    5907             :         /* Check that there is a following '=' */
    5908       66116 :         if (*cp != '=')
    5909             :         {
    5910          18 :             libpq_append_error(errorMessage,
    5911             :                                "missing \"=\" after \"%s\" in connection info string",
    5912             :                                pname);
    5913          18 :             PQconninfoFree(options);
    5914          18 :             free(buf);
    5915          18 :             return NULL;
    5916             :         }
    5917       66098 :         *cp++ = '\0';
    5918             : 
    5919             :         /* Skip blanks after the '=' */
    5920       66098 :         while (*cp)
    5921             :         {
    5922       66096 :             if (!isspace((unsigned char) *cp))
    5923       66096 :                 break;
    5924           0 :             cp++;
    5925             :         }
    5926             : 
    5927             :         /* Get the parameter value */
    5928       66098 :         pval = cp;
    5929             : 
    5930       66098 :         if (*cp != '\'')
    5931             :         {
    5932       49224 :             cp2 = pval;
    5933      554132 :             while (*cp)
    5934             :             {
    5935      548762 :                 if (isspace((unsigned char) *cp))
    5936             :                 {
    5937       43854 :                     *cp++ = '\0';
    5938       43854 :                     break;
    5939             :                 }
    5940      504908 :                 if (*cp == '\\')
    5941             :                 {
    5942           2 :                     cp++;
    5943           2 :                     if (*cp != '\0')
    5944           2 :                         *cp2++ = *cp++;
    5945             :                 }
    5946             :                 else
    5947      504906 :                     *cp2++ = *cp++;
    5948             :             }
    5949       49224 :             *cp2 = '\0';
    5950             :         }
    5951             :         else
    5952             :         {
    5953       16874 :             cp2 = pval;
    5954       16874 :             cp++;
    5955             :             for (;;)
    5956             :             {
    5957      171040 :                 if (*cp == '\0')
    5958             :                 {
    5959           0 :                     libpq_append_error(errorMessage, "unterminated quoted string in connection info string");
    5960           0 :                     PQconninfoFree(options);
    5961           0 :                     free(buf);
    5962           0 :                     return NULL;
    5963             :                 }
    5964      171040 :                 if (*cp == '\\')
    5965             :                 {
    5966        1266 :                     cp++;
    5967        1266 :                     if (*cp != '\0')
    5968        1266 :                         *cp2++ = *cp++;
    5969        1266 :                     continue;
    5970             :                 }
    5971      169774 :                 if (*cp == '\'')
    5972             :                 {
    5973       16874 :                     *cp2 = '\0';
    5974       16874 :                     cp++;
    5975       16874 :                     break;
    5976             :                 }
    5977      152900 :                 *cp2++ = *cp++;
    5978             :             }
    5979             :         }
    5980             : 
    5981             :         /*
    5982             :          * Now that we have the name and the value, store the record.
    5983             :          */
    5984       66098 :         if (!conninfo_storeval(options, pname, pval, errorMessage, false, false))
    5985             :         {
    5986           6 :             PQconninfoFree(options);
    5987           6 :             free(buf);
    5988           6 :             return NULL;
    5989             :         }
    5990             :     }
    5991             : 
    5992             :     /* Done with the modifiable input string */
    5993       21956 :     free(buf);
    5994             : 
    5995             :     /*
    5996             :      * Add in defaults if the caller wants that.
    5997             :      */
    5998       21956 :     if (use_defaults)
    5999             :     {
    6000        1644 :         if (!conninfo_add_defaults(options, errorMessage))
    6001             :         {
    6002           0 :             PQconninfoFree(options);
    6003           0 :             return NULL;
    6004             :         }
    6005             :     }
    6006             : 
    6007       21956 :     return options;
    6008             : }
    6009             : 
    6010             : /*
    6011             :  * Conninfo array parser routine
    6012             :  *
    6013             :  * If successful, a malloc'd PQconninfoOption array is returned.
    6014             :  * If not successful, NULL is returned and an error message is
    6015             :  * appended to errorMessage.
    6016             :  * Defaults are supplied (from a service file, environment variables, etc)
    6017             :  * for unspecified options, but only if use_defaults is true.
    6018             :  *
    6019             :  * If expand_dbname is non-zero, and the value passed for the first occurrence
    6020             :  * of "dbname" keyword is a connection string (as indicated by
    6021             :  * recognized_connection_string) then parse and process it, overriding any
    6022             :  * previously processed conflicting keywords. Subsequent keywords will take
    6023             :  * precedence, however. In-tree programs generally specify expand_dbname=true,
    6024             :  * so command-line arguments naming a database can use a connection string.
    6025             :  * Some code acquires arbitrary database names from known-literal sources like
    6026             :  * PQdb(), PQconninfoParse() and pg_database.datname.  When connecting to such
    6027             :  * a database, in-tree code first wraps the name in a connection string.
    6028             :  */
    6029             : static PQconninfoOption *
    6030       24914 : conninfo_array_parse(const char *const *keywords, const char *const *values,
    6031             :                      PQExpBuffer errorMessage, bool use_defaults,
    6032             :                      int expand_dbname)
    6033             : {
    6034             :     PQconninfoOption *options;
    6035       24914 :     PQconninfoOption *dbname_options = NULL;
    6036             :     PQconninfoOption *option;
    6037       24914 :     int         i = 0;
    6038             : 
    6039             :     /*
    6040             :      * If expand_dbname is non-zero, check keyword "dbname" to see if val is
    6041             :      * actually a recognized connection string.
    6042             :      */
    6043      106956 :     while (expand_dbname && keywords[i])
    6044             :     {
    6045      105914 :         const char *pname = keywords[i];
    6046      105914 :         const char *pvalue = values[i];
    6047             : 
    6048             :         /* first find "dbname" if any */
    6049      105914 :         if (strcmp(pname, "dbname") == 0 && pvalue)
    6050             :         {
    6051             :             /*
    6052             :              * If value is a connection string, parse it, but do not use
    6053             :              * defaults here -- those get picked up later. We only want to
    6054             :              * override for those parameters actually passed.
    6055             :              */
    6056       23872 :             if (recognized_connection_string(pvalue))
    6057             :             {
    6058       18302 :                 dbname_options = parse_connection_string(pvalue, errorMessage, false);
    6059       18302 :                 if (dbname_options == NULL)
    6060           0 :                     return NULL;
    6061             :             }
    6062       23872 :             break;
    6063             :         }
    6064       82042 :         ++i;
    6065             :     }
    6066             : 
    6067             :     /* Make a working copy of PQconninfoOptions */
    6068       24914 :     options = conninfo_init(errorMessage);
    6069       24914 :     if (options == NULL)
    6070             :     {
    6071           0 :         PQconninfoFree(dbname_options);
    6072           0 :         return NULL;
    6073             :     }
    6074             : 
    6075             :     /* Parse the keywords/values arrays */
    6076       24914 :     i = 0;
    6077      188176 :     while (keywords[i])
    6078             :     {
    6079      163262 :         const char *pname = keywords[i];
    6080      163262 :         const char *pvalue = values[i];
    6081             : 
    6082      163262 :         if (pvalue != NULL && pvalue[0] != '\0')
    6083             :         {
    6084             :             /* Search for the param record */
    6085      797214 :             for (option = options; option->keyword != NULL; option++)
    6086             :             {
    6087      797214 :                 if (strcmp(option->keyword, pname) == 0)
    6088       63332 :                     break;
    6089             :             }
    6090             : 
    6091             :             /* Check for invalid connection option */
    6092       63332 :             if (option->keyword == NULL)
    6093             :             {
    6094           0 :                 libpq_append_error(errorMessage, "invalid connection option \"%s\"", pname);
    6095           0 :                 PQconninfoFree(options);
    6096           0 :                 PQconninfoFree(dbname_options);
    6097           0 :                 return NULL;
    6098             :             }
    6099             : 
    6100             :             /*
    6101             :              * If we are on the first dbname parameter, and we have a parsed
    6102             :              * connection string, copy those parameters across, overriding any
    6103             :              * existing previous settings.
    6104             :              */
    6105       63332 :             if (strcmp(pname, "dbname") == 0 && dbname_options)
    6106       18302 :             {
    6107             :                 PQconninfoOption *str_option;
    6108             : 
    6109      768684 :                 for (str_option = dbname_options; str_option->keyword != NULL; str_option++)
    6110             :                 {
    6111      750382 :                     if (str_option->val != NULL)
    6112             :                     {
    6113             :                         int         k;
    6114             : 
    6115      506832 :                         for (k = 0; options[k].keyword; k++)
    6116             :                         {
    6117      506832 :                             if (strcmp(options[k].keyword, str_option->keyword) == 0)
    6118             :                             {
    6119       56404 :                                 free(options[k].val);
    6120       56404 :                                 options[k].val = strdup(str_option->val);
    6121       56404 :                                 if (!options[k].val)
    6122             :                                 {
    6123           0 :                                     libpq_append_error(errorMessage, "out of memory");
    6124           0 :                                     PQconninfoFree(options);
    6125           0 :                                     PQconninfoFree(dbname_options);
    6126           0 :                                     return NULL;
    6127             :                                 }
    6128       56404 :                                 break;
    6129             :                             }
    6130             :                         }
    6131             :                     }
    6132             :                 }
    6133             : 
    6134             :                 /*
    6135             :                  * Forget the parsed connection string, so that any subsequent
    6136             :                  * dbname parameters will not be expanded.
    6137             :                  */
    6138       18302 :                 PQconninfoFree(dbname_options);
    6139       18302 :                 dbname_options = NULL;
    6140             :             }
    6141             :             else
    6142             :             {
    6143             :                 /*
    6144             :                  * Store the value, overriding previous settings
    6145             :                  */
    6146       45030 :                 free(option->val);
    6147       45030 :                 option->val = strdup(pvalue);
    6148       45030 :                 if (!option->val)
    6149             :                 {
    6150           0 :                     libpq_append_error(errorMessage, "out of memory");
    6151           0 :                     PQconninfoFree(options);
    6152           0 :                     PQconninfoFree(dbname_options);
    6153           0 :                     return NULL;
    6154             :                 }
    6155             :             }
    6156             :         }
    6157      163262 :         ++i;
    6158             :     }
    6159       24914 :     PQconninfoFree(dbname_options);
    6160             : 
    6161             :     /*
    6162             :      * Add in defaults if the caller wants that.
    6163             :      */
    6164       24914 :     if (use_defaults)
    6165             :     {
    6166       24914 :         if (!conninfo_add_defaults(options, errorMessage))
    6167             :         {
    6168           0 :             PQconninfoFree(options);
    6169           0 :             return NULL;
    6170             :         }
    6171             :     }
    6172             : 
    6173       24914 :     return options;
    6174             : }
    6175             : 
    6176             : /*
    6177             :  * Add the default values for any unspecified options to the connection
    6178             :  * options array.
    6179             :  *
    6180             :  * Defaults are obtained from a service file, environment variables, etc.
    6181             :  *
    6182             :  * Returns true if successful, otherwise false; errorMessage, if supplied,
    6183             :  * is filled in upon failure.  Note that failure to locate a default value
    6184             :  * is not an error condition here --- we just leave the option's value as
    6185             :  * NULL.
    6186             :  */
    6187             : static bool
    6188       26704 : conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
    6189             : {
    6190             :     PQconninfoOption *option;
    6191       26704 :     PQconninfoOption *sslmode_default = NULL,
    6192       26704 :                *sslrootcert = NULL;
    6193             :     char       *tmp;
    6194             : 
    6195             :     /*
    6196             :      * If there's a service spec, use it to obtain any not-explicitly-given
    6197             :      * parameters.  Ignore error if no error message buffer is passed because
    6198             :      * there is no way to pass back the failure message.
    6199             :      */
    6200       26704 :     if (parseServiceInfo(options, errorMessage) != 0 && errorMessage)
    6201           0 :         return false;
    6202             : 
    6203             :     /*
    6204             :      * Get the fallback resources for parameters not specified in the conninfo
    6205             :      * string nor the service.
    6206             :      */
    6207     1121568 :     for (option = options; option->keyword != NULL; option++)
    6208             :     {
    6209     1094864 :         if (strcmp(option->keyword, "sslrootcert") == 0)
    6210       26704 :             sslrootcert = option;   /* save for later */
    6211             : 
    6212     1094864 :         if (option->val != NULL)
    6213      104668 :             continue;           /* Value was in conninfo or service */
    6214             : 
    6215             :         /*
    6216             :          * Try to get the environment variable fallback
    6217             :          */
    6218      990196 :         if (option->envvar != NULL)
    6219             :         {
    6220      803184 :             if ((tmp = getenv(option->envvar)) != NULL)
    6221             :             {
    6222       44040 :                 option->val = strdup(tmp);
    6223       44040 :                 if (!option->val)
    6224             :                 {
    6225           0 :                     if (errorMessage)
    6226           0 :                         libpq_append_error(errorMessage, "out of memory");
    6227           0 :                     return false;
    6228             :                 }
    6229       44040 :                 continue;
    6230             :             }
    6231             :         }
    6232             : 
    6233             :         /*
    6234             :          * Interpret the deprecated PGREQUIRESSL environment variable.  Per
    6235             :          * tradition, translate values starting with "1" to sslmode=require,
    6236             :          * and ignore other values.  Given both PGREQUIRESSL=1 and PGSSLMODE,
    6237             :          * PGSSLMODE takes precedence; the opposite was true before v9.3.
    6238             :          */
    6239      946156 :         if (strcmp(option->keyword, "sslmode") == 0)
    6240             :         {
    6241       26034 :             const char *requiresslenv = getenv("PGREQUIRESSL");
    6242             : 
    6243       26034 :             if (requiresslenv != NULL && requiresslenv[0] == '1')
    6244             :             {
    6245           0 :                 option->val = strdup("require");
    6246           0 :                 if (!option->val)
    6247             :                 {
    6248           0 :                     if (errorMessage)
    6249           0 :                         libpq_append_error(errorMessage, "out of memory");
    6250           0 :                     return false;
    6251             :                 }
    6252           0 :                 continue;
    6253             :             }
    6254             : 
    6255             :             /*
    6256             :              * sslmode is not specified. Let it be filled in with the compiled
    6257             :              * default for now, but if sslrootcert=system, we'll override the
    6258             :              * default later before returning.
    6259             :              */
    6260       26034 :             sslmode_default = option;
    6261             :         }
    6262             : 
    6263             :         /*
    6264             :          * No environment variable specified or the variable isn't set - try
    6265             :          * compiled-in default
    6266             :          */
    6267      946156 :         if (option->compiled != NULL)
    6268             :         {
    6269      309644 :             option->val = strdup(option->compiled);
    6270      309644 :             if (!option->val)
    6271             :             {
    6272           0 :                 if (errorMessage)
    6273           0 :                     libpq_append_error(errorMessage, "out of memory");
    6274           0 :                 return false;
    6275             :             }
    6276      309644 :             continue;
    6277             :         }
    6278             : 
    6279             :         /*
    6280             :          * Special handling for "user" option.  Note that if pg_fe_getauthname
    6281             :          * fails, we just leave the value as NULL; there's no need for this to
    6282             :          * be an error condition if the caller provides a user name.  The only
    6283             :          * reason we do this now at all is so that callers of PQconndefaults
    6284             :          * will see a correct default (barring error, of course).
    6285             :          */
    6286      636512 :         if (strcmp(option->keyword, "user") == 0)
    6287             :         {
    6288       24844 :             option->val = pg_fe_getauthname(NULL);
    6289       24844 :             continue;
    6290             :         }
    6291             :     }
    6292             : 
    6293             :     /*
    6294             :      * Special handling for sslrootcert=system with no sslmode explicitly
    6295             :      * defined. In this case we want to strengthen the default sslmode to
    6296             :      * verify-full.
    6297             :      */
    6298       26704 :     if (sslmode_default && sslrootcert)
    6299             :     {
    6300       26034 :         if (sslrootcert->val && strcmp(sslrootcert->val, "system") == 0)
    6301             :         {
    6302           8 :             free(sslmode_default->val);
    6303             : 
    6304           8 :             sslmode_default->val = strdup("verify-full");
    6305           8 :             if (!sslmode_default->val)
    6306             :             {
    6307           0 :                 if (errorMessage)
    6308           0 :                     libpq_append_error(errorMessage, "out of memory");
    6309           0 :                 return false;
    6310             :             }
    6311             :         }
    6312             :     }
    6313             : 
    6314       26704 :     return true;
    6315             : }
    6316             : 
    6317             : /*
    6318             :  * Subroutine for parse_connection_string
    6319             :  *
    6320             :  * Deal with a URI connection string.
    6321             :  */
    6322             : static PQconninfoOption *
    6323         124 : conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage,
    6324             :                    bool use_defaults)
    6325             : {
    6326             :     PQconninfoOption *options;
    6327             : 
    6328             :     /* Make a working copy of PQconninfoOptions */
    6329         124 :     options = conninfo_init(errorMessage);
    6330         124 :     if (options == NULL)
    6331           0 :         return NULL;
    6332             : 
    6333         124 :     if (!conninfo_uri_parse_options(options, uri, errorMessage))
    6334             :     {
    6335          30 :         PQconninfoFree(options);
    6336          30 :         return NULL;
    6337             :     }
    6338             : 
    6339             :     /*
    6340             :      * Add in defaults if the caller wants that.
    6341             :      */
    6342          94 :     if (use_defaults)
    6343             :     {
    6344           0 :         if (!conninfo_add_defaults(options, errorMessage))
    6345             :         {
    6346           0 :             PQconninfoFree(options);
    6347           0 :             return NULL;
    6348             :         }
    6349             :     }
    6350             : 
    6351          94 :     return options;
    6352             : }
    6353             : 
    6354             : /*
    6355             :  * conninfo_uri_parse_options
    6356             :  *      Actual URI parser.
    6357             :  *
    6358             :  * If successful, returns true while the options array is filled with parsed
    6359             :  * options from the URI.
    6360             :  * If not successful, returns false and fills errorMessage accordingly.
    6361             :  *
    6362             :  * Parses the connection URI string in 'uri' according to the URI syntax (RFC
    6363             :  * 3986):
    6364             :  *
    6365             :  * postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...]
    6366             :  *
    6367             :  * where "netloc" is a hostname, an IPv4 address, or an IPv6 address surrounded
    6368             :  * by literal square brackets.  As an extension, we also allow multiple
    6369             :  * netloc[:port] specifications, separated by commas:
    6370             :  *
    6371             :  * postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]
    6372             :  *
    6373             :  * Any of the URI parts might use percent-encoding (%xy).
    6374             :  */
    6375             : static bool
    6376         124 : conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
    6377             :                            PQExpBuffer errorMessage)
    6378             : {
    6379             :     int         prefix_len;
    6380             :     char       *p;
    6381         124 :     char       *buf = NULL;
    6382             :     char       *start;
    6383         124 :     char        prevchar = '\0';
    6384         124 :     char       *user = NULL;
    6385         124 :     char       *host = NULL;
    6386         124 :     bool        retval = false;
    6387             :     PQExpBufferData hostbuf;
    6388             :     PQExpBufferData portbuf;
    6389             : 
    6390         124 :     initPQExpBuffer(&hostbuf);
    6391         124 :     initPQExpBuffer(&portbuf);
    6392         124 :     if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
    6393             :     {
    6394           0 :         libpq_append_error(errorMessage, "out of memory");
    6395           0 :         goto cleanup;
    6396             :     }
    6397             : 
    6398             :     /* need a modifiable copy of the input URI */
    6399         124 :     buf = strdup(uri);
    6400         124 :     if (buf == NULL)
    6401             :     {
    6402           0 :         libpq_append_error(errorMessage, "out of memory");
    6403           0 :         goto cleanup;
    6404             :     }
    6405         124 :     start = buf;
    6406             : 
    6407             :     /* Skip the URI prefix */
    6408         124 :     prefix_len = uri_prefix_length(uri);
    6409         124 :     if (prefix_len == 0)
    6410             :     {
    6411             :         /* Should never happen */
    6412           0 :         libpq_append_error(errorMessage,
    6413             :                            "invalid URI propagated to internal parser routine: \"%s\"",
    6414             :                            uri);
    6415           0 :         goto cleanup;
    6416             :     }
    6417         124 :     start += prefix_len;
    6418         124 :     p = start;
    6419             : 
    6420             :     /* Look ahead for possible user credentials designator */
    6421        1444 :     while (*p && *p != '@' && *p != '/')
    6422        1320 :         ++p;
    6423         124 :     if (*p == '@')
    6424             :     {
    6425             :         /*
    6426             :          * Found username/password designator, so URI should be of the form
    6427             :          * "scheme://user[:password]@[netloc]".
    6428             :          */
    6429          24 :         user = start;
    6430             : 
    6431          24 :         p = user;
    6432         208 :         while (*p != ':' && *p != '@')
    6433         184 :             ++p;
    6434             : 
    6435             :         /* Save last char and cut off at end of user name */
    6436          24 :         prevchar = *p;
    6437          24 :         *p = '\0';
    6438             : 
    6439          46 :         if (*user &&
    6440          22 :             !conninfo_storeval(options, "user", user,
    6441             :                                errorMessage, false, true))
    6442           0 :             goto cleanup;
    6443             : 
    6444          24 :         if (prevchar == ':')
    6445             :         {
    6446           2 :             const char *password = p + 1;
    6447             : 
    6448          16 :             while (*p != '@')
    6449          14 :                 ++p;
    6450           2 :             *p = '\0';
    6451             : 
    6452           4 :             if (*password &&
    6453           2 :                 !conninfo_storeval(options, "password", password,
    6454             :                                    errorMessage, false, true))
    6455           0 :                 goto cleanup;
    6456             :         }
    6457             : 
    6458             :         /* Advance past end of parsed user name or password token */
    6459          24 :         ++p;
    6460             :     }
    6461             :     else
    6462             :     {
    6463             :         /*
    6464             :          * No username/password designator found.  Reset to start of URI.
    6465             :          */
    6466         100 :         p = start;
    6467             :     }
    6468             : 
    6469             :     /*
    6470             :      * There may be multiple netloc[:port] pairs, each separated from the next
    6471             :      * by a comma.  When we initially enter this loop, "p" has been
    6472             :      * incremented past optional URI credential information at this point and
    6473             :      * now points at the "netloc" part of the URI.  On subsequent loop
    6474             :      * iterations, "p" has been incremented past the comma separator and now
    6475             :      * points at the start of the next "netloc".
    6476             :      */
    6477             :     for (;;)
    6478             :     {
    6479             :         /*
    6480             :          * Look for IPv6 address.
    6481             :          */
    6482         124 :         if (*p == '[')
    6483             :         {
    6484          16 :             host = ++p;
    6485         102 :             while (*p && *p != ']')
    6486          86 :                 ++p;
    6487          16 :             if (!*p)
    6488             :             {
    6489           2 :                 libpq_append_error(errorMessage,
    6490             :                                    "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"",
    6491             :                                    uri);
    6492           2 :                 goto cleanup;
    6493             :             }
    6494          14 :             if (p == host)
    6495             :             {
    6496           2 :                 libpq_append_error(errorMessage,
    6497             :                                    "IPv6 host address may not be empty in URI: \"%s\"",
    6498             :                                    uri);
    6499           2 :                 goto cleanup;
    6500             :             }
    6501             : 
    6502             :             /* Cut off the bracket and advance */
    6503          12 :             *(p++) = '\0';
    6504             : 
    6505             :             /*
    6506             :              * The address may be followed by a port specifier or a slash or a
    6507             :              * query or a separator comma.
    6508             :              */
    6509          12 :             if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
    6510             :             {
    6511           2 :                 libpq_append_error(errorMessage,
    6512             :                                    "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"",
    6513           2 :                                    *p, (int) (p - buf + 1), uri);
    6514           2 :                 goto cleanup;
    6515             :             }
    6516             :         }
    6517             :         else
    6518             :         {
    6519             :             /* not an IPv6 address: DNS-named or IPv4 netloc */
    6520         108 :             host = p;
    6521             : 
    6522             :             /*
    6523             :              * Look for port specifier (colon) or end of host specifier
    6524             :              * (slash) or query (question mark) or host separator (comma).
    6525             :              */
    6526         470 :             while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
    6527         362 :                 ++p;
    6528             :         }
    6529             : 
    6530             :         /* Save the hostname terminator before we null it */
    6531         118 :         prevchar = *p;
    6532         118 :         *p = '\0';
    6533             : 
    6534         118 :         appendPQExpBufferStr(&hostbuf, host);
    6535             : 
    6536         118 :         if (prevchar == ':')
    6537             :         {
    6538          28 :             const char *port = ++p; /* advance past host terminator */
    6539             : 
    6540         158 :             while (*p && *p != '/' && *p != '?' && *p != ',')
    6541         130 :                 ++p;
    6542             : 
    6543          28 :             prevchar = *p;
    6544          28 :             *p = '\0';
    6545             : 
    6546          28 :             appendPQExpBufferStr(&portbuf, port);
    6547             :         }
    6548             : 
    6549         118 :         if (prevchar != ',')
    6550         118 :             break;
    6551           0 :         ++p;                    /* advance past comma separator */
    6552           0 :         appendPQExpBufferChar(&hostbuf, ',');
    6553           0 :         appendPQExpBufferChar(&portbuf, ',');
    6554             :     }
    6555             : 
    6556             :     /* Save final values for host and port. */
    6557         118 :     if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
    6558           0 :         goto cleanup;
    6559         206 :     if (hostbuf.data[0] &&
    6560          88 :         !conninfo_storeval(options, "host", hostbuf.data,
    6561             :                            errorMessage, false, true))
    6562           8 :         goto cleanup;
    6563         136 :     if (portbuf.data[0] &&
    6564          26 :         !conninfo_storeval(options, "port", portbuf.data,
    6565             :                            errorMessage, false, true))
    6566           0 :         goto cleanup;
    6567             : 
    6568         110 :     if (prevchar && prevchar != '?')
    6569             :     {
    6570          56 :         const char *dbname = ++p;   /* advance past host terminator */
    6571             : 
    6572             :         /* Look for query parameters */
    6573         132 :         while (*p && *p != '?')
    6574          76 :             ++p;
    6575             : 
    6576          56 :         prevchar = *p;
    6577          56 :         *p = '\0';
    6578             : 
    6579             :         /*
    6580             :          * Avoid setting dbname to an empty string, as it forces the default
    6581             :          * value (username) and ignores $PGDATABASE, as opposed to not setting
    6582             :          * it at all.
    6583             :          */
    6584          90 :         if (*dbname &&
    6585          34 :             !conninfo_storeval(options, "dbname", dbname,
    6586             :                                errorMessage, false, true))
    6587           0 :             goto cleanup;
    6588             :     }
    6589             : 
    6590         110 :     if (prevchar)
    6591             :     {
    6592          54 :         ++p;                    /* advance past terminator */
    6593             : 
    6594          54 :         if (!conninfo_uri_parse_params(p, options, errorMessage))
    6595          16 :             goto cleanup;
    6596             :     }
    6597             : 
    6598             :     /* everything parsed okay */
    6599          94 :     retval = true;
    6600             : 
    6601         124 : cleanup:
    6602         124 :     termPQExpBuffer(&hostbuf);
    6603         124 :     termPQExpBuffer(&portbuf);
    6604         124 :     free(buf);
    6605         124 :     return retval;
    6606             : }
    6607             : 
    6608             : /*
    6609             :  * Connection URI parameters parser routine
    6610             :  *
    6611             :  * If successful, returns true while connOptions is filled with parsed
    6612             :  * parameters.  Otherwise, returns false and fills errorMessage appropriately.
    6613             :  *
    6614             :  * Destructively modifies 'params' buffer.
    6615             :  */
    6616             : static bool
    6617          54 : conninfo_uri_parse_params(char *params,
    6618             :                           PQconninfoOption *connOptions,
    6619             :                           PQExpBuffer errorMessage)
    6620             : {
    6621          98 :     while (*params)
    6622             :     {
    6623          60 :         char       *keyword = params;
    6624          60 :         char       *value = NULL;
    6625          60 :         char       *p = params;
    6626          60 :         bool        malloced = false;
    6627             :         int         oldmsglen;
    6628             : 
    6629             :         /*
    6630             :          * Scan the params string for '=' and '&', marking the end of keyword
    6631             :          * and value respectively.
    6632             :          */
    6633             :         for (;;)
    6634             :         {
    6635        1012 :             if (*p == '=')
    6636             :             {
    6637             :                 /* Was there '=' already? */
    6638          58 :                 if (value != NULL)
    6639             :                 {
    6640           2 :                     libpq_append_error(errorMessage,
    6641             :                                        "extra key/value separator \"=\" in URI query parameter: \"%s\"",
    6642             :                                        keyword);
    6643           2 :                     return false;
    6644             :                 }
    6645             :                 /* Cut off keyword, advance to value */
    6646          56 :                 *p++ = '\0';
    6647          56 :                 value = p;
    6648             :             }
    6649         954 :             else if (*p == '&' || *p == '\0')
    6650             :             {
    6651             :                 /*
    6652             :                  * If not at the end, cut off value and advance; leave p
    6653             :                  * pointing to start of the next parameter, if any.
    6654             :                  */
    6655          58 :                 if (*p != '\0')
    6656          14 :                     *p++ = '\0';
    6657             :                 /* Was there '=' at all? */
    6658          58 :                 if (value == NULL)
    6659             :                 {
    6660           4 :                     libpq_append_error(errorMessage,
    6661             :                                        "missing key/value separator \"=\" in URI query parameter: \"%s\"",
    6662             :                                        keyword);
    6663           4 :                     return false;
    6664             :                 }
    6665             :                 /* Got keyword and value, go process them. */
    6666          54 :                 break;
    6667             :             }
    6668             :             else
    6669         896 :                 ++p;            /* Advance over all other bytes. */
    6670             :         }
    6671             : 
    6672          54 :         keyword = conninfo_uri_decode(keyword, errorMessage);
    6673          54 :         if (keyword == NULL)
    6674             :         {
    6675             :             /* conninfo_uri_decode already set an error message */
    6676           2 :             return false;
    6677             :         }
    6678          52 :         value = conninfo_uri_decode(value, errorMessage);
    6679          52 :         if (value == NULL)
    6680             :         {
    6681             :             /* conninfo_uri_decode already set an error message */
    6682           4 :             free(keyword);
    6683           4 :             return false;
    6684             :         }
    6685          48 :         malloced = true;
    6686             : 
    6687             :         /*
    6688             :          * Special keyword handling for improved JDBC compatibility.
    6689             :          */
    6690          48 :         if (strcmp(keyword, "ssl") == 0 &&
    6691           0 :             strcmp(value, "true") == 0)
    6692             :         {
    6693           0 :             free(keyword);
    6694           0 :             free(value);
    6695           0 :             malloced = false;
    6696             : 
    6697           0 :             keyword = "sslmode";
    6698           0 :             value = "require";
    6699             :         }
    6700             : 
    6701             :         /*
    6702             :          * Store the value if the corresponding option exists; ignore
    6703             :          * otherwise.  At this point both keyword and value are not
    6704             :          * URI-encoded.
    6705             :          */
    6706          48 :         oldmsglen = errorMessage->len;
    6707          48 :         if (!conninfo_storeval(connOptions, keyword, value,
    6708             :                                errorMessage, true, false))
    6709             :         {
    6710             :             /* Insert generic message if conninfo_storeval didn't give one. */
    6711           4 :             if (errorMessage->len == oldmsglen)
    6712           4 :                 libpq_append_error(errorMessage,
    6713             :                                    "invalid URI query parameter: \"%s\"",
    6714             :                                    keyword);
    6715             :             /* And fail. */
    6716           4 :             if (malloced)
    6717             :             {
    6718           4 :                 free(keyword);
    6719           4 :                 free(value);
    6720             :             }
    6721           4 :             return false;
    6722             :         }
    6723             : 
    6724          44 :         if (malloced)
    6725             :         {
    6726          44 :             free(keyword);
    6727          44 :             free(value);
    6728             :         }
    6729             : 
    6730             :         /* Proceed to next key=value pair, if any */
    6731          44 :         params = p;
    6732             :     }
    6733             : 
    6734          38 :     return true;
    6735             : }
    6736             : 
    6737             : /*
    6738             :  * Connection URI decoder routine
    6739             :  *
    6740             :  * If successful, returns the malloc'd decoded string.
    6741             :  * If not successful, returns NULL and fills errorMessage accordingly.
    6742             :  *
    6743             :  * The string is decoded by replacing any percent-encoded tokens with
    6744             :  * corresponding characters, while preserving any non-encoded characters.  A
    6745             :  * percent-encoded token is a character triplet: a percent sign, followed by a
    6746             :  * pair of hexadecimal digits (0-9A-F), where lower- and upper-case letters are
    6747             :  * treated identically.
    6748             :  */
    6749             : static char *
    6750         278 : conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
    6751             : {
    6752             :     char       *buf;            /* result */
    6753             :     char       *p;              /* output location */
    6754         278 :     const char *q = str;        /* input location */
    6755             : 
    6756         278 :     buf = malloc(strlen(str) + 1);
    6757         278 :     if (buf == NULL)
    6758             :     {
    6759           0 :         libpq_append_error(errorMessage, "out of memory");
    6760           0 :         return NULL;
    6761             :     }
    6762         278 :     p = buf;
    6763             : 
    6764             :     /* skip leading whitespaces */
    6765         304 :     for (const char *s = q; *s == ' '; s++)
    6766             :     {
    6767          26 :         q++;
    6768          26 :         continue;
    6769             :     }
    6770             : 
    6771             :     for (;;)
    6772             :     {
    6773        1844 :         if (*q != '%')
    6774             :         {
    6775             :             /* if found a whitespace or NUL, the string ends */
    6776        1822 :             if (*q == ' ' || *q == '\0')
    6777         268 :                 goto end;
    6778             : 
    6779             :             /* copy character */
    6780        1554 :             *(p++) = *(q++);
    6781             :         }
    6782             :         else
    6783             :         {
    6784             :             int         hi;
    6785             :             int         lo;
    6786             :             int         c;
    6787             : 
    6788          22 :             ++q;                /* skip the percent sign itself */
    6789             : 
    6790             :             /*
    6791             :              * Possible EOL will be caught by the first call to
    6792             :              * get_hexdigit(), so we never dereference an invalid q pointer.
    6793             :              */
    6794          22 :             if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
    6795             :             {
    6796           8 :                 libpq_append_error(errorMessage,
    6797             :                                    "invalid percent-encoded token: \"%s\"",
    6798             :                                    str);
    6799           8 :                 free(buf);
    6800          10 :                 return NULL;
    6801             :             }
    6802             : 
    6803          14 :             c = (hi << 4) | lo;
    6804          14 :             if (c == 0)
    6805             :             {
    6806           2 :                 libpq_append_error(errorMessage,
    6807             :                                    "forbidden value %%00 in percent-encoded value: \"%s\"",
    6808             :                                    str);
    6809           2 :                 free(buf);
    6810           2 :                 return NULL;
    6811             :             }
    6812          12 :             *(p++) = c;
    6813             :         }
    6814             :     }
    6815             : 
    6816         268 : end:
    6817             : 
    6818             :     /* skip trailing whitespaces */
    6819         292 :     for (const char *s = q; *s == ' '; s++)
    6820             :     {
    6821          24 :         q++;
    6822          24 :         continue;
    6823             :     }
    6824             : 
    6825             :     /* Not at the end of the string yet?  Fail. */
    6826         268 :     if (*q != '\0')
    6827             :     {
    6828           4 :         libpq_append_error(errorMessage,
    6829             :                            "unexpected spaces found in \"%s\", use percent-encoded spaces (%%20) instead",
    6830             :                            str);
    6831           4 :         free(buf);
    6832           4 :         return NULL;
    6833             :     }
    6834             : 
    6835             :     /* Copy NUL terminator */
    6836         264 :     *p = '\0';
    6837             : 
    6838         264 :     return buf;
    6839             : }
    6840             : 
    6841             : /*
    6842             :  * Convert hexadecimal digit character to its integer value.
    6843             :  *
    6844             :  * If successful, returns true and value is filled with digit's base 16 value.
    6845             :  * If not successful, returns false.
    6846             :  *
    6847             :  * Lower- and upper-case letters in the range A-F are treated identically.
    6848             :  */
    6849             : static bool
    6850          38 : get_hexdigit(char digit, int *value)
    6851             : {
    6852          38 :     if ('0' <= digit && digit <= '9')
    6853          22 :         *value = digit - '0';
    6854          16 :     else if ('A' <= digit && digit <= 'F')
    6855           6 :         *value = digit - 'A' + 10;
    6856          10 :     else if ('a' <= digit && digit <= 'f')
    6857           2 :         *value = digit - 'a' + 10;
    6858             :     else
    6859           8 :         return false;
    6860             : 
    6861          30 :     return true;
    6862             : }
    6863             : 
    6864             : /*
    6865             :  * Find an option value corresponding to the keyword in the connOptions array.
    6866             :  *
    6867             :  * If successful, returns a pointer to the corresponding option's value.
    6868             :  * If not successful, returns NULL.
    6869             :  */
    6870             : static const char *
    6871     1089024 : conninfo_getval(PQconninfoOption *connOptions,
    6872             :                 const char *keyword)
    6873             : {
    6874             :     PQconninfoOption *option;
    6875             : 
    6876     1089024 :     option = conninfo_find(connOptions, keyword);
    6877             : 
    6878     1089024 :     return option ? option->val : NULL;
    6879             : }
    6880             : 
    6881             : /*
    6882             :  * Store a (new) value for an option corresponding to the keyword in
    6883             :  * connOptions array.
    6884             :  *
    6885             :  * If uri_decode is true, the value is URI-decoded.  The keyword is always
    6886             :  * assumed to be non URI-encoded.
    6887             :  *
    6888             :  * If successful, returns a pointer to the corresponding PQconninfoOption,
    6889             :  * which value is replaced with a strdup'd copy of the passed value string.
    6890             :  * The existing value for the option is free'd before replacing, if any.
    6891             :  *
    6892             :  * If not successful, returns NULL and fills errorMessage accordingly.
    6893             :  * However, if the reason of failure is an invalid keyword being passed and
    6894             :  * ignoreMissing is true, errorMessage will be left untouched.
    6895             :  */
    6896             : static PQconninfoOption *
    6897       78472 : conninfo_storeval(PQconninfoOption *connOptions,
    6898             :                   const char *keyword, const char *value,
    6899             :                   PQExpBuffer errorMessage, bool ignoreMissing,
    6900             :                   bool uri_decode)
    6901             : {
    6902             :     PQconninfoOption *option;
    6903             :     char       *value_copy;
    6904             : 
    6905             :     /*
    6906             :      * For backwards compatibility, requiressl=1 gets translated to
    6907             :      * sslmode=require, and requiressl=0 gets translated to sslmode=prefer
    6908             :      * (which is the default for sslmode).
    6909             :      */
    6910       78472 :     if (strcmp(keyword, "requiressl") == 0)
    6911             :     {
    6912           0 :         keyword = "sslmode";
    6913           0 :         if (value[0] == '1')
    6914           0 :             value = "require";
    6915             :         else
    6916           0 :             value = "prefer";
    6917             :     }
    6918             : 
    6919       78472 :     option = conninfo_find(connOptions, keyword);
    6920       78472 :     if (option == NULL)
    6921             :     {
    6922          10 :         if (!ignoreMissing)
    6923           6 :             libpq_append_error(errorMessage,
    6924             :                                "invalid connection option \"%s\"",
    6925             :                                keyword);
    6926          10 :         return NULL;
    6927             :     }
    6928             : 
    6929       78462 :     if (uri_decode)
    6930             :     {
    6931         172 :         value_copy = conninfo_uri_decode(value, errorMessage);
    6932         172 :         if (value_copy == NULL)
    6933             :             /* conninfo_uri_decode already set an error message */
    6934           8 :             return NULL;
    6935             :     }
    6936             :     else
    6937             :     {
    6938       78290 :         value_copy = strdup(value);
    6939       78290 :         if (value_copy == NULL)
    6940             :         {
    6941           0 :             libpq_append_error(errorMessage, "out of memory");
    6942           0 :             return NULL;
    6943             :         }
    6944             :     }
    6945             : 
    6946       78454 :     free(option->val);
    6947       78454 :     option->val = value_copy;
    6948             : 
    6949       78454 :     return option;
    6950             : }
    6951             : 
    6952             : /*
    6953             :  * Find a PQconninfoOption option corresponding to the keyword in the
    6954             :  * connOptions array.
    6955             :  *
    6956             :  * If successful, returns a pointer to the corresponding PQconninfoOption
    6957             :  * structure.
    6958             :  * If not successful, returns NULL.
    6959             :  */
    6960             : static PQconninfoOption *
    6961     1167496 : conninfo_find(PQconninfoOption *connOptions, const char *keyword)
    6962             : {
    6963             :     PQconninfoOption *option;
    6964             : 
    6965    23721670 :     for (option = connOptions; option->keyword != NULL; option++)
    6966             :     {
    6967    23721660 :         if (strcmp(option->keyword, keyword) == 0)
    6968     1167486 :             return option;
    6969             :     }
    6970             : 
    6971          10 :     return NULL;
    6972             : }
    6973             : 
    6974             : 
    6975             : /*
    6976             :  * Return the connection options used for the connection
    6977             :  */
    6978             : PQconninfoOption *
    6979         606 : PQconninfo(PGconn *conn)
    6980             : {
    6981             :     PQExpBufferData errorBuf;
    6982             :     PQconninfoOption *connOptions;
    6983             : 
    6984         606 :     if (conn == NULL)
    6985           0 :         return NULL;
    6986             : 
    6987             :     /*
    6988             :      * We don't actually report any errors here, but callees want a buffer,
    6989             :      * and we prefer not to trash the conn's errorMessage.
    6990             :      */
    6991         606 :     initPQExpBuffer(&errorBuf);
    6992         606 :     if (PQExpBufferDataBroken(errorBuf))
    6993           0 :         return NULL;            /* out of memory already :-( */
    6994             : 
    6995         606 :     connOptions = conninfo_init(&errorBuf);
    6996             : 
    6997         606 :     if (connOptions != NULL)
    6998             :     {
    6999             :         const internalPQconninfoOption *option;
    7000             : 
    7001       25452 :         for (option = PQconninfoOptions; option->keyword; option++)
    7002             :         {
    7003             :             char      **connmember;
    7004             : 
    7005       24846 :             if (option->connofs < 0)
    7006         606 :                 continue;
    7007             : 
    7008       24240 :             connmember = (char **) ((char *) conn + option->connofs);
    7009             : 
    7010       24240 :             if (*connmember)
    7011       12154 :                 conninfo_storeval(connOptions, option->keyword, *connmember,
    7012             :                                   &errorBuf, true, false);
    7013             :         }
    7014             :     }
    7015             : 
    7016         606 :     termPQExpBuffer(&errorBuf);
    7017             : 
    7018         606 :     return connOptions;
    7019             : }
    7020             : 
    7021             : 
    7022             : void
    7023       73770 : PQconninfoFree(PQconninfoOption *connOptions)
    7024             : {
    7025       73770 :     if (connOptions == NULL)
    7026       26214 :         return;
    7027             : 
    7028     1997352 :     for (PQconninfoOption *option = connOptions; option->keyword != NULL; option++)
    7029     1949796 :         free(option->val);
    7030       47556 :     free(connOptions);
    7031             : }
    7032             : 
    7033             : 
    7034             : /* =========== accessor functions for PGconn ========= */
    7035             : char *
    7036       36068 : PQdb(const PGconn *conn)
    7037             : {
    7038       36068 :     if (!conn)
    7039           2 :         return NULL;
    7040       36066 :     return conn->dbName;
    7041             : }
    7042             : 
    7043             : char *
    7044       18662 : PQuser(const PGconn *conn)
    7045             : {
    7046       18662 :     if (!conn)
    7047           0 :         return NULL;
    7048       18662 :     return conn->pguser;
    7049             : }
    7050             : 
    7051             : char *
    7052         348 : PQpass(const PGconn *conn)
    7053             : {
    7054         348 :     char       *password = NULL;
    7055             : 
    7056         348 :     if (!conn)
    7057           0 :         return NULL;
    7058         348 :     if (conn->connhost != NULL)
    7059         348 :         password = conn->connhost[conn->whichhost].password;
    7060         348 :     if (password == NULL)
    7061         344 :         password = conn->pgpass;
    7062             :     /* Historically we've returned "" not NULL for no password specified */
    7063         348 :     if (password == NULL)
    7064         220 :         password = "";
    7065         348 :     return password;
    7066             : }
    7067             : 
    7068             : char *
    7069       18958 : PQhost(const PGconn *conn)
    7070             : {
    7071       18958 :     if (!conn)
    7072           0 :         return NULL;
    7073             : 
    7074       18958 :     if (conn->connhost != NULL)
    7075             :     {
    7076             :         /*
    7077             :          * Return the verbatim host value provided by user, or hostaddr in its
    7078             :          * lack.
    7079             :          */
    7080       18958 :         if (conn->connhost[conn->whichhost].host != NULL &&
    7081       18958 :             conn->connhost[conn->whichhost].host[0] != '\0')
    7082       18958 :             return conn->connhost[conn->whichhost].host;
    7083           0 :         else if (conn->connhost[conn->whichhost].hostaddr != NULL &&
    7084           0 :                  conn->connhost[conn->whichhost].hostaddr[0] != '\0')
    7085           0 :             return conn->connhost[conn->whichhost].hostaddr;
    7086             :     }
    7087             : 
    7088           0 :     return "";
    7089             : }
    7090             : 
    7091             : char *
    7092           0 : PQhostaddr(const PGconn *conn)
    7093             : {
    7094           0 :     if (!conn)
    7095           0 :         return NULL;
    7096             : 
    7097             :     /* Return the parsed IP address */
    7098           0 :     if (conn->connhost != NULL && conn->connip != NULL)
    7099           0 :         return conn->connip;
    7100             : 
    7101           0 :     return "";
    7102             : }
    7103             : 
    7104             : char *
    7105       18958 : PQport(const PGconn *conn)
    7106             : {
    7107       18958 :     if (!conn)
    7108           0 :         return NULL;
    7109             : 
    7110       18958 :     if (conn->connhost != NULL)
    7111       18958 :         return conn->connhost[conn->whichhost].port;
    7112             : 
    7113           0 :     return "";
    7114             : }
    7115             : 
    7116             : /*
    7117             :  * No longer does anything, but the function remains for API backwards
    7118             :  * compatibility.
    7119             :  */
    7120             : char *
    7121           0 : PQtty(const PGconn *conn)
    7122             : {
    7123           0 :     if (!conn)
    7124           0 :         return NULL;
    7125           0 :     return "";
    7126             : }
    7127             : 
    7128             : char *
    7129           0 : PQoptions(const PGconn *conn)
    7130             : {
    7131           0 :     if (!conn)
    7132           0 :         return NULL;
    7133           0 :     return conn->pgoptions;
    7134             : }
    7135             : 
    7136             : ConnStatusType
    7137      440650 : PQstatus(const PGconn *conn)
    7138             : {
    7139      440650 :     if (!conn)
    7140           0 :         return CONNECTION_BAD;
    7141      440650 :     return conn->status;
    7142             : }
    7143             : 
    7144             : PGTransactionStatusType
    7145      358106 : PQtransactionStatus(const PGconn *conn)
    7146             : {
    7147      358106 :     if (!conn || conn->status != CONNECTION_OK)
    7148           0 :         return PQTRANS_UNKNOWN;
    7149      358106 :     if (conn->asyncStatus != PGASYNC_IDLE)
    7150           2 :         return PQTRANS_ACTIVE;
    7151      358104 :     return conn->xactStatus;
    7152             : }
    7153             : 
    7154             : const char *
    7155      658546 : PQparameterStatus(const PGconn *conn, const char *paramName)
    7156             : {
    7157             :     const pgParameterStatus *pstatus;
    7158             : 
    7159      658546 :     if (!conn || !paramName)
    7160           0 :         return NULL;
    7161     3434704 :     for (pstatus = conn->pstatus; pstatus != NULL; pstatus = pstatus->next)
    7162             :     {
    7163     3434704 :         if (strcmp(pstatus->name, paramName) == 0)
    7164      658546 :             return pstatus->value;
    7165             :     }
    7166           0 :     return NULL;
    7167             : }
    7168             : 
    7169             : int
    7170           0 : PQprotocolVersion(const PGconn *conn)
    7171             : {
    7172           0 :     if (!conn)
    7173           0 :         return 0;
    7174           0 :     if (conn->status == CONNECTION_BAD)
    7175           0 :         return 0;
    7176           0 :     return PG_PROTOCOL_MAJOR(conn->pversion);
    7177             : }
    7178             : 
    7179             : int
    7180           0 : PQfullProtocolVersion(const PGconn *conn)
    7181             : {
    7182           0 :     if (!conn)
    7183           0 :         return 0;
    7184           0 :     if (conn->status == CONNECTION_BAD)
    7185           0 :         return 0;
    7186           0 :     return PG_PROTOCOL_FULL(conn->pversion);
    7187             : }
    7188             : 
    7189             : int
    7190       45892 : PQserverVersion(const PGconn *conn)
    7191             : {
    7192       45892 :     if (!conn)
    7193           0 :         return 0;
    7194       45892 :     if (conn->status == CONNECTION_BAD)
    7195           0 :         return 0;
    7196       45892 :     return conn->sversion;
    7197             : }
    7198             : 
    7199             : char *
    7200        1166 : PQerrorMessage(const PGconn *conn)
    7201             : {
    7202        1166 :     if (!conn)
    7203           0 :         return libpq_gettext("connection pointer is NULL\n");
    7204             : 
    7205             :     /*
    7206             :      * The errorMessage buffer might be marked "broken" due to having
    7207             :      * previously failed to allocate enough memory for the message.  In that
    7208             :      * case, tell the application we ran out of memory.
    7209             :      */
    7210        1166 :     if (PQExpBufferBroken(&conn->errorMessage))
    7211           0 :         return libpq_gettext("out of memory\n");
    7212             : 
    7213        1166 :     return conn->errorMessage.data;
    7214             : }
    7215             : 
    7216             : /*
    7217             :  * In Windows, socket values are unsigned, and an invalid socket value
    7218             :  * (INVALID_SOCKET) is ~0, which equals -1 in comparisons (with no compiler
    7219             :  * warning). Ideally we would return an unsigned value for PQsocket() on
    7220             :  * Windows, but that would cause the function's return value to differ from
    7221             :  * Unix, so we just return -1 for invalid sockets.
    7222             :  * http://msdn.microsoft.com/en-us/library/windows/desktop/cc507522%28v=vs.85%29.aspx
    7223             :  * http://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c
    7224             :  */
    7225             : int
    7226      448744 : PQsocket(const PGconn *conn)
    7227             : {
    7228      448744 :     if (!conn)
    7229           0 :         return -1;
    7230      448744 :     return (conn->sock != PGINVALID_SOCKET) ? conn->sock : -1;
    7231             : }
    7232             : 
    7233             : int
    7234        1484 : PQbackendPID(const PGconn *conn)
    7235             : {
    7236        1484 :     if (!conn || conn->status != CONNECTION_OK)
    7237           0 :         return 0;
    7238        1484 :     return conn->be_pid;
    7239             : }
    7240             : 
    7241             : PGpipelineStatus
    7242       80372 : PQpipelineStatus(const PGconn *conn)
    7243             : {
    7244       80372 :     if (!conn)
    7245           0 :         return PQ_PIPELINE_OFF;
    7246             : 
    7247       80372 :     return conn->pipelineStatus;
    7248             : }
    7249             : 
    7250             : int
    7251         348 : PQconnectionNeedsPassword(const PGconn *conn)
    7252             : {
    7253             :     char       *password;
    7254             : 
    7255         348 :     if (!conn)
    7256           0 :         return false;
    7257         348 :     password = PQpass(conn);
    7258         348 :     if (conn->password_needed &&
    7259          44 :         (password == NULL || password[0] == '\0'))
    7260           2 :         return true;
    7261             :     else
    7262         346 :         return false;
    7263             : }
    7264             : 
    7265             : int
    7266         534 : PQconnectionUsedPassword(const PGconn *conn)
    7267             : {
    7268         534 :     if (!conn)
    7269           0 :         return false;
    7270         534 :     if (conn->password_needed)
    7271           2 :         return true;
    7272             :     else
    7273         532 :         return false;
    7274             : }
    7275             : 
    7276             : int
    7277           0 : PQconnectionUsedGSSAPI(const PGconn *conn)
    7278             : {
    7279           0 :     if (!conn)
    7280           0 :         return false;
    7281           0 :     if (conn->gssapi_used)
    7282           0 :         return true;
    7283             :     else
    7284           0 :         return false;
    7285             : }
    7286             : 
    7287             : int
    7288      354680 : PQclientEncoding(const PGconn *conn)
    7289             : {
    7290      354680 :     if (!conn || conn->status != CONNECTION_OK)
    7291           0 :         return -1;
    7292      354680 :     return conn->client_encoding;
    7293             : }
    7294             : 
    7295             : int
    7296          36 : PQsetClientEncoding(PGconn *conn, const char *encoding)
    7297             : {
    7298             :     char        qbuf[128];
    7299             :     static const char query[] = "set client_encoding to '%s'";
    7300             :     PGresult   *res;
    7301             :     int         status;
    7302             : 
    7303          36 :     if (!conn || conn->status != CONNECTION_OK)
    7304           0 :         return -1;
    7305             : 
    7306          36 :     if (!encoding)
    7307           0 :         return -1;
    7308             : 
    7309             :     /* Resolve special "auto" value from the locale */
    7310          36 :     if (strcmp(encoding, "auto") == 0)
    7311           0 :         encoding = pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true));
    7312             : 
    7313             :     /* check query buffer overflow */
    7314          36 :     if (sizeof(qbuf) < (sizeof(query) + strlen(encoding)))
    7315           0 :         return -1;
    7316             : 
    7317             :     /* ok, now send a query */
    7318          36 :     sprintf(qbuf, query, encoding);
    7319          36 :     res = PQexec(conn, qbuf);
    7320             : 
    7321          36 :     if (res == NULL)
    7322           0 :         return -1;
    7323          36 :     if (res->resultStatus != PGRES_COMMAND_OK)
    7324           0 :         status = -1;
    7325             :     else
    7326             :     {
    7327             :         /*
    7328             :          * We rely on the backend to report the parameter value, and we'll
    7329             :          * change state at that time.
    7330             :          */
    7331          36 :         status = 0;             /* everything is ok */
    7332             :     }
    7333          36 :     PQclear(res);
    7334          36 :     return status;
    7335             : }
    7336             : 
    7337             : PGVerbosity
    7338       18800 : PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
    7339             : {
    7340             :     PGVerbosity old;
    7341             : 
    7342       18800 :     if (!conn)
    7343           0 :         return PQERRORS_DEFAULT;
    7344       18800 :     old = conn->verbosity;
    7345       18800 :     conn->verbosity = verbosity;
    7346       18800 :     return old;
    7347             : }
    7348             : 
    7349             : PGContextVisibility
    7350       18692 : PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context)
    7351             : {
    7352             :     PGContextVisibility old;
    7353             : 
    7354       18692 :     if (!conn)
    7355           0 :         return PQSHOW_CONTEXT_ERRORS;
    7356       18692 :     old = conn->show_context;
    7357       18692 :     conn->show_context = show_context;
    7358       18692 :     return old;
    7359             : }
    7360             : 
    7361             : PQnoticeReceiver
    7362         522 : PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg)
    7363             : {
    7364             :     PQnoticeReceiver old;
    7365             : 
    7366         522 :     if (conn == NULL)
    7367           0 :         return NULL;
    7368             : 
    7369         522 :     old = conn->noticeHooks.noticeRec;
    7370         522 :     if (proc)
    7371             :     {
    7372         522 :         conn->noticeHooks.noticeRec = proc;
    7373         522 :         conn->noticeHooks.noticeRecArg = arg;
    7374             :     }
    7375         522 :     return old;
    7376             : }
    7377             : 
    7378             : PQnoticeProcessor
    7379       20120 : PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
    7380             : {
    7381             :     PQnoticeProcessor old;
    7382             : 
    7383       20120 :     if (conn == NULL)
    7384           0 :         return NULL;
    7385             : 
    7386       20120 :     old = conn->noticeHooks.noticeProc;
    7387       20120 :     if (proc)
    7388             :     {
    7389       20120 :         conn->noticeHooks.noticeProc = proc;
    7390       20120 :         conn->noticeHooks.noticeProcArg = arg;
    7391             :     }
    7392       20120 :     return old;
    7393             : }
    7394             : 
    7395             : /*
    7396             :  * The default notice message receiver just gets the standard notice text
    7397             :  * and sends it to the notice processor.  This two-level setup exists
    7398             :  * mostly for backwards compatibility; perhaps we should deprecate use of
    7399             :  * PQsetNoticeProcessor?
    7400             :  */
    7401             : static void
    7402      155518 : defaultNoticeReceiver(void *arg, const PGresult *res)
    7403             : {
    7404             :     (void) arg;                 /* not used */
    7405      155518 :     if (res->noticeHooks.noticeProc != NULL)
    7406      155518 :         res->noticeHooks.noticeProc(res->noticeHooks.noticeProcArg,
    7407      155518 :                                     PQresultErrorMessage(res));
    7408      155518 : }
    7409             : 
    7410             : /*
    7411             :  * The default notice message processor just prints the
    7412             :  * message on stderr.  Applications can override this if they
    7413             :  * want the messages to go elsewhere (a window, for example).
    7414             :  * Note that simply discarding notices is probably a bad idea.
    7415             :  */
    7416             : static void
    7417         134 : defaultNoticeProcessor(void *arg, const char *message)
    7418             : {
    7419             :     (void) arg;                 /* not used */
    7420             :     /* Note: we expect the supplied string to end with a newline already. */
    7421         134 :     fprintf(stderr, "%s", message);
    7422         134 : }
    7423             : 
    7424             : /*
    7425             :  * returns a pointer to the next token or NULL if the current
    7426             :  * token doesn't match
    7427             :  */
    7428             : static char *
    7429          92 : pwdfMatchesString(char *buf, const char *token)
    7430             : {
    7431             :     char       *tbuf;
    7432             :     const char *ttok;
    7433          92 :     bool        bslash = false;
    7434             : 
    7435          92 :     if (buf == NULL || token == NULL)
    7436           0 :         return NULL;
    7437          92 :     tbuf = buf;
    7438          92 :     ttok = token;
    7439          92 :     if (tbuf[0] == '*' && tbuf[1] == ':')
    7440          56 :         return tbuf + 2;
    7441         292 :     while (*tbuf != 0)
    7442             :     {
    7443         292 :         if (*tbuf == '\\' && !bslash)
    7444             :         {
    7445           0 :             tbuf++;
    7446           0 :             bslash = true;
    7447             :         }
    7448         292 :         if (*tbuf == ':' && *ttok == 0 && !bslash)
    7449          26 :             return tbuf + 1;
    7450         266 :         bslash = false;
    7451         266 :         if (*ttok == 0)
    7452           0 :             return NULL;
    7453         266 :         if (*tbuf == *ttok)
    7454             :         {
    7455         256 :             tbuf++;
    7456         256 :             ttok++;
    7457             :         }
    7458             :         else
    7459          10 :             return NULL;
    7460             :     }
    7461           0 :     return NULL;
    7462             : }
    7463             : 
    7464             : /* Get a password from the password file. Return value is malloc'd. */
    7465             : static char *
    7466       26514 : passwordFromFile(const char *hostname, const char *port, const char *dbname,
    7467             :                  const char *username, const char *pgpassfile)
    7468             : {
    7469             :     FILE       *fp;
    7470             : #ifndef WIN32
    7471             :     struct stat stat_buf;
    7472             : #endif
    7473             :     PQExpBufferData buf;
    7474             : 
    7475       26514 :     if (dbname == NULL || dbname[0] == '\0')
    7476           0 :         return NULL;
    7477             : 
    7478       26514 :     if (username == NULL || username[0] == '\0')
    7479           0 :         return NULL;
    7480             : 
    7481             :     /* 'localhost' matches pghost of '' or the default socket directory */
    7482       26514 :     if (hostname == NULL || hostname[0] == '\0')
    7483           0 :         hostname = DefaultHost;
    7484       26514 :     else if (is_unixsock_path(hostname))
    7485             : 
    7486             :         /*
    7487             :          * We should probably use canonicalize_path(), but then we have to
    7488             :          * bring path.c into libpq, and it doesn't seem worth it.
    7489             :          */
    7490       25922 :         if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0)
    7491           0 :             hostname = DefaultHost;
    7492             : 
    7493       26514 :     if (port == NULL || port[0] == '\0')
    7494           0 :         port = DEF_PGPORT_STR;
    7495             : 
    7496             :     /* If password file cannot be opened, ignore it. */
    7497       26514 :     fp = fopen(pgpassfile, "r");
    7498       26514 :     if (fp == NULL)
    7499       26498 :         return NULL;
    7500             : 
    7501             : #ifndef WIN32
    7502          16 :     if (fstat(fileno(fp), &stat_buf) != 0)
    7503             :     {
    7504           0 :         fclose(fp);
    7505           0 :         return NULL;
    7506             :     }
    7507             : 
    7508          16 :     if (!S_ISREG(stat_buf.st_mode))
    7509             :     {
    7510           0 :         fprintf(stderr,
    7511           0 :                 libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"),
    7512             :                 pgpassfile);
    7513           0 :         fclose(fp);
    7514           0 :         return NULL;
    7515             :     }
    7516             : 
    7517             :     /* If password file is insecure, alert the user and ignore it. */
    7518          16 :     if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
    7519             :     {
    7520           0 :         fprintf(stderr,
    7521           0 :                 libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
    7522             :                 pgpassfile);
    7523           0 :         fclose(fp);
    7524           0 :         return NULL;
    7525             :     }
    7526             : #else
    7527             : 
    7528             :     /*
    7529             :      * On Win32, the directory is protected, so we don't have to check the
    7530             :      * file.
    7531             :      */
    7532             : #endif
    7533             : 
    7534             :     /* Use an expansible buffer to accommodate any reasonable line length */
    7535          16 :     initPQExpBuffer(&buf);
    7536             : 
    7537          80 :     while (!feof(fp) && !ferror(fp))
    7538             :     {
    7539             :         /* Make sure there's a reasonable amount of room in the buffer */
    7540          80 :         if (!enlargePQExpBuffer(&buf, 128))
    7541           0 :             break;
    7542             : 
    7543             :         /* Read some data, appending it to what we already have */
    7544          80 :         if (fgets(buf.data + buf.len, buf.maxlen - buf.len, fp) == NULL)
    7545           2 :             break;
    7546          78 :         buf.len += strlen(buf.data + buf.len);
    7547             : 
    7548             :         /* If we don't yet have a whole line, loop around to read more */
    7549          78 :         if (!(buf.len > 0 && buf.data[buf.len - 1] == '\n') && !feof(fp))
    7550          16 :             continue;
    7551             : 
    7552             :         /* ignore comments */
    7553          62 :         if (buf.data[0] != '#')
    7554             :         {
    7555          46 :             char       *t = buf.data;
    7556             :             int         len;
    7557             : 
    7558             :             /* strip trailing newline and carriage return */
    7559          46 :             len = pg_strip_crlf(t);
    7560             : 
    7561          70 :             if (len > 0 &&
    7562          48 :                 (t = pwdfMatchesString(t, hostname)) != NULL &&
    7563          48 :                 (t = pwdfMatchesString(t, port)) != NULL &&
    7564          44 :                 (t = pwdfMatchesString(t, dbname)) != NULL &&
    7565          20 :                 (t = pwdfMatchesString(t, username)) != NULL)
    7566             :             {
    7567             :                 /* Found a match. */
    7568             :                 char       *ret,
    7569             :                            *p1,
    7570             :                            *p2;
    7571             : 
    7572          14 :                 ret = strdup(t);
    7573             : 
    7574          14 :                 fclose(fp);
    7575          14 :                 explicit_bzero(buf.data, buf.maxlen);
    7576          14 :                 termPQExpBuffer(&buf);
    7577             : 
    7578          14 :                 if (!ret)
    7579             :                 {
    7580             :                     /* Out of memory. XXX: an error message would be nice. */
    7581           0 :                     return NULL;
    7582             :                 }
    7583             : 
    7584             :                 /* De-escape password. */
    7585          70 :                 for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2)
    7586             :                 {
    7587          56 :                     if (*p1 == '\\' && p1[1] != '\0')
    7588           6 :                         ++p1;
    7589          56 :                     *p2 = *p1;
    7590             :                 }
    7591          14 :                 *p2 = '\0';
    7592             : 
    7593          14 :                 return ret;
    7594             :             }
    7595             :         }
    7596             : 
    7597             :         /* No match, reset buffer to prepare for next line. */
    7598          48 :         buf.len = 0;
    7599             :     }
    7600             : 
    7601           2 :     fclose(fp);
    7602           2 :     explicit_bzero(buf.data, buf.maxlen);
    7603           2 :     termPQExpBuffer(&buf);
    7604           2 :     return NULL;
    7605             : }
    7606             : 
    7607             : 
    7608             : /*
    7609             :  *  If the connection failed due to bad password, we should mention
    7610             :  *  if we got the password from the pgpassfile.
    7611             :  */
    7612             : static void
    7613          96 : pgpassfileWarning(PGconn *conn)
    7614             : {
    7615             :     /* If it was 'invalid authorization', add pgpassfile mention */
    7616             :     /* only works with >= 9.0 servers */
    7617          96 :     if (conn->password_needed &&
    7618          42 :         conn->connhost[conn->whichhost].password != NULL &&
    7619           0 :         conn->result)
    7620             :     {
    7621           0 :         const char *sqlstate = PQresultErrorField(conn->result,
    7622             :                                                   PG_DIAG_SQLSTATE);
    7623             : 
    7624           0 :         if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0)
    7625           0 :             libpq_append_conn_error(conn, "password retrieved from file \"%s\"",
    7626             :                                     conn->pgpassfile);
    7627             :     }
    7628          96 : }
    7629             : 
    7630             : /*
    7631             :  * Check if the SSL protocol value given in input is valid or not.
    7632             :  * This is used as a sanity check routine for the connection parameters
    7633             :  * ssl_min_protocol_version and ssl_max_protocol_version.
    7634             :  */
    7635             : static bool
    7636       53022 : sslVerifyProtocolVersion(const char *version)
    7637             : {
    7638             :     /*
    7639             :      * An empty string and a NULL value are considered valid as it is
    7640             :      * equivalent to ignoring the parameter.
    7641             :      */
    7642       53022 :     if (!version || strlen(version) == 0)
    7643       26502 :         return true;
    7644             : 
    7645       53040 :     if (pg_strcasecmp(version, "TLSv1") == 0 ||
    7646       53038 :         pg_strcasecmp(version, "TLSv1.1") == 0 ||
    7647       26522 :         pg_strcasecmp(version, "TLSv1.2") == 0 ||
    7648           4 :         pg_strcasecmp(version, "TLSv1.3") == 0)
    7649       26516 :         return true;
    7650             : 
    7651             :     /* anything else is wrong */
    7652           4 :     return false;
    7653             : }
    7654             : 
    7655             : 
    7656             : /*
    7657             :  * Ensure that the SSL protocol range given in input is correct.  The check
    7658             :  * is performed on the input string to keep it TLS backend agnostic.  Input
    7659             :  * to this function is expected verified with sslVerifyProtocolVersion().
    7660             :  */
    7661             : static bool
    7662       26508 : sslVerifyProtocolRange(const char *min, const char *max)
    7663             : {
    7664             :     Assert(sslVerifyProtocolVersion(min) &&
    7665             :            sslVerifyProtocolVersion(max));
    7666             : 
    7667             :     /* If at least one of the bounds is not set, the range is valid */
    7668       26508 :     if (min == NULL || max == NULL || strlen(min) == 0 || strlen(max) == 0)
    7669       26502 :         return true;
    7670             : 
    7671             :     /*
    7672             :      * If the minimum version is the lowest one we accept, then all options
    7673             :      * for the maximum are valid.
    7674             :      */
    7675           6 :     if (pg_strcasecmp(min, "TLSv1") == 0)
    7676           0 :         return true;
    7677             : 
    7678             :     /*
    7679             :      * The minimum bound is valid, and cannot be TLSv1, so using TLSv1 for the
    7680             :      * maximum is incorrect.
    7681             :      */
    7682           6 :     if (pg_strcasecmp(max, "TLSv1") == 0)
    7683           0 :         return false;
    7684             : 
    7685             :     /*
    7686             :      * At this point we know that we have a mix of TLSv1.1 through 1.3
    7687             :      * versions.
    7688             :      */
    7689           6 :     if (pg_strcasecmp(min, max) > 0)
    7690           2 :         return false;
    7691             : 
    7692           4 :     return true;
    7693             : }
    7694             : 
    7695             : 
    7696             : /*
    7697             :  * Obtain user's home directory, return in given buffer
    7698             :  *
    7699             :  * On Unix, this actually returns the user's home directory.  On Windows
    7700             :  * it returns the PostgreSQL-specific application data folder.
    7701             :  *
    7702             :  * This is essentially the same as get_home_path(), but we don't use that
    7703             :  * because we don't want to pull path.c into libpq (it pollutes application
    7704             :  * namespace).
    7705             :  *
    7706             :  * Returns true on success, false on failure to obtain the directory name.
    7707             :  *
    7708             :  * CAUTION: although in most situations failure is unexpected, there are users
    7709             :  * who like to run applications in a home-directory-less environment.  On
    7710             :  * failure, you almost certainly DO NOT want to report an error.  Just act as
    7711             :  * though whatever file you were hoping to find in the home directory isn't
    7712             :  * there (which it isn't).
    7713             :  */
    7714             : bool
    7715       25954 : pqGetHomeDirectory(char *buf, int bufsize)
    7716             : {
    7717             : #ifndef WIN32
    7718             :     const char *home;
    7719             : 
    7720       25954 :     home = getenv("HOME");
    7721       25954 :     if (home && home[0])
    7722             :     {
    7723       25954 :         strlcpy(buf, home, bufsize);
    7724       25954 :         return true;
    7725             :     }
    7726             :     else
    7727             :     {
    7728             :         struct passwd pwbuf;
    7729             :         struct passwd *pw;
    7730             :         char        tmpbuf[1024];
    7731             :         int         rc;
    7732             : 
    7733           0 :         rc = getpwuid_r(geteuid(), &pwbuf, tmpbuf, sizeof tmpbuf, &pw);
    7734           0 :         if (rc != 0 || !pw)
    7735           0 :             return false;
    7736           0 :         strlcpy(buf, pw->pw_dir, bufsize);
    7737           0 :         return true;
    7738             :     }
    7739             : #else
    7740             :     char        tmppath[MAX_PATH];
    7741             : 
    7742             :     ZeroMemory(tmppath, sizeof(tmppath));
    7743             :     if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK)
    7744             :         return false;
    7745             :     snprintf(buf, bufsize, "%s/postgresql", tmppath);
    7746             :     return true;
    7747             : #endif
    7748             : }
    7749             : 
    7750             : /*
    7751             :  * Parse and try to interpret "value" as an integer value, and if successful,
    7752             :  * store it in *result, complaining if there is any trailing garbage or an
    7753             :  * overflow.  This allows any number of leading and trailing whitespaces.
    7754             :  */
    7755             : bool
    7756       26528 : pqParseIntParam(const char *value, int *result, PGconn *conn,
    7757             :                 const char *context)
    7758             : {
    7759             :     char       *end;
    7760             :     long        numval;
    7761             : 
    7762             :     Assert(value != NULL);
    7763             : 
    7764       26528 :     *result = 0;
    7765             : 
    7766             :     /* strtol(3) skips leading whitespaces */
    7767       26528 :     errno = 0;
    7768       26528 :     numval = strtol(value, &end, 10);
    7769             : 
    7770             :     /*
    7771             :      * If no progress was done during the parsing or an error happened, fail.
    7772             :      * This tests properly for overflows of the result.
    7773             :      */
    7774       26528 :     if (value == end || errno != 0 || numval != (int) numval)
    7775           0 :         goto error;
    7776             : 
    7777             :     /*
    7778             :      * Skip any trailing whitespace; if anything but whitespace remains before
    7779             :      * the terminating character, fail
    7780             :      */
    7781       26528 :     while (*end != '\0' && isspace((unsigned char) *end))
    7782           0 :         end++;
    7783             : 
    7784       26528 :     if (*end != '\0')
    7785           0 :         goto error;
    7786             : 
    7787       26528 :     *result = numval;
    7788       26528 :     return true;
    7789             : 
    7790           0 : error:
    7791           0 :     libpq_append_conn_error(conn, "invalid integer value \"%s\" for connection option \"%s\"",
    7792             :                             value, context);
    7793           0 :     return false;
    7794             : }
    7795             : 
    7796             : /*
    7797             :  * To keep the API consistent, the locking stubs are always provided, even
    7798             :  * if they are not required.
    7799             :  *
    7800             :  * Since we neglected to provide any error-return convention in the
    7801             :  * pgthreadlock_t API, we can't do much except Assert upon failure of any
    7802             :  * mutex primitive.  Fortunately, such failures appear to be nonexistent in
    7803             :  * the field.
    7804             :  */
    7805             : 
    7806             : static void
    7807           0 : default_threadlock(int acquire)
    7808             : {
    7809             :     static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
    7810             : 
    7811           0 :     if (acquire)
    7812             :     {
    7813           0 :         if (pthread_mutex_lock(&singlethread_lock))
    7814             :             Assert(false);
    7815             :     }
    7816             :     else
    7817             :     {
    7818           0 :         if (pthread_mutex_unlock(&singlethread_lock))
    7819             :             Assert(false);
    7820             :     }
    7821           0 : }
    7822             : 
    7823             : pgthreadlock_t
    7824           0 : PQregisterThreadLock(pgthreadlock_t newhandler)
    7825             : {
    7826           0 :     pgthreadlock_t prev = pg_g_threadlock;
    7827             : 
    7828           0 :     if (newhandler)
    7829           0 :         pg_g_threadlock = newhandler;
    7830             :     else
    7831           0 :         pg_g_threadlock = default_threadlock;
    7832             : 
    7833           0 :     return prev;
    7834             : }

Generated by: LCOV version 1.14