PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2017, 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 <sys/stat.h>
22 #include <signal.h>
23 #include <fcntl.h>
24 #include <ctype.h>
25 #include <sys/socket.h>
26 #include <unistd.h>
27 #include <netdb.h>
28 #include <netinet/in.h>
29 #ifdef HAVE_NETINET_TCP_H
30 #include <netinet/tcp.h>
31 #include <arpa/inet.h>
32 #endif
33 
34 #include "libpq/libpq.h"
35 #include "miscadmin.h"
36 #include "pgstat.h"
37 #include "tcop/tcopprot.h"
38 #include "utils/memutils.h"
39 #include "storage/ipc.h"
40 #include "storage/proc.h"
41 
42 
47 
48 #ifdef USE_SSL
49 bool ssl_loaded_verify_locations = false;
50 #endif
51 
52 /* GUC variable controlling SSL cipher list */
54 
55 /* GUC variable for default ECHD curve. */
57 
58 /* GUC variable: if false, prefer client ciphers */
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
101 #else
102  return false;
103 #endif
104 }
105 
106 /*
107  * Attempt to negotiate secure session.
108  */
109 int
111 {
112  int r = 0;
113 
114 #ifdef USE_SSL
115  r = be_tls_open_server(port);
116 #endif
117 
118  return r;
119 }
120 
121 /*
122  * Close secure session.
123  */
124 void
126 {
127 #ifdef USE_SSL
128  if (port->ssl_in_use)
129  be_tls_close(port);
130 #endif
131 }
132 
133 /*
134  * Read data from a secure connection.
135  */
136 ssize_t
137 secure_read(Port *port, void *ptr, size_t len)
138 {
139  ssize_t n;
140  int waitfor;
141 
142 retry:
143 #ifdef USE_SSL
144  waitfor = 0;
145  if (port->ssl_in_use)
146  {
147  n = be_tls_read(port, ptr, len, &waitfor);
148  }
149  else
150 #endif
151  {
152  n = secure_raw_read(port, ptr, len);
153  waitfor = WL_SOCKET_READABLE;
154  }
155 
156  /* In blocking mode, wait until the socket is ready */
157  if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
158  {
159  WaitEvent event;
160 
161  Assert(waitfor);
162 
163  ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
164 
165  WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
167 
168  /*
169  * If the postmaster has died, it's not safe to continue running,
170  * because it is the postmaster's job to kill us if some other backend
171  * exists uncleanly. Moreover, we won't run very well in this state;
172  * helper processes like walwriter and the bgwriter will exit, so
173  * performance may be poor. Finally, if we don't exit, pg_ctl will be
174  * unable to restart the postmaster without manual intervention, so no
175  * new connections can be accepted. Exiting clears the deck for a
176  * postmaster restart.
177  *
178  * (Note that we only make this check when we would otherwise sleep on
179  * our latch. We might still continue running for a while if the
180  * postmaster is killed in mid-query, or even through multiple queries
181  * if we never have to wait for read. We don't want to burn too many
182  * cycles checking for this very rare condition, and this should cause
183  * us to exit quickly in most cases.)
184  */
185  if (event.events & WL_POSTMASTER_DEATH)
186  ereport(FATAL,
187  (errcode(ERRCODE_ADMIN_SHUTDOWN),
188  errmsg("terminating connection due to unexpected postmaster exit")));
189 
190  /* Handle interrupt. */
191  if (event.events & WL_LATCH_SET)
192  {
195 
196  /*
197  * We'll retry the read. Most likely it will return immediately
198  * because there's still no data available, and we'll wait for the
199  * socket to become ready again.
200  */
201  }
202  goto retry;
203  }
204 
205  /*
206  * Process interrupts that happened while (or before) receiving. Note that
207  * we signal that we're not blocking, which will prevent some types of
208  * interrupts from being processed.
209  */
211 
212  return n;
213 }
214 
215 ssize_t
216 secure_raw_read(Port *port, void *ptr, size_t len)
217 {
218  ssize_t n;
219 
220  /*
221  * Try to read from the socket without blocking. If it succeeds we're
222  * done, otherwise we'll wait for the socket using the latch mechanism.
223  */
224 #ifdef WIN32
225  pgwin32_noblock = true;
226 #endif
227  n = recv(port->sock, ptr, len, 0);
228 #ifdef WIN32
229  pgwin32_noblock = false;
230 #endif
231 
232  return n;
233 }
234 
235 
236 /*
237  * Write data to a secure connection.
238  */
239 ssize_t
240 secure_write(Port *port, void *ptr, size_t len)
241 {
242  ssize_t n;
243  int waitfor;
244 
245 retry:
246  waitfor = 0;
247 #ifdef USE_SSL
248  if (port->ssl_in_use)
249  {
250  n = be_tls_write(port, ptr, len, &waitfor);
251  }
252  else
253 #endif
254  {
255  n = secure_raw_write(port, ptr, len);
256  waitfor = WL_SOCKET_WRITEABLE;
257  }
258 
259  if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
260  {
261  WaitEvent event;
262 
263  Assert(waitfor);
264 
265  ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
266 
267  WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
269 
270  /* See comments in secure_read. */
271  if (event.events & WL_POSTMASTER_DEATH)
272  ereport(FATAL,
273  (errcode(ERRCODE_ADMIN_SHUTDOWN),
274  errmsg("terminating connection due to unexpected postmaster exit")));
275 
276  /* Handle interrupt. */
277  if (event.events & WL_LATCH_SET)
278  {
281 
282  /*
283  * We'll retry the write. Most likely it will return immediately
284  * because there's still no data available, and we'll wait for the
285  * socket to become ready again.
286  */
287  }
288  goto retry;
289  }
290 
291  /*
292  * Process interrupts that happened while (or before) sending. Note that
293  * we signal that we're not blocking, which will prevent some types of
294  * interrupts from being processed.
295  */
297 
298  return n;
299 }
300 
301 ssize_t
302 secure_raw_write(Port *port, const void *ptr, size_t len)
303 {
304  ssize_t n;
305 
306 #ifdef WIN32
307  pgwin32_noblock = true;
308 #endif
309  n = send(port->sock, ptr, len, 0);
310 #ifdef WIN32
311  pgwin32_noblock = false;
312 #endif
313 
314  return n;
315 }
#define send(s, buf, len, flags)
Definition: win32.h:376
int secure_initialize(bool isServerStart)
Definition: be-secure.c:73
#define EWOULDBLOCK
Definition: win32.h:291
ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
#define WL_SOCKET_WRITEABLE
Definition: latch.h:126
bool ssl_loaded_verify_locations
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:302
int errcode(int sqlerrcode)
Definition: elog.c:575
Definition: libpq-be.h:116
ssize_t secure_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:137
void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
Definition: latch.c:672
bool ssl_in_use
Definition: libpq-be.h:181
#define WL_SOCKET_READABLE
Definition: latch.h:125
char * ssl_cert_file
Definition: be-secure.c:43
int pgwin32_noblock
Definition: socket.c:28
WaitEventSet * FeBeWaitSet
Definition: pqcomm.c:167
#define recv(s, buf, len, flags)
Definition: win32.h:375
void ResetLatch(volatile Latch *latch)
Definition: latch.c:450
char * ssl_crl_file
Definition: be-secure.c:46
pgsocket sock
Definition: libpq-be.h:118
int be_tls_init(bool isServerStart)
#define EAGAIN
Definition: win32.h:283
#define FATAL
Definition: elog.h:52
uint32 events
Definition: latch.h:133
char * SSLECDHCurve
Definition: be-secure.c:56
ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
char * SSLCipherSuites
Definition: be-secure.c:53
void be_tls_destroy(void)
ssize_t secure_write(Port *port, void *ptr, size_t len)
Definition: be-secure.c:240
#define ereport(elevel, rest)
Definition: elog.h:122
static int port
Definition: pg_regress.c:89
#define WL_POSTMASTER_DEATH
Definition: latch.h:128
void ProcessClientReadInterrupt(bool blocked)
Definition: postgres.c:522
char * ssl_ca_file
Definition: be-secure.c:45
int be_tls_open_server(Port *port)
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:216
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
void secure_close(Port *port)
Definition: be-secure.c:125
bool secure_loaded_verify_locations(void)
Definition: be-secure.c:97
int errmsg(const char *fmt,...)
Definition: elog.c:797
int secure_open_server(Port *port)
Definition: be-secure.c:110
void be_tls_close(Port *port)
struct Latch * MyLatch
Definition: globals.c:51
#define WL_LATCH_SET
Definition: latch.h:124
char * ssl_key_file
Definition: be-secure.c:44
int WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent *occurred_events, int nevents, uint32 wait_event_info)
Definition: latch.c:855
bool SSLPreferServerCiphers
Definition: be-secure.c:59
void ProcessClientWriteInterrupt(bool blocked)
Definition: postgres.c:560
void secure_destroy(void)
Definition: be-secure.c:86