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-2020, 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 PGresult tuple 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 
237 /* (this is used only for 2.0-protocol connections) */
238 typedef enum
239 {
240 	SETENV_STATE_CLIENT_ENCODING_SEND,	/* About to send an Environment Option */
241 	SETENV_STATE_CLIENT_ENCODING_WAIT,	/* Waiting for above send to complete */
242 	SETENV_STATE_OPTION_SEND,	/* About to send an Environment Option */
243 	SETENV_STATE_OPTION_WAIT,	/* Waiting for above send to complete */
244 	SETENV_STATE_QUERY1_SEND,	/* About to send a status query */
245 	SETENV_STATE_QUERY1_WAIT,	/* Waiting for query to complete */
246 	SETENV_STATE_QUERY2_SEND,	/* About to send a status query */
247 	SETENV_STATE_QUERY2_WAIT,	/* Waiting for query to complete */
248 	SETENV_STATE_IDLE
249 } PGSetenvStatusType;
250 
251 /* Typedef for the EnvironmentOptions[] array */
252 typedef struct PQEnvironmentOption
253 {
254 	const char *envName,		/* name of an environment variable */
255 			   *pgName;			/* name of corresponding SET variable */
256 } PQEnvironmentOption;
257 
258 /* Typedef for parameter-status list entries */
259 typedef struct pgParameterStatus
260 {
261 	struct pgParameterStatus *next; /* list link */
262 	char	   *name;			/* parameter name */
263 	char	   *value;			/* parameter value */
264 	/* Note: name and value are stored in same malloc block as struct is */
265 } pgParameterStatus;
266 
267 /* large-object-access data ... allocated only if large-object code is used. */
268 typedef struct pgLobjfuncs
269 {
270 	Oid			fn_lo_open;		/* OID of backend function lo_open		*/
271 	Oid			fn_lo_close;	/* OID of backend function lo_close		*/
272 	Oid			fn_lo_creat;	/* OID of backend function lo_creat		*/
273 	Oid			fn_lo_create;	/* OID of backend function lo_create	*/
274 	Oid			fn_lo_unlink;	/* OID of backend function lo_unlink	*/
275 	Oid			fn_lo_lseek;	/* OID of backend function lo_lseek		*/
276 	Oid			fn_lo_lseek64;	/* OID of backend function lo_lseek64	*/
277 	Oid			fn_lo_tell;		/* OID of backend function lo_tell		*/
278 	Oid			fn_lo_tell64;	/* OID of backend function lo_tell64	*/
279 	Oid			fn_lo_truncate; /* OID of backend function lo_truncate	*/
280 	Oid			fn_lo_truncate64;	/* OID of function lo_truncate64 */
281 	Oid			fn_lo_read;		/* OID of backend function LOread		*/
282 	Oid			fn_lo_write;	/* OID of backend function LOwrite		*/
283 } PGlobjfuncs;
284 
285 /* PGdataValue represents a data field value being passed to a row processor.
286  * It could be either text or binary data; text data is not zero-terminated.
287  * A SQL NULL is represented by len < 0; then value is still valid but there
288  * are no data bytes there.
289  */
290 typedef struct pgDataValue
291 {
292 	int			len;			/* data length in bytes, or <0 if NULL */
293 	const char *value;			/* data value, without zero-termination */
294 } PGdataValue;
295 
296 /* Host address type enum for struct pg_conn_host */
297 typedef enum pg_conn_host_type
298 {
299 	CHT_HOST_NAME,
300 	CHT_HOST_ADDRESS,
301 	CHT_UNIX_SOCKET
302 } pg_conn_host_type;
303 
304 /*
305  * pg_conn_host stores all information about each of possibly several hosts
306  * mentioned in the connection string.  Most fields are derived by splitting
307  * the relevant connection parameter (e.g., pghost) at commas.
308  */
309 typedef struct pg_conn_host
310 {
311 	pg_conn_host_type type;		/* type of host address */
312 	char	   *host;			/* host name or socket path */
313 	char	   *hostaddr;		/* host numeric IP address */
314 	char	   *port;			/* port number (always provided) */
315 	char	   *password;		/* password for this host, read from the
316 								 * password file; NULL if not sought or not
317 								 * found in password file. */
318 } pg_conn_host;
319 
320 /*
321  * PGconn stores all the state data associated with a single connection
322  * to a backend.
323  */
324 struct pg_conn
325 {
326 	/* Saved values of connection options */
327 	char	   *pghost;			/* the machine on which the server is running,
328 								 * or a path to a UNIX-domain socket, or a
329 								 * comma-separated list of machines and/or
330 								 * paths; if NULL, use DEFAULT_PGSOCKET_DIR */
331 	char	   *pghostaddr;		/* the numeric IP address of the machine on
332 								 * which the server is running, or a
333 								 * comma-separated list of same.  Takes
334 								 * precedence over pghost. */
335 	char	   *pgport;			/* the server's communication port number, or
336 								 * a comma-separated list of ports */
337 	char	   *pgtty;			/* tty on which the backend messages is
338 								 * displayed (OBSOLETE, NOT USED) */
339 	char	   *connect_timeout;	/* connection timeout (numeric string) */
340 	char	   *pgtcp_user_timeout; /* tcp user timeout (numeric string) */
341 	char	   *client_encoding_initial;	/* encoding to use */
342 	char	   *pgoptions;		/* options to start the backend with */
343 	char	   *appname;		/* application name */
344 	char	   *fbappname;		/* fallback application name */
345 	char	   *dbName;			/* database name */
346 	char	   *replication;	/* connect as the replication standby? */
347 	char	   *pguser;			/* Postgres username and password, if any */
348 	char	   *pgpass;
349 	char	   *pgpassfile;		/* path to a file containing password(s) */
350 	char	   *channel_binding;	/* channel binding mode
351 									 * (require,prefer,disable) */
352 	char	   *keepalives;		/* use TCP keepalives? */
353 	char	   *keepalives_idle;	/* time between TCP keepalives */
354 	char	   *keepalives_interval;	/* time between TCP keepalive
355 										 * retransmits */
356 	char	   *keepalives_count;	/* maximum number of TCP keepalive
357 									 * retransmits */
358 	char	   *sslmode;		/* SSL mode (require,prefer,allow,disable) */
359 	char	   *sslcompression; /* SSL compression (0 or 1) */
360 	char	   *sslkey;			/* client key filename */
361 	char	   *sslcert;		/* client certificate filename */
362 	char	   *sslpassword;	/* client key file password */
363 	char	   *sslrootcert;	/* root certificate filename */
364 	char	   *sslcrl;			/* certificate revocation list filename */
365 	char	   *requirepeer;	/* required peer credentials for local sockets */
366 	char	   *gssencmode;		/* GSS mode (require,prefer,disable) */
367 	char	   *krbsrvname;		/* Kerberos service name */
368 	char	   *gsslib;			/* What GSS library to use ("gssapi" or
369 								 * "sspi") */
370 	char	   *ssl_min_protocol_version;	/* minimum TLS protocol version */
371 	char	   *ssl_max_protocol_version;	/* maximum TLS protocol version */
372 
373 	/* Type of connection to make.  Possible values: any, read-write. */
374 	char	   *target_session_attrs;
375 
376 	/* Optional file to write trace info to */
377 	FILE	   *Pfdebug;
378 
379 	/* Callback procedures for notice message processing */
380 	PGNoticeHooks noticeHooks;
381 
382 	/* Event procs registered via PQregisterEventProc */
383 	PGEvent    *events;			/* expandable array of event data */
384 	int			nEvents;		/* number of active events */
385 	int			eventArraySize; /* allocated array size */
386 
387 	/* Status indicators */
388 	ConnStatusType status;
389 	PGAsyncStatusType asyncStatus;
390 	PGTransactionStatusType xactStatus; /* never changes to ACTIVE */
391 	PGQueryClass queryclass;
392 	char	   *last_query;		/* last SQL command, or NULL if unknown */
393 	char		last_sqlstate[6];	/* last reported SQLSTATE */
394 	bool		options_valid;	/* true if OK to attempt connection */
395 	bool		nonblocking;	/* whether this connection is using nonblock
396 								 * sending semantics */
397 	bool		singleRowMode;	/* return current query result row-by-row? */
398 	char		copy_is_binary; /* 1 = copy binary, 0 = copy text */
399 	int			copy_already_done;	/* # bytes already returned in COPY OUT */
400 	PGnotify   *notifyHead;		/* oldest unreported Notify msg */
401 	PGnotify   *notifyTail;		/* newest unreported Notify msg */
402 
403 	/* Support for multiple hosts in connection string */
404 	int			nconnhost;		/* # of hosts named in conn string */
405 	int			whichhost;		/* host we're currently trying/connected to */
406 	pg_conn_host *connhost;		/* details about each named host */
407 	char	   *connip;			/* IP address for current network connection */
408 
409 	/* Connection data */
410 	pgsocket	sock;			/* FD for socket, PGINVALID_SOCKET if
411 								 * unconnected */
412 	SockAddr	laddr;			/* Local address */
413 	SockAddr	raddr;			/* Remote address */
414 	ProtocolVersion pversion;	/* FE/BE protocol version in use */
415 	int			sversion;		/* server version, e.g. 70401 for 7.4.1 */
416 	bool		auth_req_received;	/* true if any type of auth req received */
417 	bool		password_needed;	/* true if server demanded a password */
418 	bool		sigpipe_so;		/* have we masked SIGPIPE via SO_NOSIGPIPE? */
419 	bool		sigpipe_flag;	/* can we mask SIGPIPE via MSG_NOSIGNAL? */
420 	bool		write_failed;	/* have we had a write failure on sock? */
421 	char	   *write_err_msg;	/* write error message, or NULL if OOM */
422 
423 	/* Transient state needed while establishing connection */
424 	bool		try_next_addr;	/* time to advance to next address/host? */
425 	bool		try_next_host;	/* time to advance to next connhost[]? */
426 	struct addrinfo *addrlist;	/* list of addresses for current connhost */
427 	struct addrinfo *addr_cur;	/* the one currently being tried */
428 	int			addrlist_family;	/* needed to know how to free addrlist */
429 	PGSetenvStatusType setenv_state;	/* for 2.0 protocol only */
430 	const PQEnvironmentOption *next_eo;
431 	bool		send_appname;	/* okay to send application_name? */
432 
433 	/* Miscellaneous stuff */
434 	int			be_pid;			/* PID of backend --- needed for cancels */
435 	int			be_key;			/* key of backend --- needed for cancels */
436 	pgParameterStatus *pstatus; /* ParameterStatus data */
437 	int			client_encoding;	/* encoding id */
438 	bool		std_strings;	/* standard_conforming_strings */
439 	PGVerbosity verbosity;		/* error/notice message verbosity */
440 	PGContextVisibility show_context;	/* whether to show CONTEXT field */
441 	PGlobjfuncs *lobjfuncs;		/* private state for large-object access fns */
442 
443 	/* Buffer for data received from backend and not yet processed */
444 	char	   *inBuffer;		/* currently allocated buffer */
445 	int			inBufSize;		/* allocated size of buffer */
446 	int			inStart;		/* offset to first unconsumed data in buffer */
447 	int			inCursor;		/* next byte to tentatively consume */
448 	int			inEnd;			/* offset to first position after avail data */
449 
450 	/* Buffer for data not yet sent to backend */
451 	char	   *outBuffer;		/* currently allocated buffer */
452 	int			outBufSize;		/* allocated size of buffer */
453 	int			outCount;		/* number of chars waiting in buffer */
454 
455 	/* State for constructing messages in outBuffer */
456 	int			outMsgStart;	/* offset to msg start (length word); if -1,
457 								 * msg has no length word */
458 	int			outMsgEnd;		/* offset to msg end (so far) */
459 
460 	/* Row processor interface workspace */
461 	PGdataValue *rowBuf;		/* array for passing values to rowProcessor */
462 	int			rowBufLen;		/* number of entries allocated in rowBuf */
463 
464 	/* Status for asynchronous result construction */
465 	PGresult   *result;			/* result being constructed */
466 	PGresult   *next_result;	/* next result (used in single-row mode) */
467 
468 	/* Assorted state for SASL, SSL, GSS, etc */
469 	void	   *sasl_state;
470 
471 	/* SSL structures */
472 	bool		ssl_in_use;
473 
474 #ifdef USE_SSL
475 	bool		allow_ssl_try;	/* Allowed to try SSL negotiation */
476 	bool		wait_ssl_try;	/* Delay SSL negotiation until after
477 								 * attempting normal connection */
478 #ifdef USE_OPENSSL
479 	SSL		   *ssl;			/* SSL status, if have SSL connection */
480 	X509	   *peer;			/* X509 cert of server */
481 #ifdef USE_SSL_ENGINE
482 	ENGINE	   *engine;			/* SSL engine, if any */
483 #else
484 	void	   *engine;			/* dummy field to keep struct the same if
485 								 * OpenSSL version changes */
486 #endif
487 #endif							/* USE_OPENSSL */
488 #endif							/* USE_SSL */
489 
490 #ifdef ENABLE_GSS
491 	gss_ctx_id_t gctx;			/* GSS context */
492 	gss_name_t	gtarg_nam;		/* GSS target name */
493 
494 	/* The following are encryption-only */
495 	bool		try_gss;		/* GSS attempting permitted */
496 	bool		gssenc;			/* GSS encryption is usable */
497 	gss_cred_id_t gcred;		/* GSS credential temp storage. */
498 
499 	/* GSS encryption I/O state --- see fe-secure-gssapi.c */
500 	char	   *gss_SendBuffer; /* Encrypted data waiting to be sent */
501 	int			gss_SendLength; /* End of data available in gss_SendBuffer */
502 	int			gss_SendNext;	/* Next index to send a byte from
503 								 * gss_SendBuffer */
504 	int			gss_SendConsumed;	/* Number of *unencrypted* bytes consumed
505 									 * for current contents of gss_SendBuffer */
506 	char	   *gss_RecvBuffer; /* Received, encrypted data */
507 	int			gss_RecvLength; /* End of data available in gss_RecvBuffer */
508 	char	   *gss_ResultBuffer;	/* Decryption of data in gss_RecvBuffer */
509 	int			gss_ResultLength;	/* End of data available in
510 									 * gss_ResultBuffer */
511 	int			gss_ResultNext; /* Next index to read a byte from
512 								 * gss_ResultBuffer */
513 	uint32		gss_MaxPktSize; /* Maximum size we can encrypt and fit the
514 								 * results into our output buffer */
515 #endif
516 
517 #ifdef ENABLE_SSPI
518 	CredHandle *sspicred;		/* SSPI credentials handle */
519 	CtxtHandle *sspictx;		/* SSPI context */
520 	char	   *sspitarget;		/* SSPI target name */
521 	int			usesspi;		/* Indicate if SSPI is in use on the
522 								 * connection */
523 #endif
524 
525 	/* Buffer for current error message */
526 	PQExpBufferData errorMessage;	/* expansible string */
527 
528 	/* Buffer for receiving various parts of messages */
529 	PQExpBufferData workBuffer; /* expansible string */
530 };
531 
532 /* PGcancel stores all data necessary to cancel a connection. A copy of this
533  * data is required to safely cancel a connection running on a different
534  * thread.
535  */
536 struct pg_cancel
537 {
538 	SockAddr	raddr;			/* Remote address */
539 	int			be_pid;			/* PID of backend --- needed for cancels */
540 	int			be_key;			/* key of backend --- needed for cancels */
541 };
542 
543 
544 /* String descriptions of the ExecStatusTypes.
545  * direct use of this array is deprecated; call PQresStatus() instead.
546  */
547 extern char *const pgresStatus[];
548 
549 
550 #ifdef USE_SSL
551 
552 #ifndef WIN32
553 #define USER_CERT_FILE		".postgresql/postgresql.crt"
554 #define USER_KEY_FILE		".postgresql/postgresql.key"
555 #define ROOT_CERT_FILE		".postgresql/root.crt"
556 #define ROOT_CRL_FILE		".postgresql/root.crl"
557 #else
558 /* On Windows, the "home" directory is already PostgreSQL-specific */
559 #define USER_CERT_FILE		"postgresql.crt"
560 #define USER_KEY_FILE		"postgresql.key"
561 #define ROOT_CERT_FILE		"root.crt"
562 #define ROOT_CRL_FILE		"root.crl"
563 #endif
564 
565 #endif							/* USE_SSL */
566 
567 /* ----------------
568  * Internal functions of libpq
569  * Functions declared here need to be visible across files of libpq,
570  * but are not intended to be called by applications.  We use the
571  * convention "pqXXX" for internal functions, vs. the "PQxxx" names
572  * used for application-visible routines.
573  * ----------------
574  */
575 
576 /* === in fe-connect.c === */
577 
578 extern void pqDropConnection(PGconn *conn, bool flushInput);
579 extern int	pqPacketSend(PGconn *conn, char pack_type,
580 						 const void *buf, size_t buf_len);
581 extern bool pqGetHomeDirectory(char *buf, int bufsize);
582 
583 #ifdef ENABLE_THREAD_SAFETY
584 extern pgthreadlock_t pg_g_threadlock;
585 
586 #define PGTHREAD_ERROR(msg) \
587 	do { \
588 		fprintf(stderr, "%s\n", msg); \
589 		abort(); \
590 	} while (0)
591 
592 
593 #define pglock_thread()		pg_g_threadlock(true)
594 #define pgunlock_thread()	pg_g_threadlock(false)
595 #else
596 #define pglock_thread()		((void) 0)
597 #define pgunlock_thread()	((void) 0)
598 #endif
599 
600 /* === in fe-exec.c === */
601 
602 extern void pqSetResultError(PGresult *res, const char *msg);
603 extern void pqCatenateResultError(PGresult *res, const char *msg);
604 extern void *pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary);
605 extern char *pqResultStrdup(PGresult *res, const char *str);
606 extern void pqClearAsyncResult(PGconn *conn);
607 extern void pqSaveErrorResult(PGconn *conn);
608 extern PGresult *pqPrepareAsyncResult(PGconn *conn);
609 extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2, 3);
610 extern void pqSaveMessageField(PGresult *res, char code,
611 							   const char *value);
612 extern void pqSaveParameterStatus(PGconn *conn, const char *name,
613 								  const char *value);
614 extern int	pqRowProcessor(PGconn *conn, const char **errmsgp);
615 
616 /* === in fe-protocol2.c === */
617 
618 extern PostgresPollingStatusType pqSetenvPoll(PGconn *conn);
619 
620 extern char *pqBuildStartupPacket2(PGconn *conn, int *packetlen,
621 								   const PQEnvironmentOption *options);
622 extern void pqParseInput2(PGconn *conn);
623 extern int	pqGetCopyData2(PGconn *conn, char **buffer, int async);
624 extern int	pqGetline2(PGconn *conn, char *s, int maxlen);
625 extern int	pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize);
626 extern int	pqEndcopy2(PGconn *conn);
627 extern PGresult *pqFunctionCall2(PGconn *conn, Oid fnid,
628 								 int *result_buf, int *actual_result_len,
629 								 int result_is_int,
630 								 const PQArgBlock *args, int nargs);
631 
632 /* === in fe-protocol3.c === */
633 
634 extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen,
635 								   const PQEnvironmentOption *options);
636 extern void pqParseInput3(PGconn *conn);
637 extern int	pqGetErrorNotice3(PGconn *conn, bool isError);
638 extern void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res,
639 								 PGVerbosity verbosity, PGContextVisibility show_context);
640 extern int	pqGetCopyData3(PGconn *conn, char **buffer, int async);
641 extern int	pqGetline3(PGconn *conn, char *s, int maxlen);
642 extern int	pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize);
643 extern int	pqEndcopy3(PGconn *conn);
644 extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid,
645 								 int *result_buf, int *actual_result_len,
646 								 int result_is_int,
647 								 const PQArgBlock *args, int nargs);
648 
649 /* === in fe-misc.c === */
650 
651  /*
652   * "Get" and "Put" routines return 0 if successful, EOF if not. Note that for
653   * Get, EOF merely means the buffer is exhausted, not that there is
654   * necessarily any error.
655   */
656 extern int	pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn);
657 extern int	pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn);
658 extern int	pqGetc(char *result, PGconn *conn);
659 extern int	pqPutc(char c, PGconn *conn);
660 extern int	pqGets(PQExpBuffer buf, PGconn *conn);
661 extern int	pqGets_append(PQExpBuffer buf, PGconn *conn);
662 extern int	pqPuts(const char *s, PGconn *conn);
663 extern int	pqGetnchar(char *s, size_t len, PGconn *conn);
664 extern int	pqSkipnchar(size_t len, PGconn *conn);
665 extern int	pqPutnchar(const char *s, size_t len, PGconn *conn);
666 extern int	pqGetInt(int *result, size_t bytes, PGconn *conn);
667 extern int	pqPutInt(int value, size_t bytes, PGconn *conn);
668 extern int	pqPutMsgStart(char msg_type, bool force_len, PGconn *conn);
669 extern int	pqPutMsgEnd(PGconn *conn);
670 extern int	pqReadData(PGconn *conn);
671 extern int	pqFlush(PGconn *conn);
672 extern int	pqWait(int forRead, int forWrite, PGconn *conn);
673 extern int	pqWaitTimed(int forRead, int forWrite, PGconn *conn,
674 						time_t finish_time);
675 extern int	pqReadReady(PGconn *conn);
676 extern int	pqWriteReady(PGconn *conn);
677 
678 /* === in fe-secure.c === */
679 
680 extern int	pqsecure_initialize(PGconn *);
681 extern PostgresPollingStatusType pqsecure_open_client(PGconn *);
682 extern void pqsecure_close(PGconn *);
683 extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len);
684 extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
685 extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len);
686 extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len);
687 
688 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
689 extern int	pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
690 extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
691 							 bool got_epipe);
692 #endif
693 
694 /* === SSL === */
695 
696 /*
697  * The SSL implementation provides these functions.
698  */
699 
700 /*
701  *	Implementation of PQinitSSL().
702  */
703 extern void pgtls_init_library(bool do_ssl, int do_crypto);
704 
705 /*
706  * Initialize SSL library.
707  *
708  * The conn parameter is only used to be able to pass back an error
709  * message - no connection-local setup is made here.
710  *
711  * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage).
712  */
713 extern int	pgtls_init(PGconn *conn);
714 
715 /*
716  *	Begin or continue negotiating a secure session.
717  */
718 extern PostgresPollingStatusType pgtls_open_client(PGconn *conn);
719 
720 /*
721  *	Close SSL connection.
722  */
723 extern void pgtls_close(PGconn *conn);
724 
725 /*
726  *	Read data from a secure connection.
727  *
728  * On failure, this function is responsible for putting a suitable message
729  * into conn->errorMessage.  The caller must still inspect errno, but only
730  * to determine whether to continue/retry after error.
731  */
732 extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len);
733 
734 /*
735  *	Is there unread data waiting in the SSL read buffer?
736  */
737 extern bool pgtls_read_pending(PGconn *conn);
738 
739 /*
740  *	Write data to a secure connection.
741  *
742  * On failure, this function is responsible for putting a suitable message
743  * into conn->errorMessage.  The caller must still inspect errno, but only
744  * to determine whether to continue/retry after error.
745  */
746 extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
747 
748 /*
749  * Get the hash of the server certificate, for SCRAM channel binding type
750  * tls-server-end-point.
751  *
752  * NULL is sent back to the caller in the event of an error, with an
753  * error message for the caller to consume.
754  *
755  * This is not supported with old versions of OpenSSL that don't have
756  * the X509_get_signature_nid() function.
757  */
758 #if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID)
759 #define HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
760 extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len);
761 #endif
762 
763 /*
764  * Verify that the server certificate matches the host name we connected to.
765  *
766  * The certificate's Common Name and Subject Alternative Names are considered.
767  *
768  * Returns 1 if the name matches, and 0 if it does not. On error, returns
769  * -1, and sets the libpq error message.
770  *
771  */
772 extern int	pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
773 															int *names_examined,
774 															char **first_name);
775 
776 /* === GSSAPI === */
777 
778 #ifdef ENABLE_GSS
779 
780 /*
781  * Establish a GSSAPI-encrypted connection.
782  */
783 extern PostgresPollingStatusType pqsecure_open_gss(PGconn *conn);
784 
785 /*
786  * Read and write functions for GSSAPI-encrypted connections, with internal
787  * buffering to handle nonblocking sockets.
788  */
789 extern ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len);
790 extern ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len);
791 #endif
792 
793 /* === miscellaneous macros === */
794 
795 /*
796  * this is so that we can check if a connection is non-blocking internally
797  * without the overhead of a function call
798  */
799 #define pqIsnonblocking(conn)	((conn)->nonblocking)
800 
801 #ifdef ENABLE_NLS
802 extern char *libpq_gettext(const char *msgid) pg_attribute_format_arg(1);
803 extern char *libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n) pg_attribute_format_arg(1) pg_attribute_format_arg(2);
804 #else
805 #define libpq_gettext(x) (x)
806 #define libpq_ngettext(s, p, n) ((n) == 1 ? (s) : (p))
807 #endif
808 
809 /*
810  * These macros are needed to let error-handling code be portable between
811  * Unix and Windows.  (ugh)
812  */
813 #ifdef WIN32
814 #define SOCK_ERRNO (WSAGetLastError())
815 #define SOCK_STRERROR winsock_strerror
816 #define SOCK_ERRNO_SET(e) WSASetLastError(e)
817 #else
818 #define SOCK_ERRNO errno
819 #define SOCK_STRERROR strerror_r
820 #define SOCK_ERRNO_SET(e) (errno = (e))
821 #endif
822 
823 #endif							/* LIBPQ_INT_H */
824