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