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