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

Generated by: LCOV version 1.16