PostgreSQL Source Code  git master
be-secure.c
Go to the documentation of this file.
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 
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. */
54 
55 /* GUC variable: if false, prefer client ciphers */
57 
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 secure_initialize(bool isServerStart)
74 {
75 #ifdef USE_SSL
76  return be_tls_init(isServerStart);
77 #else
78  return 0;
79 #endif
80 }
81 
82 /*
83  * Destroy global context, if any.
84  */
85 void
87 {
88 #ifdef USE_SSL
90 #endif
91 }
92 
93 /*
94  * Indicate if we have loaded the root CA store to verify certificates
95  */
96 bool
98 {
99 #ifdef USE_SSL
100  return ssl_loaded_verify_locations;
101 #else
102  return false;
103 #endif
104 }
105 
106 /*
107  * Attempt to negotiate secure session.
108  */
109 int
111 {
112 #ifdef USE_SSL
113  int r = 0;
114  ssize_t len;
115 
116  /* push unencrypted buffered data back through SSL setup */
118  if (len > 0)
119  {
120  char *buf = palloc(len);
121 
122  pq_startmsgread();
123  if (pq_getbytes(buf, len) == EOF)
124  return STATUS_ERROR; /* shouldn't be possible */
125  pq_endmsgread();
126  port->raw_buf = buf;
127  port->raw_buf_remaining = len;
128  port->raw_buf_consumed = 0;
129  }
131 
133 
134  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  elog(LOG, "buffered unencrypted data remains after negotiating SSL connection");
141  return STATUS_ERROR;
142  }
143  if (port->raw_buf != NULL)
144  {
145  pfree(port->raw_buf);
146  port->raw_buf = NULL;
147  }
148 
149  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  return r;
154 #else
155  return 0;
156 #endif
157 }
158 
159 /*
160  * Close secure session.
161  */
162 void
164 {
165 #ifdef USE_SSL
166  if (port->ssl_in_use)
168 #endif
169 }
170 
171 /*
172  * Read data from a secure connection.
173  */
174 ssize_t
175 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. */
182 
183 retry:
184 #ifdef USE_SSL
185  waitfor = 0;
186  if (port->ssl_in_use)
187  {
188  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  n = secure_raw_read(port, ptr, len);
202  waitfor = WL_SOCKET_READABLE;
203  }
204 
205  /* In blocking mode, wait until the socket is ready */
206  if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
207  {
208  WaitEvent event;
209 
210  Assert(waitfor);
211 
213 
214  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  if (event.events & WL_POSTMASTER_DEATH)
235  ereport(FATAL,
236  (errcode(ERRCODE_ADMIN_SHUTDOWN),
237  errmsg("terminating connection due to unexpected postmaster exit")));
238 
239  /* Handle interrupt. */
240  if (event.events & WL_LATCH_SET)
241  {
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  goto retry;
252  }
253 
254  /*
255  * Process interrupts that happened during a successful (or non-blocking,
256  * or hard-failed) read.
257  */
259 
260  return n;
261 }
262 
263 ssize_t
264 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  if (port->raw_buf_remaining > 0)
270  {
271  /* consume up to len bytes from the raw_buf */
272  if (len > port->raw_buf_remaining)
273  len = port->raw_buf_remaining;
274  Assert(port->raw_buf);
275  memcpy(ptr, port->raw_buf + port->raw_buf_consumed, len);
276  port->raw_buf_consumed += len;
277  port->raw_buf_remaining -= len;
278  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  n = recv(port->sock, ptr, len, 0);
289 #ifdef WIN32
290  pgwin32_noblock = false;
291 #endif
292 
293  return n;
294 }
295 
296 
297 /*
298  * Write data to a secure connection.
299  */
300 ssize_t
301 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. */
308 
309 retry:
310  waitfor = 0;
311 #ifdef USE_SSL
312  if (port->ssl_in_use)
313  {
314  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  n = secure_raw_write(port, ptr, len);
328  waitfor = WL_SOCKET_WRITEABLE;
329  }
330 
331  if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
332  {
333  WaitEvent event;
334 
335  Assert(waitfor);
336 
338 
339  WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
340  WAIT_EVENT_CLIENT_WRITE);
341 
342  /* See comments in secure_read. */
343  if (event.events & WL_POSTMASTER_DEATH)
344  ereport(FATAL,
345  (errcode(ERRCODE_ADMIN_SHUTDOWN),
346  errmsg("terminating connection due to unexpected postmaster exit")));
347 
348  /* Handle interrupt. */
349  if (event.events & WL_LATCH_SET)
350  {
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  goto retry;
361  }
362 
363  /*
364  * Process interrupts that happened during a successful (or non-blocking,
365  * or hard-failed) write.
366  */
368 
369  return n;
370 }
371 
372 ssize_t
373 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  n = send(port->sock, ptr, len, 0);
381 #ifdef WIN32
382  pgwin32_noblock = false;
383 #endif
384 
385  return n;
386 }
ssize_t be_gssapi_read(Port *port, void *ptr, size_t len)
ssize_t be_gssapi_write(Port *port, void *ptr, size_t len)
void be_tls_destroy(void)
int be_tls_init(bool isServerStart)
int be_tls_open_server(Port *port)
void be_tls_close(Port *port)
ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
void secure_destroy(void)
Definition: be-secure.c:86
char * ssl_crl_dir
Definition: be-secure.c:40
char * ssl_dh_params_file
Definition: be-secure.c:41
int ssl_min_protocol_version
Definition: be-secure.c:58
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:264
int secure_initialize(bool isServerStart)
Definition: be-secure.c:73
char * ssl_cert_file
Definition: be-secure.c:36
bool SSLPreferServerCiphers
Definition: be-secure.c:56
char * ssl_library
Definition: be-secure.c:35
int ssl_max_protocol_version
Definition: be-secure.c:59
char * ssl_passphrase_command
Definition: be-secure.c:42
ssize_t secure_write(Port *port, void *ptr, size_t len)
Definition: be-secure.c:301
int secure_open_server(Port *port)
Definition: be-secure.c:110
bool ssl_passphrase_command_supports_reload
Definition: be-secure.c:43
char * SSLCipherSuites
Definition: be-secure.c:50
bool secure_loaded_verify_locations(void)
Definition: be-secure.c:97
char * SSLECDHCurve
Definition: be-secure.c:53
char * ssl_key_file
Definition: be-secure.c:37
void secure_close(Port *port)
Definition: be-secure.c:163
ssize_t secure_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:175
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:373
char * ssl_crl_file
Definition: be-secure.c:39
char * ssl_ca_file
Definition: be-secure.c:38
#define Assert(condition)
Definition: c.h:858
#define STATUS_ERROR
Definition: c.h:1170
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1159
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define LOG
Definition: elog.h:31
#define FATAL
Definition: elog.h:41
#define DEBUG2
Definition: elog.h:29
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
struct Latch * MyLatch
Definition: globals.c:60
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
Definition: latch.c:1049
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
Definition: latch.c:1424
void ResetLatch(Latch *latch)
Definition: latch.c:724
#define WL_SOCKET_READABLE
Definition: latch.h:128
#define WL_LATCH_SET
Definition: latch.h:127
#define WL_POSTMASTER_DEATH
Definition: latch.h:131
#define WL_SOCKET_WRITEABLE
Definition: latch.h:129
@ PG_TLS1_2_VERSION
Definition: libpq.h:131
@ PG_TLS_ANY
Definition: libpq.h:128
#define FeBeWaitSetSocketPos
Definition: libpq.h:63
void pfree(void *pointer)
Definition: mcxt.c:1520
void * palloc(Size size)
Definition: mcxt.c:1316
const void size_t len
static int port
Definition: pg_regress.c:116
static char * buf
Definition: pg_test_fsync.c:73
void ProcessClientReadInterrupt(bool blocked)
Definition: postgres.c:509
void ProcessClientWriteInterrupt(bool blocked)
Definition: postgres.c:555
int pq_getbytes(char *s, size_t len)
Definition: pqcomm.c:1062
ssize_t pq_buffer_remaining_data(void)
Definition: pqcomm.c:1126
WaitEventSet * FeBeWaitSet
Definition: pqcomm.c:165
void pq_endmsgread(void)
Definition: pqcomm.c:1164
void pq_startmsgread(void)
Definition: pqcomm.c:1140
int pgwin32_noblock
Definition: socket.c:28
Definition: libpq-be.h:133
uint32 events
Definition: latch.h:155
#define EWOULDBLOCK
Definition: win32_port.h:380
#define recv(s, buf, len, flags)
Definition: win32_port.h:496
#define send(s, buf, len, flags)
Definition: win32_port.h:497
#define EAGAIN
Definition: win32_port.h:372