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-2019, 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 "tcop/tcopprot.h"
36 #include "utils/memutils.h"
37 #include "storage/ipc.h"
38 #include "storage/proc.h"
39 
40 
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
120  r = be_tls_open_server(port);
121 
122  ereport(DEBUG2,
123  (errmsg("SSL connection from \"%s\"",
124  port->peer_cn ? port->peer_cn : "(anonymous)")));
125 #endif
126 
127  return r;
128 }
129 
130 /*
131  * Close secure session.
132  */
133 void
135 {
136 #ifdef USE_SSL
137  if (port->ssl_in_use)
138  be_tls_close(port);
139 #endif
140 }
141 
142 /*
143  * Read data from a secure connection.
144  */
145 ssize_t
146 secure_read(Port *port, void *ptr, size_t len)
147 {
148  ssize_t n;
149  int waitfor;
150 
151  /* Deal with any already-pending interrupt condition. */
153 
154 retry:
155 #ifdef USE_SSL
156  waitfor = 0;
157  if (port->ssl_in_use)
158  {
159  n = be_tls_read(port, ptr, len, &waitfor);
160  }
161  else
162 #endif
163 #ifdef ENABLE_GSS
164  if (port->gss->enc)
165  {
166  n = be_gssapi_read(port, ptr, len);
167  waitfor = WL_SOCKET_READABLE;
168  }
169  else
170 #endif
171  {
172  n = secure_raw_read(port, ptr, len);
173  waitfor = WL_SOCKET_READABLE;
174  }
175 
176  /* In blocking mode, wait until the socket is ready */
177  if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
178  {
179  WaitEvent event;
180 
181  Assert(waitfor);
182 
183  ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
184 
185  WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
187 
188  /*
189  * If the postmaster has died, it's not safe to continue running,
190  * because it is the postmaster's job to kill us if some other backend
191  * exits uncleanly. Moreover, we won't run very well in this state;
192  * helper processes like walwriter and the bgwriter will exit, so
193  * performance may be poor. Finally, if we don't exit, pg_ctl will be
194  * unable to restart the postmaster without manual intervention, so no
195  * new connections can be accepted. Exiting clears the deck for a
196  * postmaster restart.
197  *
198  * (Note that we only make this check when we would otherwise sleep on
199  * our latch. We might still continue running for a while if the
200  * postmaster is killed in mid-query, or even through multiple queries
201  * if we never have to wait for read. We don't want to burn too many
202  * cycles checking for this very rare condition, and this should cause
203  * us to exit quickly in most cases.)
204  */
205  if (event.events & WL_POSTMASTER_DEATH)
206  ereport(FATAL,
207  (errcode(ERRCODE_ADMIN_SHUTDOWN),
208  errmsg("terminating connection due to unexpected postmaster exit")));
209 
210  /* Handle interrupt. */
211  if (event.events & WL_LATCH_SET)
212  {
215 
216  /*
217  * We'll retry the read. Most likely it will return immediately
218  * because there's still no data available, and we'll wait for the
219  * socket to become ready again.
220  */
221  }
222  goto retry;
223  }
224 
225  /*
226  * Process interrupts that happened during a successful (or non-blocking,
227  * or hard-failed) read.
228  */
230 
231  return n;
232 }
233 
234 ssize_t
235 secure_raw_read(Port *port, void *ptr, size_t len)
236 {
237  ssize_t n;
238 
239  /*
240  * Try to read from the socket without blocking. If it succeeds we're
241  * done, otherwise we'll wait for the socket using the latch mechanism.
242  */
243 #ifdef WIN32
244  pgwin32_noblock = true;
245 #endif
246  n = recv(port->sock, ptr, len, 0);
247 #ifdef WIN32
248  pgwin32_noblock = false;
249 #endif
250 
251  return n;
252 }
253 
254 
255 /*
256  * Write data to a secure connection.
257  */
258 ssize_t
259 secure_write(Port *port, void *ptr, size_t len)
260 {
261  ssize_t n;
262  int waitfor;
263 
264  /* Deal with any already-pending interrupt condition. */
266 
267 retry:
268  waitfor = 0;
269 #ifdef USE_SSL
270  if (port->ssl_in_use)
271  {
272  n = be_tls_write(port, ptr, len, &waitfor);
273  }
274  else
275 #endif
276 #ifdef ENABLE_GSS
277  if (port->gss->enc)
278  {
279  n = be_gssapi_write(port, ptr, len);
280  waitfor = WL_SOCKET_WRITEABLE;
281  }
282  else
283 #endif
284  {
285  n = secure_raw_write(port, ptr, len);
286  waitfor = WL_SOCKET_WRITEABLE;
287  }
288 
289  if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
290  {
291  WaitEvent event;
292 
293  Assert(waitfor);
294 
295  ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
296 
297  WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
299 
300  /* See comments in secure_read. */
301  if (event.events & WL_POSTMASTER_DEATH)
302  ereport(FATAL,
303  (errcode(ERRCODE_ADMIN_SHUTDOWN),
304  errmsg("terminating connection due to unexpected postmaster exit")));
305 
306  /* Handle interrupt. */
307  if (event.events & WL_LATCH_SET)
308  {
311 
312  /*
313  * We'll retry the write. Most likely it will return immediately
314  * because there's still no buffer space available, and we'll wait
315  * for the socket to become ready again.
316  */
317  }
318  goto retry;
319  }
320 
321  /*
322  * Process interrupts that happened during a successful (or non-blocking,
323  * or hard-failed) write.
324  */
326 
327  return n;
328 }
329 
330 ssize_t
331 secure_raw_write(Port *port, const void *ptr, size_t len)
332 {
333  ssize_t n;
334 
335 #ifdef WIN32
336  pgwin32_noblock = true;
337 #endif
338  n = send(port->sock, ptr, len, 0);
339 #ifdef WIN32
340  pgwin32_noblock = false;
341 #endif
342 
343  return n;
344 }
int secure_initialize(bool isServerStart)
Definition: be-secure.c:78
ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
#define WL_SOCKET_WRITEABLE
Definition: latch.h:126
#define EAGAIN
Definition: win32_port.h:330
char * peer_cn
Definition: libpq-be.h:191
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:331
int errcode(int sqlerrcode)
Definition: elog.c:570
char * ssl_library
Definition: be-secure.c:41
Definition: libpq-be.h:120
ssize_t secure_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:146
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
Definition: latch.c:766
bool ssl_in_use
Definition: libpq-be.h:190
#define WL_SOCKET_READABLE
Definition: latch.h:125
char * ssl_cert_file
Definition: be-secure.c:42
int pgwin32_noblock
Definition: socket.c:28
WaitEventSet * FeBeWaitSet
Definition: pqcomm.c:186
char * ssl_crl_file
Definition: be-secure.c:45
#define recv(s, buf, len, flags)
Definition: win32_port.h:446
pgsocket sock
Definition: libpq-be.h:122
int be_tls_init(bool isServerStart)
void ResetLatch(Latch *latch)
Definition: latch.c:519
int ssl_min_protocol_version
Definition: be-secure.c:63
#define FATAL
Definition: elog.h:52
uint32 events
Definition: latch.h:144
char * SSLECDHCurve
Definition: be-secure.c:58
#define DEBUG2
Definition: elog.h:24
ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
char * SSLCipherSuites
Definition: be-secure.c:55
void be_tls_destroy(void)
ssize_t secure_write(Port *port, void *ptr, size_t len)
Definition: be-secure.c:259
#define ereport(elevel, rest)
Definition: elog.h:141
bool ssl_passphrase_command_supports_reload
Definition: be-secure.c:48
static int port
Definition: pg_regress.c:92
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
ssize_t be_gssapi_write(Port *port, void *ptr, size_t len)
void ProcessClientReadInterrupt(bool blocked)
Definition: postgres.c:530
char * ssl_ca_file
Definition: be-secure.c:44
int be_tls_open_server(Port *port)
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:235
#define Assert(condition)
Definition: c.h:732
void secure_close(Port *port)
Definition: be-secure.c:134
bool secure_loaded_verify_locations(void)
Definition: be-secure.c:102
char * ssl_dh_params_file
Definition: be-secure.c:46
int ssl_max_protocol_version
Definition: be-secure.c:64
void * gss
Definition: libpq-be.h:184
int errmsg(const char *fmt,...)
Definition: elog.c:784
int secure_open_server(Port *port)
Definition: be-secure.c:115
void be_tls_close(Port *port)
struct Latch * MyLatch
Definition: globals.c:54
#define EWOULDBLOCK
Definition: win32_port.h:338
char * ssl_passphrase_command
Definition: be-secure.c:47
#define WL_LATCH_SET
Definition: latch.h:124
char * ssl_key_file
Definition: be-secure.c:43
#define send(s, buf, len, flags)
Definition: win32_port.h:447
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
Definition: latch.c:953
bool SSLPreferServerCiphers
Definition: be-secure.c:61
ssize_t be_gssapi_read(Port *port, void *ptr, size_t len)
void ProcessClientWriteInterrupt(bool blocked)
Definition: postgres.c:576
void secure_destroy(void)
Definition: be-secure.c:91