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