summaryrefslogtreecommitdiff
path: root/src/include/libpq/libpq-be.h
blob: e9df4295e202d01ec31f7b6715a13e55fa28ab5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/*-------------------------------------------------------------------------
 *
 * libpq-be.h
 *	  This file contains definitions for structures and externs used
 *	  by the postmaster during client authentication.
 *
 *	  Note that this is backend-internal and is NOT exported to clients.
 *	  Structs that need to be client-visible are in pqcomm.h.
 *
 *
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/libpq/libpq-be.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef LIBPQ_BE_H
#define LIBPQ_BE_H

#include <sys/time.h>
#ifdef USE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif
#include <netinet/tcp.h>

#ifdef ENABLE_GSS
#if defined(HAVE_GSSAPI_H)
#include <gssapi.h>
#else
#include <gssapi/gssapi.h>
#endif							/* HAVE_GSSAPI_H */
#endif							/* ENABLE_GSS */

#ifdef ENABLE_SSPI
#define SECURITY_WIN32
#if defined(WIN32) && !defined(_MSC_VER)
#include <ntsecapi.h>
#endif
#include <security.h>
#undef SECURITY_WIN32

#ifndef ENABLE_GSS
/*
 * Define a fake structure compatible with GSSAPI on Unix.
 */
typedef struct
{
	void	   *value;
	int			length;
} gss_buffer_desc;
#endif
#endif							/* ENABLE_SSPI */

#include "datatype/timestamp.h"
#include "libpq/hba.h"
#include "libpq/pqcomm.h"


typedef enum CAC_state
{
	CAC_OK,
	CAC_STARTUP,
	CAC_SHUTDOWN,
	CAC_RECOVERY,
	CAC_NOTCONSISTENT,
	CAC_TOOMANY
} CAC_state;


/*
 * GSSAPI specific state information
 */
#if defined(ENABLE_GSS) | defined(ENABLE_SSPI)
typedef struct
{
	gss_buffer_desc outbuf;		/* GSSAPI output token buffer */
#ifdef ENABLE_GSS
	gss_cred_id_t cred;			/* GSSAPI connection cred's */
	gss_ctx_id_t ctx;			/* GSSAPI connection context */
	gss_name_t	name;			/* GSSAPI client name */
	char	   *princ;			/* GSSAPI Principal used for auth, NULL if
								 * GSSAPI auth was not used */
	bool		auth;			/* GSSAPI Authentication used */
	bool		enc;			/* GSSAPI encryption in use */
	bool		delegated_creds;	/* GSSAPI Delegated credentials */
#endif
} pg_gssinfo;
#endif

/*
 * ClientConnectionInfo includes the fields describing the client connection
 * that are copied over to parallel workers as nothing from Port does that.
 * The same rules apply for allocations here as for Port (everything must be
 * malloc'd or palloc'd in TopMemoryContext).
 *
 * If you add a struct member here, remember to also handle serialization in
 * SerializeClientConnectionInfo() and co.
 */
typedef struct ClientConnectionInfo
{
	/*
	 * Authenticated identity.  The meaning of this identifier is dependent on
	 * auth_method; it is the identity (if any) that the user presented during
	 * the authentication cycle, before they were assigned a database role.
	 * (It is effectively the "SYSTEM-USERNAME" of a pg_ident usermap --
	 * though the exact string in use may be different, depending on pg_hba
	 * options.)
	 *
	 * authn_id is NULL if the user has not actually been authenticated, for
	 * example if the "trust" auth method is in use.
	 */
	const char *authn_id;

	/*
	 * The HBA method that determined the above authn_id.  This only has
	 * meaning if authn_id is not NULL; otherwise it's undefined.
	 */
	UserAuth	auth_method;
} ClientConnectionInfo;

/*
 * This is used by the postmaster in its communication with frontends.  It
 * contains all state information needed during this communication before the
 * backend is run.  The Port structure is kept in malloc'd memory and is
 * still available when a backend is running (see MyProcPort).  The data
 * it points to must also be malloc'd, or else palloc'd in TopMemoryContext,
 * so that it survives into PostgresMain execution!
 *
 * remote_hostname is set if we did a successful reverse lookup of the
 * client's IP address during connection setup.
 * remote_hostname_resolv tracks the state of hostname verification:
 *	+1 = remote_hostname is known to resolve to client's IP address
 *	-1 = remote_hostname is known NOT to resolve to client's IP address
 *	 0 = we have not done the forward DNS lookup yet
 *	-2 = there was an error in name resolution
 * If reverse lookup of the client IP address fails, remote_hostname will be
 * left NULL while remote_hostname_resolv is set to -2.  If reverse lookup
 * succeeds but forward lookup fails, remote_hostname_resolv is also set to -2
 * (the case is distinguishable because remote_hostname isn't NULL).  In
 * either of the -2 cases, remote_hostname_errcode saves the lookup return
 * code for possible later use with gai_strerror.
 */

typedef struct Port
{
	pgsocket	sock;			/* File descriptor */
	bool		noblock;		/* is the socket in non-blocking mode? */
	ProtocolVersion proto;		/* FE/BE protocol version */
	SockAddr	laddr;			/* local addr (postmaster) */
	SockAddr	raddr;			/* remote addr (client) */
	char	   *remote_host;	/* name (or ip addr) of remote host */
	char	   *remote_hostname;	/* name (not ip addr) of remote host, if
									 * available */
	int			remote_hostname_resolv; /* see above */
	int			remote_hostname_errcode;	/* see above */
	char	   *remote_port;	/* text rep of remote port */
	CAC_state	canAcceptConnections;	/* postmaster connection status */

	/*
	 * Information that needs to be saved from the startup packet and passed
	 * into backend execution.  "char *" fields are NULL if not set.
	 * guc_options points to a List of alternating option names and values.
	 */
	char	   *database_name;
	char	   *user_name;
	char	   *cmdline_options;
	List	   *guc_options;

	/*
	 * The startup packet application name, only used here for the "connection
	 * authorized" log message. We shouldn't use this post-startup, instead
	 * the GUC should be used as application can change it afterward.
	 */
	char	   *application_name;

	/*
	 * Information that needs to be held during the authentication cycle.
	 */
	HbaLine    *hba;

	/*
	 * TCP keepalive and user timeout settings.
	 *
	 * default values are 0 if AF_UNIX or not yet known; current values are 0
	 * if AF_UNIX or using the default. Also, -1 in a default value means we
	 * were unable to find out the default (getsockopt failed).
	 */
	int			default_keepalives_idle;
	int			default_keepalives_interval;
	int			default_keepalives_count;
	int			default_tcp_user_timeout;
	int			keepalives_idle;
	int			keepalives_interval;
	int			keepalives_count;
	int			tcp_user_timeout;

	/*
	 * GSSAPI structures.
	 */
#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)

	/*
	 * If GSSAPI is supported and used on this connection, store GSSAPI
	 * information.  Even when GSSAPI is not compiled in, store a NULL pointer
	 * to keep struct offsets the same (for extension ABI compatibility).
	 */
	pg_gssinfo *gss;
#else
	void	   *gss;
#endif

	/*
	 * SSL structures.
	 */
	bool		ssl_in_use;
	char	   *peer_cn;
	char	   *peer_dn;
	bool		peer_cert_valid;

	/*
	 * OpenSSL structures. (Keep these last so that the locations of other
	 * fields are the same whether or not you build with SSL enabled.)
	 */
#ifdef USE_OPENSSL
	SSL		   *ssl;
	X509	   *peer;
#endif
} Port;

#ifdef USE_SSL
/*
 *	Hardcoded DH parameters, used in ephemeral DH keying.  (See also
 *	README.SSL for more details on EDH.)
 *
 *	This is the 2048-bit DH parameter from RFC 3526.  The generation of the
 *	prime is specified in RFC 2412 Appendix E, which also discusses the
 *	design choice of the generator.  Note that when loaded with OpenSSL
 *	this causes DH_check() to fail on DH_NOT_SUITABLE_GENERATOR, where
 *	leaking a bit is preferred.
 */
#define FILE_DH2048 \
"-----BEGIN DH PARAMETERS-----\n\
MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n\
IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n\
awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n\
mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n\
fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n\
5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==\n\
-----END DH PARAMETERS-----\n"

/*
 * These functions are implemented by the glue code specific to each
 * SSL implementation (e.g. be-secure-openssl.c)
 */

/*
 * Initialize global SSL context.
 *
 * If isServerStart is true, report any errors as FATAL (so we don't return).
 * Otherwise, log errors at LOG level and return -1 to indicate trouble,
 * preserving the old SSL state if any.  Returns 0 if OK.
 */
extern int	be_tls_init(bool isServerStart);

/*
 * Destroy global SSL context, if any.
 */
extern void be_tls_destroy(void);

/*
 * Attempt to negotiate SSL connection.
 */
extern int	be_tls_open_server(Port *port);

/*
 * Close SSL connection.
 */
extern void be_tls_close(Port *port);

/*
 * Read data from a secure connection.
 */
extern ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor);

/*
 * Write data to a secure connection.
 */
extern ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor);

/*
 * Return information about the SSL connection.
 */
extern int	be_tls_get_cipher_bits(Port *port);
extern const char *be_tls_get_version(Port *port);
extern const char *be_tls_get_cipher(Port *port);
extern void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len);
extern void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len);
extern void be_tls_get_peer_serial(Port *port, char *ptr, size_t len);

/*
 * Get the server certificate hash for SCRAM channel binding type
 * tls-server-end-point.
 *
 * The result is a palloc'd hash of the server certificate with its
 * size, and NULL if there is no certificate available.
 *
 * This is not supported with old versions of OpenSSL that don't have
 * the X509_get_signature_nid() function.
 */
#if defined(USE_OPENSSL) && (defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO))
#define HAVE_BE_TLS_GET_CERTIFICATE_HASH
extern char *be_tls_get_certificate_hash(Port *port, size_t *len);
#endif

/* init hook for SSL, the default sets the password callback if appropriate */
#ifdef USE_OPENSSL
typedef void (*openssl_tls_init_hook_typ) (SSL_CTX *context, bool isServerStart);
extern PGDLLIMPORT openssl_tls_init_hook_typ openssl_tls_init_hook;
#endif

#endif							/* USE_SSL */

#ifdef ENABLE_GSS
/*
 * Return information about the GSSAPI authenticated connection
 */
extern bool be_gssapi_get_auth(Port *port);
extern bool be_gssapi_get_enc(Port *port);
extern const char *be_gssapi_get_princ(Port *port);
extern bool be_gssapi_get_deleg(Port *port);

/* Read and write to a GSSAPI-encrypted connection. */
extern ssize_t be_gssapi_read(Port *port, void *ptr, size_t len);
extern ssize_t be_gssapi_write(Port *port, void *ptr, size_t len);
#endif							/* ENABLE_GSS */

extern PGDLLIMPORT ProtocolVersion FrontendProtocol;
extern PGDLLIMPORT ClientConnectionInfo MyClientConnectionInfo;

/* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */

extern int	pq_getkeepalivesidle(Port *port);
extern int	pq_getkeepalivesinterval(Port *port);
extern int	pq_getkeepalivescount(Port *port);
extern int	pq_gettcpusertimeout(Port *port);

extern int	pq_setkeepalivesidle(int idle, Port *port);
extern int	pq_setkeepalivesinterval(int interval, Port *port);
extern int	pq_setkeepalivescount(int count, Port *port);
extern int	pq_settcpusertimeout(int timeout, Port *port);

#endif							/* LIBPQ_BE_H */