Line data Source code
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-2024, 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 : #include <netinet/tcp.h>
28 : #include <arpa/inet.h>
29 :
30 : #include "libpq/libpq.h"
31 : #include "miscadmin.h"
32 : #include "tcop/tcopprot.h"
33 : #include "utils/injection_point.h"
34 : #include "utils/wait_event.h"
35 :
36 : char *ssl_library;
37 : char *ssl_cert_file;
38 : char *ssl_key_file;
39 : char *ssl_ca_file;
40 : char *ssl_crl_file;
41 : char *ssl_crl_dir;
42 : char *ssl_dh_params_file;
43 : char *ssl_passphrase_command;
44 : bool ssl_passphrase_command_supports_reload;
45 :
46 : #ifdef USE_SSL
47 : bool ssl_loaded_verify_locations = false;
48 : #endif
49 :
50 : /* GUC variable controlling SSL cipher list */
51 : char *SSLCipherSuites = NULL;
52 : char *SSLCipherList = NULL;
53 :
54 : /* GUC variable for default ECHD curve. */
55 : char *SSLECDHCurve;
56 :
57 : /* GUC variable: if false, prefer client ciphers */
58 : bool SSLPreferServerCiphers;
59 :
60 : int ssl_min_protocol_version = PG_TLS1_2_VERSION;
61 : int ssl_max_protocol_version = PG_TLS_ANY;
62 :
63 : /* ------------------------------------------------------------ */
64 : /* Procedures common to all secure sessions */
65 : /* ------------------------------------------------------------ */
66 :
67 : /*
68 : * Initialize global context.
69 : *
70 : * If isServerStart is true, report any errors as FATAL (so we don't return).
71 : * Otherwise, log errors at LOG level and return -1 to indicate trouble,
72 : * preserving the old SSL state if any. Returns 0 if OK.
73 : */
74 : int
75 64 : secure_initialize(bool isServerStart)
76 : {
77 : #ifdef USE_SSL
78 64 : return be_tls_init(isServerStart);
79 : #else
80 : return 0;
81 : #endif
82 : }
83 :
84 : /*
85 : * Destroy global context, if any.
86 : */
87 : void
88 246 : secure_destroy(void)
89 : {
90 : #ifdef USE_SSL
91 246 : be_tls_destroy();
92 : #endif
93 246 : }
94 :
95 : /*
96 : * Indicate if we have loaded the root CA store to verify certificates
97 : */
98 : bool
99 60 : secure_loaded_verify_locations(void)
100 : {
101 : #ifdef USE_SSL
102 60 : return ssl_loaded_verify_locations;
103 : #else
104 : return false;
105 : #endif
106 : }
107 :
108 : /*
109 : * Attempt to negotiate secure session.
110 : */
111 : int
112 248 : secure_open_server(Port *port)
113 : {
114 : #ifdef USE_SSL
115 248 : int r = 0;
116 : ssize_t len;
117 :
118 : /* push unencrypted buffered data back through SSL setup */
119 248 : len = pq_buffer_remaining_data();
120 248 : if (len > 0)
121 : {
122 6 : char *buf = palloc(len);
123 :
124 6 : pq_startmsgread();
125 6 : if (pq_getbytes(buf, len) == EOF)
126 0 : return STATUS_ERROR; /* shouldn't be possible */
127 6 : pq_endmsgread();
128 6 : port->raw_buf = buf;
129 6 : port->raw_buf_remaining = len;
130 6 : port->raw_buf_consumed = 0;
131 : }
132 : Assert(pq_buffer_remaining_data() == 0);
133 :
134 248 : INJECTION_POINT("backend-ssl-startup");
135 :
136 246 : r = be_tls_open_server(port);
137 :
138 246 : if (port->raw_buf_remaining > 0)
139 : {
140 : /*
141 : * This shouldn't be possible -- it would mean the client sent
142 : * encrypted data before we established a session key...
143 : */
144 0 : elog(LOG, "buffered unencrypted data remains after negotiating SSL connection");
145 0 : return STATUS_ERROR;
146 : }
147 246 : if (port->raw_buf != NULL)
148 : {
149 6 : pfree(port->raw_buf);
150 6 : port->raw_buf = NULL;
151 : }
152 :
153 246 : ereport(DEBUG2,
154 : (errmsg_internal("SSL connection from DN:\"%s\" CN:\"%s\"",
155 : port->peer_dn ? port->peer_dn : "(anonymous)",
156 : port->peer_cn ? port->peer_cn : "(anonymous)")));
157 246 : return r;
158 : #else
159 : return 0;
160 : #endif
161 : }
162 :
163 : /*
164 : * Close secure session.
165 : */
166 : void
167 22498 : secure_close(Port *port)
168 : {
169 : #ifdef USE_SSL
170 22498 : if (port->ssl_in_use)
171 246 : be_tls_close(port);
172 : #endif
173 22498 : }
174 :
175 : /*
176 : * Read data from a secure connection.
177 : */
178 : ssize_t
179 3181872 : secure_read(Port *port, void *ptr, size_t len)
180 : {
181 : ssize_t n;
182 : int waitfor;
183 :
184 : /* Deal with any already-pending interrupt condition. */
185 3181872 : ProcessClientReadInterrupt(false);
186 :
187 3492142 : retry:
188 : #ifdef USE_SSL
189 3492142 : waitfor = 0;
190 3492142 : if (port->ssl_in_use)
191 : {
192 762 : n = be_tls_read(port, ptr, len, &waitfor);
193 : }
194 : else
195 : #endif
196 : #ifdef ENABLE_GSS
197 : if (port->gss && port->gss->enc)
198 : {
199 : n = be_gssapi_read(port, ptr, len);
200 : waitfor = WL_SOCKET_READABLE;
201 : }
202 : else
203 : #endif
204 : {
205 3491380 : n = secure_raw_read(port, ptr, len);
206 3491380 : waitfor = WL_SOCKET_READABLE;
207 : }
208 :
209 : /* In blocking mode, wait until the socket is ready */
210 3492142 : if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
211 : {
212 : WaitEvent event;
213 :
214 : Assert(waitfor);
215 :
216 310350 : ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, waitfor, NULL);
217 :
218 310350 : WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
219 : WAIT_EVENT_CLIENT_READ);
220 :
221 : /*
222 : * If the postmaster has died, it's not safe to continue running,
223 : * because it is the postmaster's job to kill us if some other backend
224 : * exits uncleanly. Moreover, we won't run very well in this state;
225 : * helper processes like walwriter and the bgwriter will exit, so
226 : * performance may be poor. Finally, if we don't exit, pg_ctl will be
227 : * unable to restart the postmaster without manual intervention, so no
228 : * new connections can be accepted. Exiting clears the deck for a
229 : * postmaster restart.
230 : *
231 : * (Note that we only make this check when we would otherwise sleep on
232 : * our latch. We might still continue running for a while if the
233 : * postmaster is killed in mid-query, or even through multiple queries
234 : * if we never have to wait for read. We don't want to burn too many
235 : * cycles checking for this very rare condition, and this should cause
236 : * us to exit quickly in most cases.)
237 : */
238 310350 : if (event.events & WL_POSTMASTER_DEATH)
239 0 : ereport(FATAL,
240 : (errcode(ERRCODE_ADMIN_SHUTDOWN),
241 : errmsg("terminating connection due to unexpected postmaster exit")));
242 :
243 : /* Handle interrupt. */
244 310350 : if (event.events & WL_LATCH_SET)
245 : {
246 19470 : ResetLatch(MyLatch);
247 19470 : ProcessClientReadInterrupt(true);
248 :
249 : /*
250 : * We'll retry the read. Most likely it will return immediately
251 : * because there's still no data available, and we'll wait for the
252 : * socket to become ready again.
253 : */
254 : }
255 310324 : goto retry;
256 : }
257 :
258 : /*
259 : * Process interrupts that happened during a successful (or non-blocking,
260 : * or hard-failed) read.
261 : */
262 3181792 : ProcessClientReadInterrupt(false);
263 :
264 3181788 : return n;
265 : }
266 :
267 : ssize_t
268 3495408 : secure_raw_read(Port *port, void *ptr, size_t len)
269 : {
270 : ssize_t n;
271 :
272 : /* Read from the "unread" buffered data first. c.f. libpq-be.h */
273 3495408 : if (port->raw_buf_remaining > 0)
274 : {
275 : /* consume up to len bytes from the raw_buf */
276 12 : if (len > port->raw_buf_remaining)
277 0 : len = port->raw_buf_remaining;
278 : Assert(port->raw_buf);
279 12 : memcpy(ptr, port->raw_buf + port->raw_buf_consumed, len);
280 12 : port->raw_buf_consumed += len;
281 12 : port->raw_buf_remaining -= len;
282 12 : return len;
283 : }
284 :
285 : /*
286 : * Try to read from the socket without blocking. If it succeeds we're
287 : * done, otherwise we'll wait for the socket using the latch mechanism.
288 : */
289 : #ifdef WIN32
290 : pgwin32_noblock = true;
291 : #endif
292 3495396 : n = recv(port->sock, ptr, len, 0);
293 : #ifdef WIN32
294 : pgwin32_noblock = false;
295 : #endif
296 :
297 3495396 : return n;
298 : }
299 :
300 :
301 : /*
302 : * Write data to a secure connection.
303 : */
304 : ssize_t
305 2045070 : secure_write(Port *port, void *ptr, size_t len)
306 : {
307 : ssize_t n;
308 : int waitfor;
309 :
310 : /* Deal with any already-pending interrupt condition. */
311 2045070 : ProcessClientWriteInterrupt(false);
312 :
313 2064118 : retry:
314 2064118 : waitfor = 0;
315 : #ifdef USE_SSL
316 2064118 : if (port->ssl_in_use)
317 : {
318 372 : n = be_tls_write(port, ptr, len, &waitfor);
319 : }
320 : else
321 : #endif
322 : #ifdef ENABLE_GSS
323 : if (port->gss && port->gss->enc)
324 : {
325 : n = be_gssapi_write(port, ptr, len);
326 : waitfor = WL_SOCKET_WRITEABLE;
327 : }
328 : else
329 : #endif
330 : {
331 2063746 : n = secure_raw_write(port, ptr, len);
332 2063746 : waitfor = WL_SOCKET_WRITEABLE;
333 : }
334 :
335 2064118 : if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
336 : {
337 : WaitEvent event;
338 :
339 : Assert(waitfor);
340 :
341 19048 : ModifyWaitEvent(FeBeWaitSet, FeBeWaitSetSocketPos, waitfor, NULL);
342 :
343 19048 : WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
344 : WAIT_EVENT_CLIENT_WRITE);
345 :
346 : /* See comments in secure_read. */
347 19048 : if (event.events & WL_POSTMASTER_DEATH)
348 0 : ereport(FATAL,
349 : (errcode(ERRCODE_ADMIN_SHUTDOWN),
350 : errmsg("terminating connection due to unexpected postmaster exit")));
351 :
352 : /* Handle interrupt. */
353 19048 : if (event.events & WL_LATCH_SET)
354 : {
355 4 : ResetLatch(MyLatch);
356 4 : ProcessClientWriteInterrupt(true);
357 :
358 : /*
359 : * We'll retry the write. Most likely it will return immediately
360 : * because there's still no buffer space available, and we'll wait
361 : * for the socket to become ready again.
362 : */
363 : }
364 19048 : goto retry;
365 : }
366 :
367 : /*
368 : * Process interrupts that happened during a successful (or non-blocking,
369 : * or hard-failed) write.
370 : */
371 2045070 : ProcessClientWriteInterrupt(false);
372 :
373 2045070 : return n;
374 : }
375 :
376 : ssize_t
377 2064814 : secure_raw_write(Port *port, const void *ptr, size_t len)
378 : {
379 : ssize_t n;
380 :
381 : #ifdef WIN32
382 : pgwin32_noblock = true;
383 : #endif
384 2064814 : n = send(port->sock, ptr, len, 0);
385 : #ifdef WIN32
386 : pgwin32_noblock = false;
387 : #endif
388 :
389 2064814 : return n;
390 : }
|