1 /*-------------------------------------------------------------------------
2 *
3 * be-secure.c
4 * functions related to setting up a secure connection to the frontend.
5 * Secure connections are expected to provide confidentiality,
6 * message integrity and endpoint authentication.
7 *
8 *
9 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
11 *
12 *
13 * IDENTIFICATION
14 * src/backend/libpq/be-secure.c
15 *
16 *-------------------------------------------------------------------------
17 */
18
19 #include "postgres.h"
20
21 #include <signal.h>
22 #include <fcntl.h>
23 #include <ctype.h>
24 #include <sys/socket.h>
25 #include <netdb.h>
26 #include <netinet/in.h>
27 #ifdef HAVE_NETINET_TCP_H
28 #include <netinet/tcp.h>
29 #include <arpa/inet.h>
30 #endif
31
32 #include "libpq/libpq.h"
33 #include "miscadmin.h"
34 #include "pgstat.h"
35 #include "storage/ipc.h"
36 #include "storage/proc.h"
37 #include "tcop/tcopprot.h"
38 #include "utils/memutils.h"
39
40 char *ssl_library;
41 char *ssl_cert_file;
42 char *ssl_key_file;
43 char *ssl_ca_file;
44 char *ssl_crl_file;
45 char *ssl_crl_dir;
46 char *ssl_dh_params_file;
47 char *ssl_passphrase_command;
48 bool ssl_passphrase_command_supports_reload;
49
50 #ifdef USE_SSL
51 bool ssl_loaded_verify_locations = false;
52 #endif
53
54 /* GUC variable controlling SSL cipher list */
55 char *SSLCipherSuites = NULL;
56
57 /* GUC variable for default ECHD curve. */
58 char *SSLECDHCurve;
59
60 /* GUC variable: if false, prefer client ciphers */
61 bool SSLPreferServerCiphers;
62
63 int ssl_min_protocol_version;
64 int ssl_max_protocol_version;
65
66 /* ------------------------------------------------------------ */
67 /* Procedures common to all secure sessions */
68 /* ------------------------------------------------------------ */
69
70 /*
71 * Initialize global context.
72 *
73 * If isServerStart is true, report any errors as FATAL (so we don't return).
74 * Otherwise, log errors at LOG level and return -1 to indicate trouble,
75 * preserving the old SSL state if any. Returns 0 if OK.
76 */
77 int
secure_initialize(bool isServerStart)78 secure_initialize(bool isServerStart)
79 {
80 #ifdef USE_SSL
81 return be_tls_init(isServerStart);
82 #else
83 return 0;
84 #endif
85 }
86
87 /*
88 * Destroy global context, if any.
89 */
90 void
secure_destroy(void)91 secure_destroy(void)
92 {
93 #ifdef USE_SSL
94 be_tls_destroy();
95 #endif
96 }
97
98 /*
99 * Indicate if we have loaded the root CA store to verify certificates
100 */
101 bool
secure_loaded_verify_locations(void)102 secure_loaded_verify_locations(void)
103 {
104 #ifdef USE_SSL
105 return ssl_loaded_verify_locations;
106 #else
107 return false;
108 #endif
109 }
110
111 /*
112 * Attempt to negotiate secure session.
113 */
114 int
secure_open_server(Port * port)115 secure_open_server(Port *port)
116 {
117 int r = 0;
118
119 #ifdef USE_SSL
120 r = be_tls_open_server(port);
121
122 ereport(DEBUG2,
123 (errmsg_internal("SSL connection from DN:\"%s\" CN:\"%s\"",
124 port->peer_dn ? port->peer_dn : "(anonymous)",
125 port->peer_cn ? port->peer_cn : "(anonymous)")));
126 #endif
127
128 return r;
129 }
130
131 /*
132 * Close secure session.
133 */
134 void
secure_close(Port * port)135 secure_close(Port *port)
136 {
137 #ifdef USE_SSL
138 if (port->ssl_in_use)
139 be_tls_close(port);
140 #endif
141 }
142
143 /*
144 * Read data from a secure connection.
145 */
146 ssize_t
secure_read(Port * port,void * ptr,size_t len)147 secure_read(Port *port, void *ptr, size_t len)
148 {
149 ssize_t n;
150 int waitfor;
151
152 /* Deal with any already-pending interrupt condition. */
153 ProcessClientReadInterrupt(false);
154
155 retry:
156 #ifdef USE_SSL
157 waitfor = 0;
158 if (port->ssl_in_use)
159 {
160 n = be_tls_read(port, ptr, len, &waitfor);
161 }
162 else
163 #endif
164 #ifdef ENABLE_GSS
165 if (port->gss && port->gss->enc)
166 {
167 n = be_gssapi_read(port, ptr, len);
168 waitfor = WL_SOCKET_READABLE;
169 }
170 else
171 #endif
172 {
173 n = secure_raw_read(port, ptr, len);
174 waitfor = WL_SOCKET_READABLE;
175 }
176
177 /* In blocking mode, wait until the socket is ready */
178 if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
179 {
180 WaitEvent event;
181
182 Assert(waitfor);
183
184 ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, waitfor, NULL);
185
186 WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
187 WAIT_EVENT_CLIENT_READ);
188
189 /*
190 * If the postmaster has died, it's not safe to continue running,
191 * because it is the postmaster's job to kill us if some other backend
192 * exits uncleanly. Moreover, we won't run very well in this state;
193 * helper processes like walwriter and the bgwriter will exit, so
194 * performance may be poor. Finally, if we don't exit, pg_ctl will be
195 * unable to restart the postmaster without manual intervention, so no
196 * new connections can be accepted. Exiting clears the deck for a
197 * postmaster restart.
198 *
199 * (Note that we only make this check when we would otherwise sleep on
200 * our latch. We might still continue running for a while if the
201 * postmaster is killed in mid-query, or even through multiple queries
202 * if we never have to wait for read. We don't want to burn too many
203 * cycles checking for this very rare condition, and this should cause
204 * us to exit quickly in most cases.)
205 */
206 if (event.events & WL_POSTMASTER_DEATH)
207 ereport(FATAL,
208 (errcode(ERRCODE_ADMIN_SHUTDOWN),
209 errmsg("terminating connection due to unexpected postmaster exit")));
210
211 /* Handle interrupt. */
212 if (event.events & WL_LATCH_SET)
213 {
214 ResetLatch(MyLatch);
215 ProcessClientReadInterrupt(true);
216
217 /*
218 * We'll retry the read. Most likely it will return immediately
219 * because there's still no data available, and we'll wait for the
220 * socket to become ready again.
221 */
222 }
223 goto retry;
224 }
225
226 /*
227 * Process interrupts that happened during a successful (or non-blocking,
228 * or hard-failed) read.
229 */
230 ProcessClientReadInterrupt(false);
231
232 return n;
233 }
234
235 ssize_t
secure_raw_read(Port * port,void * ptr,size_t len)236 secure_raw_read(Port *port, void *ptr, size_t len)
237 {
238 ssize_t n;
239
240 /*
241 * Try to read from the socket without blocking. If it succeeds we're
242 * done, otherwise we'll wait for the socket using the latch mechanism.
243 */
244 #ifdef WIN32
245 pgwin32_noblock = true;
246 #endif
247 n = recv(port->sock, ptr, len, 0);
248 #ifdef WIN32
249 pgwin32_noblock = false;
250 #endif
251
252 return n;
253 }
254
255
256 /*
257 * Write data to a secure connection.
258 */
259 ssize_t
secure_write(Port * port,void * ptr,size_t len)260 secure_write(Port *port, void *ptr, size_t len)
261 {
262 ssize_t n;
263 int waitfor;
264
265 /* Deal with any already-pending interrupt condition. */
266 ProcessClientWriteInterrupt(false);
267
268 retry:
269 waitfor = 0;
270 #ifdef USE_SSL
271 if (port->ssl_in_use)
272 {
273 n = be_tls_write(port, ptr, len, &waitfor);
274 }
275 else
276 #endif
277 #ifdef ENABLE_GSS
278 if (port->gss && port->gss->enc)
279 {
280 n = be_gssapi_write(port, ptr, len);
281 waitfor = WL_SOCKET_WRITEABLE;
282 }
283 else
284 #endif
285 {
286 n = secure_raw_write(port, ptr, len);
287 waitfor = WL_SOCKET_WRITEABLE;
288 }
289
290 if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
291 {
292 WaitEvent event;
293
294 Assert(waitfor);
295
296 ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, waitfor, NULL);
297
298 WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
299 WAIT_EVENT_CLIENT_WRITE);
300
301 /* See comments in secure_read. */
302 if (event.events & WL_POSTMASTER_DEATH)
303 ereport(FATAL,
304 (errcode(ERRCODE_ADMIN_SHUTDOWN),
305 errmsg("terminating connection due to unexpected postmaster exit")));
306
307 /* Handle interrupt. */
308 if (event.events & WL_LATCH_SET)
309 {
310 ResetLatch(MyLatch);
311 ProcessClientWriteInterrupt(true);
312
313 /*
314 * We'll retry the write. Most likely it will return immediately
315 * because there's still no buffer space available, and we'll wait
316 * for the socket to become ready again.
317 */
318 }
319 goto retry;
320 }
321
322 /*
323 * Process interrupts that happened during a successful (or non-blocking,
324 * or hard-failed) write.
325 */
326 ProcessClientWriteInterrupt(false);
327
328 return n;
329 }
330
331 ssize_t
secure_raw_write(Port * port,const void * ptr,size_t len)332 secure_raw_write(Port *port, const void *ptr, size_t len)
333 {
334 ssize_t n;
335
336 #ifdef WIN32
337 pgwin32_noblock = true;
338 #endif
339 n = send(port->sock, ptr, len, 0);
340 #ifdef WIN32
341 pgwin32_noblock = false;
342 #endif
343
344 return n;
345 }
346