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 : }
|