| 1 | /*------------------------------------------------------------------------- |
| 2 | * |
| 3 | * libpq-int.h |
| 4 | * This file contains internal definitions meant to be used only by |
| 5 | * the frontend libpq library, not by applications that call it. |
| 6 | * |
| 7 | * An application can include this file if it wants to bypass the |
| 8 | * official API defined by libpq-fe.h, but code that does so is much |
| 9 | * more likely to break across PostgreSQL releases than code that uses |
| 10 | * only the official API. |
| 11 | * |
| 12 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
| 13 | * Portions Copyright (c) 1994, Regents of the University of California |
| 14 | * |
| 15 | * src/interfaces/libpq/libpq-int.h |
| 16 | * |
| 17 | *------------------------------------------------------------------------- |
| 18 | */ |
| 19 | |
| 20 | #ifndef LIBPQ_INT_H |
| 21 | #define LIBPQ_INT_H |
| 22 | |
| 23 | /* We assume libpq-fe.h has already been included. */ |
| 24 | #include "libpq-events.h" |
| 25 | |
| 26 | #include <time.h> |
| 27 | #ifndef WIN32 |
| 28 | #include <sys/time.h> |
| 29 | #endif |
| 30 | |
| 31 | #ifdef ENABLE_THREAD_SAFETY |
| 32 | #ifdef WIN32 |
| 33 | #include "pthread-win32.h" |
| 34 | #else |
| 35 | #include <pthread.h> |
| 36 | #endif |
| 37 | #include <signal.h> |
| 38 | #endif |
| 39 | |
| 40 | /* include stuff common to fe and be */ |
| 41 | #include "getaddrinfo.h" |
| 42 | #include "libpq/pqcomm.h" |
| 43 | /* include stuff found in fe only */ |
| 44 | #include "pqexpbuffer.h" |
| 45 | |
| 46 | #ifdef ENABLE_GSS |
| 47 | #if defined(HAVE_GSSAPI_H) |
| 48 | #include <gssapi.h> |
| 49 | #else |
| 50 | #include <gssapi/gssapi.h> |
| 51 | #endif |
| 52 | #endif |
| 53 | |
| 54 | #ifdef ENABLE_SSPI |
| 55 | #define SECURITY_WIN32 |
| 56 | #if defined(WIN32) && !defined(_MSC_VER) |
| 57 | #include <ntsecapi.h> |
| 58 | #endif |
| 59 | #include <security.h> |
| 60 | #undef SECURITY_WIN32 |
| 61 | |
| 62 | #ifndef ENABLE_GSS |
| 63 | /* |
| 64 | * Define a fake structure compatible with GSSAPI on Unix. |
| 65 | */ |
| 66 | typedef struct |
| 67 | { |
| 68 | void *value; |
| 69 | int length; |
| 70 | } gss_buffer_desc; |
| 71 | #endif |
| 72 | #endif /* ENABLE_SSPI */ |
| 73 | |
| 74 | #ifdef USE_OPENSSL |
| 75 | #include <openssl/ssl.h> |
| 76 | #include <openssl/err.h> |
| 77 | |
| 78 | #ifndef OPENSSL_NO_ENGINE |
| 79 | #define USE_SSL_ENGINE |
| 80 | #endif |
| 81 | #endif /* USE_OPENSSL */ |
| 82 | |
| 83 | /* |
| 84 | * POSTGRES backend dependent Constants. |
| 85 | */ |
| 86 | #define CMDSTATUS_LEN 64 /* should match COMPLETION_TAG_BUFSIZE */ |
| 87 | |
| 88 | /* |
| 89 | * PGresult and the subsidiary types PGresAttDesc, PGresAttValue |
| 90 | * represent the result of a query (or more precisely, of a single SQL |
| 91 | * command --- a query string given to PQexec can contain multiple commands). |
| 92 | * Note we assume that a single command can return at most one tuple group, |
| 93 | * hence there is no need for multiple descriptor sets. |
| 94 | */ |
| 95 | |
| 96 | /* Subsidiary-storage management structure for PGresult. |
| 97 | * See space management routines in fe-exec.c for details. |
| 98 | * Note that space[k] refers to the k'th byte starting from the physical |
| 99 | * head of the block --- it's a union, not a struct! |
| 100 | */ |
| 101 | typedef union pgresult_data PGresult_data; |
| 102 | |
| 103 | union pgresult_data |
| 104 | { |
| 105 | PGresult_data *next; /* link to next block, or NULL */ |
| 106 | char space[1]; /* dummy for accessing block as bytes */ |
| 107 | }; |
| 108 | |
| 109 | /* Data about a single parameter of a prepared statement */ |
| 110 | typedef struct pgresParamDesc |
| 111 | { |
| 112 | Oid typid; /* type id */ |
| 113 | } PGresParamDesc; |
| 114 | |
| 115 | /* |
| 116 | * Data for a single attribute of a single tuple |
| 117 | * |
| 118 | * We use char* for Attribute values. |
| 119 | * |
| 120 | * The value pointer always points to a null-terminated area; we add a |
| 121 | * null (zero) byte after whatever the backend sends us. This is only |
| 122 | * particularly useful for text values ... with a binary value, the |
| 123 | * value might have embedded nulls, so the application can't use C string |
| 124 | * operators on it. But we add a null anyway for consistency. |
| 125 | * Note that the value itself does not contain a length word. |
| 126 | * |
| 127 | * A NULL attribute is a special case in two ways: its len field is NULL_LEN |
| 128 | * and its value field points to null_field in the owning PGresult. All the |
| 129 | * NULL attributes in a query result point to the same place (there's no need |
| 130 | * to store a null string separately for each one). |
| 131 | */ |
| 132 | |
| 133 | #define NULL_LEN (-1) /* pg_result len for NULL value */ |
| 134 | |
| 135 | typedef struct pgresAttValue |
| 136 | { |
| 137 | int len; /* length in bytes of the value */ |
| 138 | char *value; /* actual value, plus terminating zero byte */ |
| 139 | } PGresAttValue; |
| 140 | |
| 141 | /* Typedef for message-field list entries */ |
| 142 | typedef struct pgMessageField |
| 143 | { |
| 144 | struct pgMessageField *next; /* list link */ |
| 145 | char code; /* field code */ |
| 146 | char contents[FLEXIBLE_ARRAY_MEMBER]; /* value, nul-terminated */ |
| 147 | } PGMessageField; |
| 148 | |
| 149 | /* Fields needed for notice handling */ |
| 150 | typedef struct |
| 151 | { |
| 152 | PQnoticeReceiver noticeRec; /* notice message receiver */ |
| 153 | void *noticeRecArg; |
| 154 | PQnoticeProcessor noticeProc; /* notice message processor */ |
| 155 | void *noticeProcArg; |
| 156 | } PGNoticeHooks; |
| 157 | |
| 158 | typedef struct PGEvent |
| 159 | { |
| 160 | PGEventProc proc; /* the function to call on events */ |
| 161 | char *name; /* used only for error messages */ |
| 162 | void *passThrough; /* pointer supplied at registration time */ |
| 163 | void *data; /* optional state (instance) data */ |
| 164 | bool resultInitialized; /* T if RESULTCREATE/COPY succeeded */ |
| 165 | } PGEvent; |
| 166 | |
| 167 | struct pg_result |
| 168 | { |
| 169 | int ntups; |
| 170 | int numAttributes; |
| 171 | PGresAttDesc *attDescs; |
| 172 | PGresAttValue **tuples; /* each PGresTuple is an array of |
| 173 | * PGresAttValue's */ |
| 174 | int tupArrSize; /* allocated size of tuples array */ |
| 175 | int numParameters; |
| 176 | PGresParamDesc *paramDescs; |
| 177 | ExecStatusType resultStatus; |
| 178 | char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the query */ |
| 179 | int binary; /* binary tuple values if binary == 1, |
| 180 | * otherwise text */ |
| 181 | |
| 182 | /* |
| 183 | * These fields are copied from the originating PGconn, so that operations |
| 184 | * on the PGresult don't have to reference the PGconn. |
| 185 | */ |
| 186 | PGNoticeHooks noticeHooks; |
| 187 | PGEvent *events; |
| 188 | int nEvents; |
| 189 | int client_encoding; /* encoding id */ |
| 190 | |
| 191 | /* |
| 192 | * Error information (all NULL if not an error result). errMsg is the |
| 193 | * "overall" error message returned by PQresultErrorMessage. If we have |
| 194 | * per-field info then it is stored in a linked list. |
| 195 | */ |
| 196 | char *errMsg; /* error message, or NULL if no error */ |
| 197 | PGMessageField *errFields; /* message broken into fields */ |
| 198 | char *errQuery; /* text of triggering query, if available */ |
| 199 | |
| 200 | /* All NULL attributes in the query result point to this null string */ |
| 201 | char null_field[1]; |
| 202 | |
| 203 | /* |
| 204 | * Space management information. Note that attDescs and error stuff, if |
| 205 | * not null, point into allocated blocks. But tuples points to a |
| 206 | * separately malloc'd block, so that we can realloc it. |
| 207 | */ |
| 208 | PGresult_data *curBlock; /* most recently allocated block */ |
| 209 | int curOffset; /* start offset of free space in block */ |
| 210 | int spaceLeft; /* number of free bytes remaining in block */ |
| 211 | |
| 212 | size_t memorySize; /* total space allocated for this PGresult */ |
| 213 | }; |
| 214 | |
| 215 | /* PGAsyncStatusType defines the state of the query-execution state machine */ |
| 216 | typedef enum |
| 217 | { |
| 218 | PGASYNC_IDLE, /* nothing's happening, dude */ |
| 219 | PGASYNC_BUSY, /* query in progress */ |
| 220 | PGASYNC_READY, /* result ready for PQgetResult */ |
| 221 | PGASYNC_COPY_IN, /* Copy In data transfer in progress */ |
| 222 | PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */ |
| 223 | PGASYNC_COPY_BOTH /* Copy In/Out data transfer in progress */ |
| 224 | } PGAsyncStatusType; |
| 225 | |
| 226 | /* PGQueryClass tracks which query protocol we are now executing */ |
| 227 | typedef enum |
| 228 | { |
| 229 | PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */ |
| 230 | PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */ |
| 231 | PGQUERY_PREPARE, /* Parse only (PQprepare) */ |
| 232 | PGQUERY_DESCRIBE /* Describe Statement or Portal */ |
| 233 | } PGQueryClass; |
| 234 | |
| 235 | /* PGSetenvStatusType defines the state of the PQSetenv state machine */ |
| 236 | /* (this is used only for 2.0-protocol connections) */ |
| 237 | typedef enum |
| 238 | { |
| 239 | SETENV_STATE_CLIENT_ENCODING_SEND, /* About to send an Environment Option */ |
| 240 | SETENV_STATE_CLIENT_ENCODING_WAIT, /* Waiting for above send to complete */ |
| 241 | SETENV_STATE_OPTION_SEND, /* About to send an Environment Option */ |
| 242 | SETENV_STATE_OPTION_WAIT, /* Waiting for above send to complete */ |
| 243 | SETENV_STATE_QUERY1_SEND, /* About to send a status query */ |
| 244 | SETENV_STATE_QUERY1_WAIT, /* Waiting for query to complete */ |
| 245 | SETENV_STATE_QUERY2_SEND, /* About to send a status query */ |
| 246 | SETENV_STATE_QUERY2_WAIT, /* Waiting for query to complete */ |
| 247 | SETENV_STATE_IDLE |
| 248 | } PGSetenvStatusType; |
| 249 | |
| 250 | /* Typedef for the EnvironmentOptions[] array */ |
| 251 | typedef struct PQEnvironmentOption |
| 252 | { |
| 253 | const char *envName, /* name of an environment variable */ |
| 254 | *pgName; /* name of corresponding SET variable */ |
| 255 | } PQEnvironmentOption; |
| 256 | |
| 257 | /* Typedef for parameter-status list entries */ |
| 258 | typedef struct pgParameterStatus |
| 259 | { |
| 260 | struct pgParameterStatus *next; /* list link */ |
| 261 | char *name; /* parameter name */ |
| 262 | char *value; /* parameter value */ |
| 263 | /* Note: name and value are stored in same malloc block as struct is */ |
| 264 | } pgParameterStatus; |
| 265 | |
| 266 | /* large-object-access data ... allocated only if large-object code is used. */ |
| 267 | typedef struct pgLobjfuncs |
| 268 | { |
| 269 | Oid fn_lo_open; /* OID of backend function lo_open */ |
| 270 | Oid fn_lo_close; /* OID of backend function lo_close */ |
| 271 | Oid fn_lo_creat; /* OID of backend function lo_creat */ |
| 272 | Oid fn_lo_create; /* OID of backend function lo_create */ |
| 273 | Oid fn_lo_unlink; /* OID of backend function lo_unlink */ |
| 274 | Oid fn_lo_lseek; /* OID of backend function lo_lseek */ |
| 275 | Oid fn_lo_lseek64; /* OID of backend function lo_lseek64 */ |
| 276 | Oid fn_lo_tell; /* OID of backend function lo_tell */ |
| 277 | Oid fn_lo_tell64; /* OID of backend function lo_tell64 */ |
| 278 | Oid fn_lo_truncate; /* OID of backend function lo_truncate */ |
| 279 | Oid fn_lo_truncate64; /* OID of function lo_truncate64 */ |
| 280 | Oid fn_lo_read; /* OID of backend function LOread */ |
| 281 | Oid fn_lo_write; /* OID of backend function LOwrite */ |
| 282 | } PGlobjfuncs; |
| 283 | |
| 284 | /* PGdataValue represents a data field value being passed to a row processor. |
| 285 | * It could be either text or binary data; text data is not zero-terminated. |
| 286 | * A SQL NULL is represented by len < 0; then value is still valid but there |
| 287 | * are no data bytes there. |
| 288 | */ |
| 289 | typedef struct pgDataValue |
| 290 | { |
| 291 | int len; /* data length in bytes, or <0 if NULL */ |
| 292 | const char *value; /* data value, without zero-termination */ |
| 293 | } PGdataValue; |
| 294 | |
| 295 | /* Host address type enum for struct pg_conn_host */ |
| 296 | typedef enum pg_conn_host_type |
| 297 | { |
| 298 | CHT_HOST_NAME, |
| 299 | CHT_HOST_ADDRESS, |
| 300 | CHT_UNIX_SOCKET |
| 301 | } pg_conn_host_type; |
| 302 | |
| 303 | /* |
| 304 | * pg_conn_host stores all information about each of possibly several hosts |
| 305 | * mentioned in the connection string. Most fields are derived by splitting |
| 306 | * the relevant connection parameter (e.g., pghost) at commas. |
| 307 | */ |
| 308 | typedef struct pg_conn_host |
| 309 | { |
| 310 | pg_conn_host_type type; /* type of host address */ |
| 311 | char *host; /* host name or socket path */ |
| 312 | char *hostaddr; /* host numeric IP address */ |
| 313 | char *port; /* port number (always provided) */ |
| 314 | char *password; /* password for this host, read from the |
| 315 | * password file; NULL if not sought or not |
| 316 | * found in password file. */ |
| 317 | } pg_conn_host; |
| 318 | |
| 319 | /* |
| 320 | * PGconn stores all the state data associated with a single connection |
| 321 | * to a backend. |
| 322 | */ |
| 323 | struct pg_conn |
| 324 | { |
| 325 | /* Saved values of connection options */ |
| 326 | char *pghost; /* the machine on which the server is running, |
| 327 | * or a path to a UNIX-domain socket, or a |
| 328 | * comma-separated list of machines and/or |
| 329 | * paths; if NULL, use DEFAULT_PGSOCKET_DIR */ |
| 330 | char *pghostaddr; /* the numeric IP address of the machine on |
| 331 | * which the server is running, or a |
| 332 | * comma-separated list of same. Takes |
| 333 | * precedence over pghost. */ |
| 334 | char *pgport; /* the server's communication port number, or |
| 335 | * a comma-separated list of ports */ |
| 336 | char *pgtty; /* tty on which the backend messages is |
| 337 | * displayed (OBSOLETE, NOT USED) */ |
| 338 | char *connect_timeout; /* connection timeout (numeric string) */ |
| 339 | char *pgtcp_user_timeout; /* tcp user timeout (numeric string) */ |
| 340 | char *client_encoding_initial; /* encoding to use */ |
| 341 | char *pgoptions; /* options to start the backend with */ |
| 342 | char *appname; /* application name */ |
| 343 | char *fbappname; /* fallback application name */ |
| 344 | char *dbName; /* database name */ |
| 345 | char *replication; /* connect as the replication standby? */ |
| 346 | char *pguser; /* Postgres username and password, if any */ |
| 347 | char *pgpass; |
| 348 | char *pgpassfile; /* path to a file containing password(s) */ |
| 349 | char *keepalives; /* use TCP keepalives? */ |
| 350 | char *keepalives_idle; /* time between TCP keepalives */ |
| 351 | char *keepalives_interval; /* time between TCP keepalive |
| 352 | * retransmits */ |
| 353 | char *keepalives_count; /* maximum number of TCP keepalive |
| 354 | * retransmits */ |
| 355 | char *sslmode; /* SSL mode (require,prefer,allow,disable) */ |
| 356 | char *sslcompression; /* SSL compression (0 or 1) */ |
| 357 | char *sslkey; /* client key filename */ |
| 358 | char *sslcert; /* client certificate filename */ |
| 359 | char *sslrootcert; /* root certificate filename */ |
| 360 | char *sslcrl; /* certificate revocation list filename */ |
| 361 | char *requirepeer; /* required peer credentials for local sockets */ |
| 362 | |
| 363 | #if defined(ENABLE_GSS) || defined(ENABLE_SSPI) |
| 364 | char *krbsrvname; /* Kerberos service name */ |
| 365 | #endif |
| 366 | |
| 367 | /* Type of connection to make. Possible values: any, read-write. */ |
| 368 | char *target_session_attrs; |
| 369 | |
| 370 | /* Optional file to write trace info to */ |
| 371 | FILE *Pfdebug; |
| 372 | |
| 373 | /* Callback procedures for notice message processing */ |
| 374 | PGNoticeHooks noticeHooks; |
| 375 | |
| 376 | /* Event procs registered via PQregisterEventProc */ |
| 377 | PGEvent *events; /* expandable array of event data */ |
| 378 | int nEvents; /* number of active events */ |
| 379 | int eventArraySize; /* allocated array size */ |
| 380 | |
| 381 | /* Status indicators */ |
| 382 | ConnStatusType status; |
| 383 | PGAsyncStatusType asyncStatus; |
| 384 | PGTransactionStatusType xactStatus; /* never changes to ACTIVE */ |
| 385 | PGQueryClass queryclass; |
| 386 | char *last_query; /* last SQL command, or NULL if unknown */ |
| 387 | char last_sqlstate[6]; /* last reported SQLSTATE */ |
| 388 | bool options_valid; /* true if OK to attempt connection */ |
| 389 | bool nonblocking; /* whether this connection is using nonblock |
| 390 | * sending semantics */ |
| 391 | bool singleRowMode; /* return current query result row-by-row? */ |
| 392 | char copy_is_binary; /* 1 = copy binary, 0 = copy text */ |
| 393 | int copy_already_done; /* # bytes already returned in COPY OUT */ |
| 394 | PGnotify *notifyHead; /* oldest unreported Notify msg */ |
| 395 | PGnotify *notifyTail; /* newest unreported Notify msg */ |
| 396 | |
| 397 | /* Support for multiple hosts in connection string */ |
| 398 | int nconnhost; /* # of hosts named in conn string */ |
| 399 | int whichhost; /* host we're currently trying/connected to */ |
| 400 | pg_conn_host *connhost; /* details about each named host */ |
| 401 | char *connip; /* IP address for current network connection */ |
| 402 | |
| 403 | /* Connection data */ |
| 404 | pgsocket sock; /* FD for socket, PGINVALID_SOCKET if |
| 405 | * unconnected */ |
| 406 | SockAddr laddr; /* Local address */ |
| 407 | SockAddr raddr; /* Remote address */ |
| 408 | ProtocolVersion pversion; /* FE/BE protocol version in use */ |
| 409 | int sversion; /* server version, e.g. 70401 for 7.4.1 */ |
| 410 | bool auth_req_received; /* true if any type of auth req received */ |
| 411 | bool password_needed; /* true if server demanded a password */ |
| 412 | bool sigpipe_so; /* have we masked SIGPIPE via SO_NOSIGPIPE? */ |
| 413 | bool sigpipe_flag; /* can we mask SIGPIPE via MSG_NOSIGNAL? */ |
| 414 | bool write_failed; /* have we had a write failure on sock? */ |
| 415 | char *write_err_msg; /* write error message, or NULL if OOM */ |
| 416 | |
| 417 | /* Transient state needed while establishing connection */ |
| 418 | bool try_next_addr; /* time to advance to next address/host? */ |
| 419 | bool try_next_host; /* time to advance to next connhost[]? */ |
| 420 | struct addrinfo *addrlist; /* list of addresses for current connhost */ |
| 421 | struct addrinfo *addr_cur; /* the one currently being tried */ |
| 422 | int addrlist_family; /* needed to know how to free addrlist */ |
| 423 | PGSetenvStatusType setenv_state; /* for 2.0 protocol only */ |
| 424 | const PQEnvironmentOption *next_eo; |
| 425 | bool send_appname; /* okay to send application_name? */ |
| 426 | |
| 427 | /* Miscellaneous stuff */ |
| 428 | int be_pid; /* PID of backend --- needed for cancels */ |
| 429 | int be_key; /* key of backend --- needed for cancels */ |
| 430 | pgParameterStatus *pstatus; /* ParameterStatus data */ |
| 431 | int client_encoding; /* encoding id */ |
| 432 | bool std_strings; /* standard_conforming_strings */ |
| 433 | PGVerbosity verbosity; /* error/notice message verbosity */ |
| 434 | PGContextVisibility show_context; /* whether to show CONTEXT field */ |
| 435 | PGlobjfuncs *lobjfuncs; /* private state for large-object access fns */ |
| 436 | |
| 437 | /* Buffer for data received from backend and not yet processed */ |
| 438 | char *inBuffer; /* currently allocated buffer */ |
| 439 | int inBufSize; /* allocated size of buffer */ |
| 440 | int inStart; /* offset to first unconsumed data in buffer */ |
| 441 | int inCursor; /* next byte to tentatively consume */ |
| 442 | int inEnd; /* offset to first position after avail data */ |
| 443 | |
| 444 | /* Buffer for data not yet sent to backend */ |
| 445 | char *outBuffer; /* currently allocated buffer */ |
| 446 | int outBufSize; /* allocated size of buffer */ |
| 447 | int outCount; /* number of chars waiting in buffer */ |
| 448 | |
| 449 | /* State for constructing messages in outBuffer */ |
| 450 | int outMsgStart; /* offset to msg start (length word); if -1, |
| 451 | * msg has no length word */ |
| 452 | int outMsgEnd; /* offset to msg end (so far) */ |
| 453 | |
| 454 | /* Row processor interface workspace */ |
| 455 | PGdataValue *rowBuf; /* array for passing values to rowProcessor */ |
| 456 | int rowBufLen; /* number of entries allocated in rowBuf */ |
| 457 | |
| 458 | /* Status for asynchronous result construction */ |
| 459 | PGresult *result; /* result being constructed */ |
| 460 | PGresult *next_result; /* next result (used in single-row mode) */ |
| 461 | |
| 462 | /* Assorted state for SASL, SSL, GSS, etc */ |
| 463 | void *sasl_state; |
| 464 | |
| 465 | /* SSL structures */ |
| 466 | bool ssl_in_use; |
| 467 | |
| 468 | #ifdef USE_SSL |
| 469 | bool allow_ssl_try; /* Allowed to try SSL negotiation */ |
| 470 | bool wait_ssl_try; /* Delay SSL negotiation until after |
| 471 | * attempting normal connection */ |
| 472 | #ifdef USE_OPENSSL |
| 473 | SSL *ssl; /* SSL status, if have SSL connection */ |
| 474 | X509 *peer; /* X509 cert of server */ |
| 475 | #ifdef USE_SSL_ENGINE |
| 476 | ENGINE *engine; /* SSL engine, if any */ |
| 477 | #else |
| 478 | void *engine; /* dummy field to keep struct the same if |
| 479 | * OpenSSL version changes */ |
| 480 | #endif |
| 481 | #endif /* USE_OPENSSL */ |
| 482 | #endif /* USE_SSL */ |
| 483 | |
| 484 | char *gssencmode; /* GSS mode (require,prefer,disable) */ |
| 485 | #ifdef ENABLE_GSS |
| 486 | gss_ctx_id_t gctx; /* GSS context */ |
| 487 | gss_name_t gtarg_nam; /* GSS target name */ |
| 488 | |
| 489 | /* The following are encryption-only */ |
| 490 | bool try_gss; /* GSS attempting permitted */ |
| 491 | bool gssenc; /* GSS encryption is usable */ |
| 492 | gss_cred_id_t gcred; /* GSS credential temp storage. */ |
| 493 | #endif |
| 494 | |
| 495 | #ifdef ENABLE_SSPI |
| 496 | #ifdef ENABLE_GSS |
| 497 | char *gsslib; /* What GSS library to use ("gssapi" or |
| 498 | * "sspi") */ |
| 499 | #endif |
| 500 | CredHandle *sspicred; /* SSPI credentials handle */ |
| 501 | CtxtHandle *sspictx; /* SSPI context */ |
| 502 | char *sspitarget; /* SSPI target name */ |
| 503 | int usesspi; /* Indicate if SSPI is in use on the |
| 504 | * connection */ |
| 505 | #endif |
| 506 | |
| 507 | /* Buffer for current error message */ |
| 508 | PQExpBufferData errorMessage; /* expansible string */ |
| 509 | |
| 510 | /* Buffer for receiving various parts of messages */ |
| 511 | PQExpBufferData workBuffer; /* expansible string */ |
| 512 | }; |
| 513 | |
| 514 | /* PGcancel stores all data necessary to cancel a connection. A copy of this |
| 515 | * data is required to safely cancel a connection running on a different |
| 516 | * thread. |
| 517 | */ |
| 518 | struct pg_cancel |
| 519 | { |
| 520 | SockAddr raddr; /* Remote address */ |
| 521 | int be_pid; /* PID of backend --- needed for cancels */ |
| 522 | int be_key; /* key of backend --- needed for cancels */ |
| 523 | }; |
| 524 | |
| 525 | |
| 526 | /* String descriptions of the ExecStatusTypes. |
| 527 | * direct use of this array is deprecated; call PQresStatus() instead. |
| 528 | */ |
| 529 | extern char *const pgresStatus[]; |
| 530 | |
| 531 | |
| 532 | #ifdef USE_SSL |
| 533 | |
| 534 | #ifndef WIN32 |
| 535 | #define USER_CERT_FILE ".postgresql/postgresql.crt" |
| 536 | #define USER_KEY_FILE ".postgresql/postgresql.key" |
| 537 | #define ROOT_CERT_FILE ".postgresql/root.crt" |
| 538 | #define ROOT_CRL_FILE ".postgresql/root.crl" |
| 539 | #else |
| 540 | /* On Windows, the "home" directory is already PostgreSQL-specific */ |
| 541 | #define USER_CERT_FILE "postgresql.crt" |
| 542 | #define USER_KEY_FILE "postgresql.key" |
| 543 | #define ROOT_CERT_FILE "root.crt" |
| 544 | #define ROOT_CRL_FILE "root.crl" |
| 545 | #endif |
| 546 | |
| 547 | #endif /* USE_SSL */ |
| 548 | |
| 549 | /* ---------------- |
| 550 | * Internal functions of libpq |
| 551 | * Functions declared here need to be visible across files of libpq, |
| 552 | * but are not intended to be called by applications. We use the |
| 553 | * convention "pqXXX" for internal functions, vs. the "PQxxx" names |
| 554 | * used for application-visible routines. |
| 555 | * ---------------- |
| 556 | */ |
| 557 | |
| 558 | /* === in fe-connect.c === */ |
| 559 | |
| 560 | extern void pqDropConnection(PGconn *conn, bool flushInput); |
| 561 | extern int pqPacketSend(PGconn *conn, char pack_type, |
| 562 | const void *buf, size_t buf_len); |
| 563 | extern bool pqGetHomeDirectory(char *buf, int bufsize); |
| 564 | |
| 565 | #ifdef ENABLE_THREAD_SAFETY |
| 566 | extern pgthreadlock_t pg_g_threadlock; |
| 567 | |
| 568 | #define PGTHREAD_ERROR(msg) \ |
| 569 | do { \ |
| 570 | fprintf(stderr, "%s\n", msg); \ |
| 571 | abort(); \ |
| 572 | } while (0) |
| 573 | |
| 574 | |
| 575 | #define pglock_thread() pg_g_threadlock(true) |
| 576 | #define pgunlock_thread() pg_g_threadlock(false) |
| 577 | #else |
| 578 | #define pglock_thread() ((void) 0) |
| 579 | #define pgunlock_thread() ((void) 0) |
| 580 | #endif |
| 581 | |
| 582 | /* === in fe-exec.c === */ |
| 583 | |
| 584 | extern void pqSetResultError(PGresult *res, const char *msg); |
| 585 | extern void pqCatenateResultError(PGresult *res, const char *msg); |
| 586 | extern void *pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary); |
| 587 | extern char *pqResultStrdup(PGresult *res, const char *str); |
| 588 | extern void pqClearAsyncResult(PGconn *conn); |
| 589 | extern void pqSaveErrorResult(PGconn *conn); |
| 590 | extern PGresult *pqPrepareAsyncResult(PGconn *conn); |
| 591 | extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2, 3); |
| 592 | extern void pqSaveMessageField(PGresult *res, char code, |
| 593 | const char *value); |
| 594 | extern void pqSaveParameterStatus(PGconn *conn, const char *name, |
| 595 | const char *value); |
| 596 | extern int pqRowProcessor(PGconn *conn, const char **errmsgp); |
| 597 | |
| 598 | /* === in fe-protocol2.c === */ |
| 599 | |
| 600 | extern PostgresPollingStatusType pqSetenvPoll(PGconn *conn); |
| 601 | |
| 602 | extern char *pqBuildStartupPacket2(PGconn *conn, int *packetlen, |
| 603 | const PQEnvironmentOption *options); |
| 604 | extern void pqParseInput2(PGconn *conn); |
| 605 | extern int pqGetCopyData2(PGconn *conn, char **buffer, int async); |
| 606 | extern int pqGetline2(PGconn *conn, char *s, int maxlen); |
| 607 | extern int pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize); |
| 608 | extern int pqEndcopy2(PGconn *conn); |
| 609 | extern PGresult *pqFunctionCall2(PGconn *conn, Oid fnid, |
| 610 | int *result_buf, int *actual_result_len, |
| 611 | int result_is_int, |
| 612 | const PQArgBlock *args, int nargs); |
| 613 | |
| 614 | /* === in fe-protocol3.c === */ |
| 615 | |
| 616 | extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen, |
| 617 | const PQEnvironmentOption *options); |
| 618 | extern void pqParseInput3(PGconn *conn); |
| 619 | extern int pqGetErrorNotice3(PGconn *conn, bool isError); |
| 620 | extern void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, |
| 621 | PGVerbosity verbosity, PGContextVisibility show_context); |
| 622 | extern int pqGetCopyData3(PGconn *conn, char **buffer, int async); |
| 623 | extern int pqGetline3(PGconn *conn, char *s, int maxlen); |
| 624 | extern int pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize); |
| 625 | extern int pqEndcopy3(PGconn *conn); |
| 626 | extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid, |
| 627 | int *result_buf, int *actual_result_len, |
| 628 | int result_is_int, |
| 629 | const PQArgBlock *args, int nargs); |
| 630 | |
| 631 | /* === in fe-misc.c === */ |
| 632 | |
| 633 | /* |
| 634 | * "Get" and "Put" routines return 0 if successful, EOF if not. Note that for |
| 635 | * Get, EOF merely means the buffer is exhausted, not that there is |
| 636 | * necessarily any error. |
| 637 | */ |
| 638 | extern int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn); |
| 639 | extern int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn); |
| 640 | extern int pqGetc(char *result, PGconn *conn); |
| 641 | extern int pqPutc(char c, PGconn *conn); |
| 642 | extern int pqGets(PQExpBuffer buf, PGconn *conn); |
| 643 | extern int pqGets_append(PQExpBuffer buf, PGconn *conn); |
| 644 | extern int pqPuts(const char *s, PGconn *conn); |
| 645 | extern int pqGetnchar(char *s, size_t len, PGconn *conn); |
| 646 | extern int pqSkipnchar(size_t len, PGconn *conn); |
| 647 | extern int pqPutnchar(const char *s, size_t len, PGconn *conn); |
| 648 | extern int pqGetInt(int *result, size_t bytes, PGconn *conn); |
| 649 | extern int pqPutInt(int value, size_t bytes, PGconn *conn); |
| 650 | extern int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn); |
| 651 | extern int pqPutMsgEnd(PGconn *conn); |
| 652 | extern int pqReadData(PGconn *conn); |
| 653 | extern int pqFlush(PGconn *conn); |
| 654 | extern int pqWait(int forRead, int forWrite, PGconn *conn); |
| 655 | extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn, |
| 656 | time_t finish_time); |
| 657 | extern int pqReadReady(PGconn *conn); |
| 658 | extern int pqWriteReady(PGconn *conn); |
| 659 | |
| 660 | /* === in fe-secure.c === */ |
| 661 | |
| 662 | extern int pqsecure_initialize(PGconn *); |
| 663 | extern void pqsecure_destroy(void); |
| 664 | extern PostgresPollingStatusType pqsecure_open_client(PGconn *); |
| 665 | extern void pqsecure_close(PGconn *); |
| 666 | extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); |
| 667 | extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len); |
| 668 | extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len); |
| 669 | extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len); |
| 670 | |
| 671 | #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) |
| 672 | extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending); |
| 673 | extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, |
| 674 | bool got_epipe); |
| 675 | #endif |
| 676 | |
| 677 | /* === SSL === */ |
| 678 | |
| 679 | /* |
| 680 | * The SSL implementation provides these functions. |
| 681 | */ |
| 682 | |
| 683 | /* |
| 684 | * Implementation of PQinitSSL(). |
| 685 | */ |
| 686 | extern void pgtls_init_library(bool do_ssl, int do_crypto); |
| 687 | |
| 688 | /* |
| 689 | * Initialize SSL library. |
| 690 | * |
| 691 | * The conn parameter is only used to be able to pass back an error |
| 692 | * message - no connection-local setup is made here. |
| 693 | * |
| 694 | * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage). |
| 695 | */ |
| 696 | extern int pgtls_init(PGconn *conn); |
| 697 | |
| 698 | /* |
| 699 | * Begin or continue negotiating a secure session. |
| 700 | */ |
| 701 | extern PostgresPollingStatusType pgtls_open_client(PGconn *conn); |
| 702 | |
| 703 | /* |
| 704 | * Close SSL connection. |
| 705 | */ |
| 706 | extern void pgtls_close(PGconn *conn); |
| 707 | |
| 708 | /* |
| 709 | * Read data from a secure connection. |
| 710 | * |
| 711 | * On failure, this function is responsible for putting a suitable message |
| 712 | * into conn->errorMessage. The caller must still inspect errno, but only |
| 713 | * to determine whether to continue/retry after error. |
| 714 | */ |
| 715 | extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len); |
| 716 | |
| 717 | /* |
| 718 | * Is there unread data waiting in the SSL read buffer? |
| 719 | */ |
| 720 | extern bool pgtls_read_pending(PGconn *conn); |
| 721 | |
| 722 | /* |
| 723 | * Write data to a secure connection. |
| 724 | * |
| 725 | * On failure, this function is responsible for putting a suitable message |
| 726 | * into conn->errorMessage. The caller must still inspect errno, but only |
| 727 | * to determine whether to continue/retry after error. |
| 728 | */ |
| 729 | extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len); |
| 730 | |
| 731 | /* |
| 732 | * Get the hash of the server certificate, for SCRAM channel binding type |
| 733 | * tls-server-end-point. |
| 734 | * |
| 735 | * NULL is sent back to the caller in the event of an error, with an |
| 736 | * error message for the caller to consume. |
| 737 | * |
| 738 | * This is not supported with old versions of OpenSSL that don't have |
| 739 | * the X509_get_signature_nid() function. |
| 740 | */ |
| 741 | #if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID) |
| 742 | #define HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH |
| 743 | extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len); |
| 744 | #endif |
| 745 | |
| 746 | /* |
| 747 | * Verify that the server certificate matches the host name we connected to. |
| 748 | * |
| 749 | * The certificate's Common Name and Subject Alternative Names are considered. |
| 750 | * |
| 751 | * Returns 1 if the name matches, and 0 if it does not. On error, returns |
| 752 | * -1, and sets the libpq error message. |
| 753 | * |
| 754 | */ |
| 755 | extern int pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, |
| 756 | int *names_examined, |
| 757 | char **first_name); |
| 758 | |
| 759 | /* === GSSAPI === */ |
| 760 | |
| 761 | #ifdef ENABLE_GSS |
| 762 | |
| 763 | /* |
| 764 | * Establish a GSSAPI-encrypted connection. |
| 765 | */ |
| 766 | extern PostgresPollingStatusType pqsecure_open_gss(PGconn *conn); |
| 767 | |
| 768 | /* |
| 769 | * Read and write functions for GSSAPI-encrypted connections, with internal |
| 770 | * buffering to handle nonblocking sockets. |
| 771 | */ |
| 772 | extern ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len); |
| 773 | extern ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len); |
| 774 | #endif |
| 775 | |
| 776 | /* === miscellaneous macros === */ |
| 777 | |
| 778 | /* |
| 779 | * this is so that we can check if a connection is non-blocking internally |
| 780 | * without the overhead of a function call |
| 781 | */ |
| 782 | #define pqIsnonblocking(conn) ((conn)->nonblocking) |
| 783 | |
| 784 | #ifdef ENABLE_NLS |
| 785 | extern char *libpq_gettext(const char *msgid) pg_attribute_format_arg(1); |
| 786 | extern char *libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n) pg_attribute_format_arg(1) pg_attribute_format_arg(2); |
| 787 | #else |
| 788 | #define libpq_gettext(x) (x) |
| 789 | #define libpq_ngettext(s, p, n) ((n) == 1 ? (s) : (p)) |
| 790 | #endif |
| 791 | |
| 792 | /* |
| 793 | * These macros are needed to let error-handling code be portable between |
| 794 | * Unix and Windows. (ugh) |
| 795 | */ |
| 796 | #ifdef WIN32 |
| 797 | #define SOCK_ERRNO (WSAGetLastError()) |
| 798 | #define SOCK_STRERROR winsock_strerror |
| 799 | #define SOCK_ERRNO_SET(e) WSASetLastError(e) |
| 800 | #else |
| 801 | #define SOCK_ERRNO errno |
| 802 | #define SOCK_STRERROR strerror_r |
| 803 | #define SOCK_ERRNO_SET(e) (errno = (e)) |
| 804 | #endif |
| 805 | |
| 806 | #endif /* LIBPQ_INT_H */ |
| 807 | |