1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * libpq-be.h |
4 | * This file contains definitions for structures and externs used |
5 | * by the postmaster during client authentication. |
6 | * |
7 | * Note that this is backend-internal and is NOT exported to clients. |
8 | * Structs that need to be client-visible are in pqcomm.h. |
9 | * |
10 | * |
11 | * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group |
12 | * Portions Copyright (c) 1994, Regents of the University of California |
13 | * |
14 | * src/include/libpq/libpq-be.h |
15 | * |
16 | *------------------------------------------------------------------------- |
17 | */ |
18 | #ifndef LIBPQ_BE_H |
19 | #define LIBPQ_BE_H |
20 | |
21 | #include <sys/time.h> |
22 | #ifdef USE_OPENSSL |
23 | #include <openssl/ssl.h> |
24 | #include <openssl/err.h> |
25 | #endif |
26 | #ifdef HAVE_NETINET_TCP_H |
27 | #include <netinet/tcp.h> |
28 | #endif |
29 | |
30 | #ifdef ENABLE_GSS |
31 | #if defined(HAVE_GSSAPI_H) |
32 | #include <gssapi.h> |
33 | #else |
34 | #include <gssapi/gssapi.h> |
35 | #endif /* HAVE_GSSAPI_H */ |
36 | /* |
37 | * GSSAPI brings in headers that set a lot of things in the global namespace on win32, |
38 | * that doesn't match the msvc build. It gives a bunch of compiler warnings that we ignore, |
39 | * but also defines a symbol that simply does not exist. Undefine it again. |
40 | */ |
41 | #ifdef _MSC_VER |
42 | #undef HAVE_GETADDRINFO |
43 | #endif |
44 | #endif /* ENABLE_GSS */ |
45 | |
46 | #ifdef ENABLE_SSPI |
47 | #define SECURITY_WIN32 |
48 | #if defined(WIN32) && !defined(_MSC_VER) |
49 | #include <ntsecapi.h> |
50 | #endif |
51 | #include <security.h> |
52 | #undef SECURITY_WIN32 |
53 | |
54 | #ifndef ENABLE_GSS |
55 | /* |
56 | * Define a fake structure compatible with GSSAPI on Unix. |
57 | */ |
58 | typedef struct |
59 | { |
60 | void *value; |
61 | int length; |
62 | } gss_buffer_desc; |
63 | #endif |
64 | #endif /* ENABLE_SSPI */ |
65 | |
66 | #include "datatype/timestamp.h" |
67 | #include "libpq/hba.h" |
68 | #include "libpq/pqcomm.h" |
69 | |
70 | |
71 | typedef enum CAC_state |
72 | { |
73 | CAC_OK, CAC_STARTUP, CAC_SHUTDOWN, CAC_RECOVERY, CAC_TOOMANY, |
74 | CAC_WAITBACKUP |
75 | } CAC_state; |
76 | |
77 | |
78 | /* |
79 | * GSSAPI specific state information |
80 | */ |
81 | #if defined(ENABLE_GSS) | defined(ENABLE_SSPI) |
82 | typedef struct |
83 | { |
84 | gss_buffer_desc outbuf; /* GSSAPI output token buffer */ |
85 | #ifdef ENABLE_GSS |
86 | gss_cred_id_t cred; /* GSSAPI connection cred's */ |
87 | gss_ctx_id_t ctx; /* GSSAPI connection context */ |
88 | gss_name_t name; /* GSSAPI client name */ |
89 | char *princ; /* GSSAPI Principal used for auth, NULL if |
90 | * GSSAPI auth was not used */ |
91 | bool auth; /* GSSAPI Authentication used */ |
92 | bool enc; /* GSSAPI encryption in use */ |
93 | #endif |
94 | } pg_gssinfo; |
95 | #endif |
96 | |
97 | /* |
98 | * This is used by the postmaster in its communication with frontends. It |
99 | * contains all state information needed during this communication before the |
100 | * backend is run. The Port structure is kept in malloc'd memory and is |
101 | * still available when a backend is running (see MyProcPort). The data |
102 | * it points to must also be malloc'd, or else palloc'd in TopMemoryContext, |
103 | * so that it survives into PostgresMain execution! |
104 | * |
105 | * remote_hostname is set if we did a successful reverse lookup of the |
106 | * client's IP address during connection setup. |
107 | * remote_hostname_resolv tracks the state of hostname verification: |
108 | * +1 = remote_hostname is known to resolve to client's IP address |
109 | * -1 = remote_hostname is known NOT to resolve to client's IP address |
110 | * 0 = we have not done the forward DNS lookup yet |
111 | * -2 = there was an error in name resolution |
112 | * If reverse lookup of the client IP address fails, remote_hostname will be |
113 | * left NULL while remote_hostname_resolv is set to -2. If reverse lookup |
114 | * succeeds but forward lookup fails, remote_hostname_resolv is also set to -2 |
115 | * (the case is distinguishable because remote_hostname isn't NULL). In |
116 | * either of the -2 cases, remote_hostname_errcode saves the lookup return |
117 | * code for possible later use with gai_strerror. |
118 | */ |
119 | |
120 | typedef struct Port |
121 | { |
122 | pgsocket sock; /* File descriptor */ |
123 | bool noblock; /* is the socket in non-blocking mode? */ |
124 | ProtocolVersion proto; /* FE/BE protocol version */ |
125 | SockAddr laddr; /* local addr (postmaster) */ |
126 | SockAddr raddr; /* remote addr (client) */ |
127 | char *remote_host; /* name (or ip addr) of remote host */ |
128 | char *remote_hostname; /* name (not ip addr) of remote host, if |
129 | * available */ |
130 | int remote_hostname_resolv; /* see above */ |
131 | int remote_hostname_errcode; /* see above */ |
132 | char *remote_port; /* text rep of remote port */ |
133 | CAC_state canAcceptConnections; /* postmaster connection status */ |
134 | |
135 | /* |
136 | * Information that needs to be saved from the startup packet and passed |
137 | * into backend execution. "char *" fields are NULL if not set. |
138 | * guc_options points to a List of alternating option names and values. |
139 | */ |
140 | char *database_name; |
141 | char *user_name; |
142 | char *cmdline_options; |
143 | List *guc_options; |
144 | |
145 | /* |
146 | * The startup packet application name, only used here for the "connection |
147 | * authorized" log message. We shouldn't use this post-startup, instead |
148 | * the GUC should be used as application can change it afterward. |
149 | */ |
150 | char *application_name; |
151 | |
152 | /* |
153 | * Information that needs to be held during the authentication cycle. |
154 | */ |
155 | HbaLine *hba; |
156 | |
157 | /* |
158 | * TCP keepalive and user timeout settings. |
159 | * |
160 | * default values are 0 if AF_UNIX or not yet known; current values are 0 |
161 | * if AF_UNIX or using the default. Also, -1 in a default value means we |
162 | * were unable to find out the default (getsockopt failed). |
163 | */ |
164 | int default_keepalives_idle; |
165 | int default_keepalives_interval; |
166 | int default_keepalives_count; |
167 | int default_tcp_user_timeout; |
168 | int keepalives_idle; |
169 | int keepalives_interval; |
170 | int keepalives_count; |
171 | int tcp_user_timeout; |
172 | |
173 | /* |
174 | * GSSAPI structures. |
175 | */ |
176 | #if defined(ENABLE_GSS) || defined(ENABLE_SSPI) |
177 | |
178 | /* |
179 | * If GSSAPI is supported, store GSSAPI information. Otherwise, store a |
180 | * NULL pointer to make sure offsets in the struct remain the same. |
181 | */ |
182 | pg_gssinfo *gss; |
183 | #else |
184 | void *gss; |
185 | #endif |
186 | |
187 | /* |
188 | * SSL structures. |
189 | */ |
190 | bool ssl_in_use; |
191 | char *peer_cn; |
192 | bool peer_cert_valid; |
193 | |
194 | /* |
195 | * OpenSSL structures. (Keep these last so that the locations of other |
196 | * fields are the same whether or not you build with OpenSSL.) |
197 | */ |
198 | #ifdef USE_OPENSSL |
199 | SSL *ssl; |
200 | X509 *peer; |
201 | #endif |
202 | } Port; |
203 | |
204 | #ifdef USE_SSL |
205 | /* |
206 | * Hardcoded DH parameters, used in ephemeral DH keying. (See also |
207 | * README.SSL for more details on EDH.) |
208 | * |
209 | * If you want to create your own hardcoded DH parameters |
210 | * for fun and profit, review "Assigned Number for SKIP |
211 | * Protocols" (http://www.skip-vpn.org/spec/numbers.html) |
212 | * for suggestions. |
213 | */ |
214 | #define FILE_DH2048 \ |
215 | "-----BEGIN DH PARAMETERS-----\n\ |
216 | MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\ |
217 | 89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\ |
218 | T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\ |
219 | zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\ |
220 | Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\ |
221 | CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\ |
222 | -----END DH PARAMETERS-----\n" |
223 | |
224 | /* |
225 | * These functions are implemented by the glue code specific to each |
226 | * SSL implementation (e.g. be-secure-openssl.c) |
227 | */ |
228 | |
229 | /* |
230 | * Initialize global SSL context. |
231 | * |
232 | * If isServerStart is true, report any errors as FATAL (so we don't return). |
233 | * Otherwise, log errors at LOG level and return -1 to indicate trouble, |
234 | * preserving the old SSL state if any. Returns 0 if OK. |
235 | */ |
236 | extern int be_tls_init(bool isServerStart); |
237 | |
238 | /* |
239 | * Destroy global SSL context, if any. |
240 | */ |
241 | extern void be_tls_destroy(void); |
242 | |
243 | /* |
244 | * Attempt to negotiate SSL connection. |
245 | */ |
246 | extern int be_tls_open_server(Port *port); |
247 | |
248 | /* |
249 | * Close SSL connection. |
250 | */ |
251 | extern void be_tls_close(Port *port); |
252 | |
253 | /* |
254 | * Read data from a secure connection. |
255 | */ |
256 | extern ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor); |
257 | |
258 | /* |
259 | * Write data to a secure connection. |
260 | */ |
261 | extern ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor); |
262 | |
263 | /* |
264 | * Return information about the SSL connection. |
265 | */ |
266 | extern int be_tls_get_cipher_bits(Port *port); |
267 | extern bool be_tls_get_compression(Port *port); |
268 | extern const char *be_tls_get_version(Port *port); |
269 | extern const char *be_tls_get_cipher(Port *port); |
270 | extern void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len); |
271 | extern void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len); |
272 | extern void be_tls_get_peer_serial(Port *port, char *ptr, size_t len); |
273 | |
274 | /* |
275 | * Get the server certificate hash for SCRAM channel binding type |
276 | * tls-server-end-point. |
277 | * |
278 | * The result is a palloc'd hash of the server certificate with its |
279 | * size, and NULL if there is no certificate available. |
280 | * |
281 | * This is not supported with old versions of OpenSSL that don't have |
282 | * the X509_get_signature_nid() function. |
283 | */ |
284 | #if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID) |
285 | #define HAVE_BE_TLS_GET_CERTIFICATE_HASH |
286 | extern char *be_tls_get_certificate_hash(Port *port, size_t *len); |
287 | #endif |
288 | |
289 | #endif /* USE_SSL */ |
290 | |
291 | #ifdef ENABLE_GSS |
292 | /* |
293 | * Return information about the GSSAPI authenticated connection |
294 | */ |
295 | extern bool be_gssapi_get_auth(Port *port); |
296 | extern bool be_gssapi_get_enc(Port *port); |
297 | extern const char *be_gssapi_get_princ(Port *port); |
298 | |
299 | /* Read and write to a GSSAPI-encrypted connection. */ |
300 | extern ssize_t be_gssapi_read(Port *port, void *ptr, size_t len); |
301 | extern ssize_t be_gssapi_write(Port *port, void *ptr, size_t len); |
302 | #endif /* ENABLE_GSS */ |
303 | |
304 | extern ProtocolVersion FrontendProtocol; |
305 | |
306 | /* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */ |
307 | |
308 | extern int pq_getkeepalivesidle(Port *port); |
309 | extern int pq_getkeepalivesinterval(Port *port); |
310 | extern int pq_getkeepalivescount(Port *port); |
311 | extern int pq_gettcpusertimeout(Port *port); |
312 | |
313 | extern int pq_setkeepalivesidle(int idle, Port *port); |
314 | extern int pq_setkeepalivesinterval(int interval, Port *port); |
315 | extern int pq_setkeepalivescount(int count, Port *port); |
316 | extern int pq_settcpusertimeout(int timeout, Port *port); |
317 | |
318 | #endif /* LIBPQ_BE_H */ |
319 | |