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