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 "storage/ipc.h"
36 #include "storage/proc.h"
37 #include "tcop/tcopprot.h"
38 #include "utils/memutils.h"
39 
48 
49 #ifdef USE_SSL
50 bool ssl_loaded_verify_locations = false;
51 #endif
52 
53 /* GUC variable controlling SSL cipher list */
54 char *SSLCipherSuites = NULL;
55 
56 /* GUC variable for default ECHD curve. */
58 
59 /* GUC variable: if false, prefer client ciphers */
61 
64 
65 /* ------------------------------------------------------------ */
66 /* Procedures common to all secure sessions */
67 /* ------------------------------------------------------------ */
68 
69 /*
70  * Initialize global context.
71  *
72  * If isServerStart is true, report any errors as FATAL (so we don't return).
73  * Otherwise, log errors at LOG level and return -1 to indicate trouble,
74  * preserving the old SSL state if any. Returns 0 if OK.
75  */
76 int
77 secure_initialize(bool isServerStart)
78 {
79 #ifdef USE_SSL
80  return be_tls_init(isServerStart);
81 #else
82  return 0;
83 #endif
84 }
85 
86 /*
87  * Destroy global context, if any.
88  */
89 void
91 {
92 #ifdef USE_SSL
94 #endif
95 }
96 
97 /*
98  * Indicate if we have loaded the root CA store to verify certificates
99  */
100 bool
102 {
103 #ifdef USE_SSL
104  return ssl_loaded_verify_locations;
105 #else
106  return false;
107 #endif
108 }
109 
110 /*
111  * Attempt to negotiate secure session.
112  */
113 int
115 {
116  int r = 0;
117 
118 #ifdef USE_SSL
119  r = be_tls_open_server(port);
120 
121  ereport(DEBUG2,
122  (errmsg("SSL connection from \"%s\"",
123  port->peer_cn ? port->peer_cn : "(anonymous)")));
124 #endif
125 
126  return r;
127 }
128 
129 /*
130  * Close secure session.
131  */
132 void
134 {
135 #ifdef USE_SSL
136  if (port->ssl_in_use)
137  be_tls_close(port);
138 #endif
139 }
140 
141 /*
142  * Read data from a secure connection.
143  */
144 ssize_t
145 secure_read(Port *port, void *ptr, size_t len)
146 {
147  ssize_t n;
148  int waitfor;
149 
150  /* Deal with any already-pending interrupt condition. */
152 
153 retry:
154 #ifdef USE_SSL
155  waitfor = 0;
156  if (port->ssl_in_use)
157  {
158  n = be_tls_read(port, ptr, len, &waitfor);
159  }
160  else
161 #endif
162 #ifdef ENABLE_GSS
163  if (port->gss->enc)
164  {
165  n = be_gssapi_read(port, ptr, len);
166  waitfor = WL_SOCKET_READABLE;
167  }
168  else
169 #endif
170  {
171  n = secure_raw_read(port, ptr, len);
172  waitfor = WL_SOCKET_READABLE;
173  }
174 
175  /* In blocking mode, wait until the socket is ready */
176  if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
177  {
178  WaitEvent event;
179 
180  Assert(waitfor);
181 
182  ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
183 
184  WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
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
202  * us to exit quickly in most cases.)
203  */
204  if (event.events & WL_POSTMASTER_DEATH)
205  ereport(FATAL,
206  (errcode(ERRCODE_ADMIN_SHUTDOWN),
207  errmsg("terminating connection due to unexpected postmaster exit")));
208 
209  /* Handle interrupt. */
210  if (event.events & WL_LATCH_SET)
211  {
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.
219  */
220  }
221  goto retry;
222  }
223 
224  /*
225  * Process interrupts that happened during a successful (or non-blocking,
226  * or hard-failed) read.
227  */
229 
230  return n;
231 }
232 
233 ssize_t
234 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
243  pgwin32_noblock = true;
244 #endif
245  n = recv(port->sock, ptr, len, 0);
246 #ifdef WIN32
247  pgwin32_noblock = false;
248 #endif
249 
250  return n;
251 }
252 
253 
254 /*
255  * Write data to a secure connection.
256  */
257 ssize_t
258 secure_write(Port *port, void *ptr, size_t len)
259 {
260  ssize_t n;
261  int waitfor;
262 
263  /* Deal with any already-pending interrupt condition. */
265 
266 retry:
267  waitfor = 0;
268 #ifdef USE_SSL
269  if (port->ssl_in_use)
270  {
271  n = be_tls_write(port, ptr, len, &waitfor);
272  }
273  else
274 #endif
275 #ifdef ENABLE_GSS
276  if (port->gss->enc)
277  {
278  n = be_gssapi_write(port, ptr, len);
279  waitfor = WL_SOCKET_WRITEABLE;
280  }
281  else
282 #endif
283  {
284  n = secure_raw_write(port, ptr, len);
285  waitfor = WL_SOCKET_WRITEABLE;
286  }
287 
288  if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
289  {
290  WaitEvent event;
291 
292  Assert(waitfor);
293 
294  ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
295 
296  WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
298 
299  /* See comments in secure_read. */
300  if (event.events & WL_POSTMASTER_DEATH)
301  ereport(FATAL,
302  (errcode(ERRCODE_ADMIN_SHUTDOWN),
303  errmsg("terminating connection due to unexpected postmaster exit")));
304 
305  /* Handle interrupt. */
306  if (event.events & WL_LATCH_SET)
307  {
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.
315  */
316  }
317  goto retry;
318  }
319 
320  /*
321  * Process interrupts that happened during a successful (or non-blocking,
322  * or hard-failed) write.
323  */
325 
326  return n;
327 }
328 
329 ssize_t
330 secure_raw_write(Port *port, const void *ptr, size_t len)
331 {
332  ssize_t n;
333 
334 #ifdef WIN32
335  pgwin32_noblock = true;
336 #endif
337  n = send(port->sock, ptr, len, 0);
338 #ifdef WIN32
339  pgwin32_noblock = false;
340 #endif
341 
342  return n;
343 }
int secure_initialize(bool isServerStart)
Definition: be-secure.c:77
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:321
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:330
int errcode(int sqlerrcode)
Definition: elog.c:608
char * ssl_library
Definition: be-secure.c:40
Definition: libpq-be.h:120
ssize_t secure_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:145
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:41
int pgwin32_noblock
Definition: socket.c:28
WaitEventSet * FeBeWaitSet
Definition: pqcomm.c:186
char * ssl_crl_file
Definition: be-secure.c:44
#define recv(s, buf, len, flags)
Definition: win32_port.h:437
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:62
#define FATAL
Definition: elog.h:52
uint32 events
Definition: latch.h:144
char * SSLECDHCurve
Definition: be-secure.c:57
#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:54
void be_tls_destroy(void)
ssize_t secure_write(Port *port, void *ptr, size_t len)
Definition: be-secure.c:258
#define ereport(elevel, rest)
Definition: elog.h:141
bool ssl_passphrase_command_supports_reload
Definition: be-secure.c:47
static int port
Definition: pg_regress.c:91
#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:525
char * ssl_ca_file
Definition: be-secure.c:43
int be_tls_open_server(Port *port)
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:234
#define Assert(condition)
Definition: c.h:739
void secure_close(Port *port)
Definition: be-secure.c:133
bool secure_loaded_verify_locations(void)
Definition: be-secure.c:101
char * ssl_dh_params_file
Definition: be-secure.c:45
int ssl_max_protocol_version
Definition: be-secure.c:63
void * gss
Definition: libpq-be.h:184
int errmsg(const char *fmt,...)
Definition: elog.c:822
int secure_open_server(Port *port)
Definition: be-secure.c:114
void be_tls_close(Port *port)
struct Latch * MyLatch
Definition: globals.c:54
#define EWOULDBLOCK
Definition: win32_port.h:329
char * ssl_passphrase_command
Definition: be-secure.c:46
#define WL_LATCH_SET
Definition: latch.h:124
char * ssl_key_file
Definition: be-secure.c:42
#define send(s, buf, len, flags)
Definition: win32_port.h:438
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:60
ssize_t be_gssapi_read(Port *port, void *ptr, size_t len)
void ProcessClientWriteInterrupt(bool blocked)
Definition: postgres.c:571
void secure_destroy(void)
Definition: be-secure.c:90