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