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-2019, 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 "tcop/tcopprot.h"
36#include "utils/memutils.h"
37#include "storage/ipc.h"
38#include "storage/proc.h"
39
40
41char *ssl_library;
42char *ssl_cert_file;
43char *ssl_key_file;
44char *ssl_ca_file;
45char *ssl_crl_file;
46char *ssl_dh_params_file;
47char *ssl_passphrase_command;
48bool ssl_passphrase_command_supports_reload;
49
50#ifdef USE_SSL
51bool ssl_loaded_verify_locations = false;
52#endif
53
54/* GUC variable controlling SSL cipher list */
55char *SSLCipherSuites = NULL;
56
57/* GUC variable for default ECHD curve. */
58char *SSLECDHCurve;
59
60/* GUC variable: if false, prefer client ciphers */
61bool SSLPreferServerCiphers;
62
63int ssl_min_protocol_version;
64int 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 */
77int
78secure_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 */
90void
91secure_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 */
101bool
102secure_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 */
114int
115secure_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("SSL connection from \"%s\"",
124 port->peer_cn ? port->peer_cn : "(anonymous)")));
125#endif
126
127 return r;
128}
129
130/*
131 * Close secure session.
132 */
133void
134secure_close(Port *port)
135{
136#ifdef USE_SSL
137 if (port->ssl_in_use)
138 be_tls_close(port);
139#endif
140}
141
142/*
143 * Read data from a secure connection.
144 */
145ssize_t
146secure_read(Port *port, void *ptr, size_t len)
147{
148 ssize_t n;
149 int waitfor;
150
151 /* Deal with any already-pending interrupt condition. */
152 ProcessClientReadInterrupt(false);
153
154retry:
155#ifdef USE_SSL
156 waitfor = 0;
157 if (port->ssl_in_use)
158 {
159 n = be_tls_read(port, ptr, len, &waitfor);
160 }
161 else
162#endif
163#ifdef ENABLE_GSS
164 if (port->gss->enc)
165 {
166 n = be_gssapi_read(port, ptr, len);
167 waitfor = WL_SOCKET_READABLE;
168 }
169 else
170#endif
171 {
172 n = secure_raw_read(port, ptr, len);
173 waitfor = WL_SOCKET_READABLE;
174 }
175
176 /* In blocking mode, wait until the socket is ready */
177 if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
178 {
179 WaitEvent event;
180
181 Assert(waitfor);
182
183 ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
184
185 WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
186 WAIT_EVENT_CLIENT_READ);
187
188 /*
189 * If the postmaster has died, it's not safe to continue running,
190 * because it is the postmaster's job to kill us if some other backend
191 * exits uncleanly. Moreover, we won't run very well in this state;
192 * helper processes like walwriter and the bgwriter will exit, so
193 * performance may be poor. Finally, if we don't exit, pg_ctl will be
194 * unable to restart the postmaster without manual intervention, so no
195 * new connections can be accepted. Exiting clears the deck for a
196 * postmaster restart.
197 *
198 * (Note that we only make this check when we would otherwise sleep on
199 * our latch. We might still continue running for a while if the
200 * postmaster is killed in mid-query, or even through multiple queries
201 * if we never have to wait for read. We don't want to burn too many
202 * cycles checking for this very rare condition, and this should cause
203 * us to exit quickly in most cases.)
204 */
205 if (event.events & WL_POSTMASTER_DEATH)
206 ereport(FATAL,
207 (errcode(ERRCODE_ADMIN_SHUTDOWN),
208 errmsg("terminating connection due to unexpected postmaster exit")));
209
210 /* Handle interrupt. */
211 if (event.events & WL_LATCH_SET)
212 {
213 ResetLatch(MyLatch);
214 ProcessClientReadInterrupt(true);
215
216 /*
217 * We'll retry the read. Most likely it will return immediately
218 * because there's still no data available, and we'll wait for the
219 * socket to become ready again.
220 */
221 }
222 goto retry;
223 }
224
225 /*
226 * Process interrupts that happened during a successful (or non-blocking,
227 * or hard-failed) read.
228 */
229 ProcessClientReadInterrupt(false);
230
231 return n;
232}
233
234ssize_t
235secure_raw_read(Port *port, void *ptr, size_t len)
236{
237 ssize_t n;
238
239 /*
240 * Try to read from the socket without blocking. If it succeeds we're
241 * done, otherwise we'll wait for the socket using the latch mechanism.
242 */
243#ifdef WIN32
244 pgwin32_noblock = true;
245#endif
246 n = recv(port->sock, ptr, len, 0);
247#ifdef WIN32
248 pgwin32_noblock = false;
249#endif
250
251 return n;
252}
253
254
255/*
256 * Write data to a secure connection.
257 */
258ssize_t
259secure_write(Port *port, void *ptr, size_t len)
260{
261 ssize_t n;
262 int waitfor;
263
264 /* Deal with any already-pending interrupt condition. */
265 ProcessClientWriteInterrupt(false);
266
267retry:
268 waitfor = 0;
269#ifdef USE_SSL
270 if (port->ssl_in_use)
271 {
272 n = be_tls_write(port, ptr, len, &waitfor);
273 }
274 else
275#endif
276#ifdef ENABLE_GSS
277 if (port->gss->enc)
278 {
279 n = be_gssapi_write(port, ptr, len);
280 waitfor = WL_SOCKET_WRITEABLE;
281 }
282 else
283#endif
284 {
285 n = secure_raw_write(port, ptr, len);
286 waitfor = WL_SOCKET_WRITEABLE;
287 }
288
289 if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
290 {
291 WaitEvent event;
292
293 Assert(waitfor);
294
295 ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
296
297 WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
298 WAIT_EVENT_CLIENT_WRITE);
299
300 /* See comments in secure_read. */
301 if (event.events & WL_POSTMASTER_DEATH)
302 ereport(FATAL,
303 (errcode(ERRCODE_ADMIN_SHUTDOWN),
304 errmsg("terminating connection due to unexpected postmaster exit")));
305
306 /* Handle interrupt. */
307 if (event.events & WL_LATCH_SET)
308 {
309 ResetLatch(MyLatch);
310 ProcessClientWriteInterrupt(true);
311
312 /*
313 * We'll retry the write. Most likely it will return immediately
314 * because there's still no buffer space available, and we'll wait
315 * for the socket to become ready again.
316 */
317 }
318 goto retry;
319 }
320
321 /*
322 * Process interrupts that happened during a successful (or non-blocking,
323 * or hard-failed) write.
324 */
325 ProcessClientWriteInterrupt(false);
326
327 return n;
328}
329
330ssize_t
331secure_raw_write(Port *port, const void *ptr, size_t len)
332{
333 ssize_t n;
334
335#ifdef WIN32
336 pgwin32_noblock = true;
337#endif
338 n = send(port->sock, ptr, len, 0);
339#ifdef WIN32
340 pgwin32_noblock = false;
341#endif
342
343 return n;
344}
345