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-2016, 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 "tcop/tcopprot.h"
37 #include "utils/memutils.h"
38 #include "storage/ipc.h"
39 #include "storage/proc.h"
40
41
42 char *ssl_cert_file;
43 char *ssl_key_file;
44 char *ssl_ca_file;
45 char *ssl_crl_file;
46
47 #ifdef USE_SSL
48 bool ssl_loaded_verify_locations = false;
49 #endif
50
51 /* GUC variable controlling SSL cipher list */
52 char *SSLCipherSuites = NULL;
53
54 /* GUC variable for default ECHD curve. */
55 char *SSLECDHCurve;
56
57 /* GUC variable: if false, prefer client ciphers */
58 bool SSLPreferServerCiphers;
59
60 /* ------------------------------------------------------------ */
61 /* Procedures common to all secure sessions */
62 /* ------------------------------------------------------------ */
63
64 /*
65 * Initialize global context
66 */
67 int
secure_initialize(void)68 secure_initialize(void)
69 {
70 #ifdef USE_SSL
71 be_tls_init();
72 #endif
73
74 return 0;
75 }
76
77 /*
78 * Indicate if we have loaded the root CA store to verify certificates
79 */
80 bool
secure_loaded_verify_locations(void)81 secure_loaded_verify_locations(void)
82 {
83 #ifdef USE_SSL
84 return ssl_loaded_verify_locations;
85 #else
86 return false;
87 #endif
88 }
89
90 /*
91 * Attempt to negotiate secure session.
92 */
93 int
secure_open_server(Port * port)94 secure_open_server(Port *port)
95 {
96 int r = 0;
97
98 #ifdef USE_SSL
99 r = be_tls_open_server(port);
100 #endif
101
102 return r;
103 }
104
105 /*
106 * Close secure session.
107 */
108 void
secure_close(Port * port)109 secure_close(Port *port)
110 {
111 #ifdef USE_SSL
112 if (port->ssl_in_use)
113 be_tls_close(port);
114 #endif
115 }
116
117 /*
118 * Read data from a secure connection.
119 */
120 ssize_t
secure_read(Port * port,void * ptr,size_t len)121 secure_read(Port *port, void *ptr, size_t len)
122 {
123 ssize_t n;
124 int waitfor;
125
126 /* Deal with any already-pending interrupt condition. */
127 ProcessClientReadInterrupt(false);
128
129 retry:
130 #ifdef USE_SSL
131 waitfor = 0;
132 if (port->ssl_in_use)
133 {
134 n = be_tls_read(port, ptr, len, &waitfor);
135 }
136 else
137 #endif
138 {
139 n = secure_raw_read(port, ptr, len);
140 waitfor = WL_SOCKET_READABLE;
141 }
142
143 /* In blocking mode, wait until the socket is ready */
144 if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
145 {
146 WaitEvent event;
147
148 Assert(waitfor);
149
150 ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
151
152 WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1);
153
154 /*
155 * If the postmaster has died, it's not safe to continue running,
156 * because it is the postmaster's job to kill us if some other backend
157 * exists uncleanly. Moreover, we won't run very well in this state;
158 * helper processes like walwriter and the bgwriter will exit, so
159 * performance may be poor. Finally, if we don't exit, pg_ctl will be
160 * unable to restart the postmaster without manual intervention, so no
161 * new connections can be accepted. Exiting clears the deck for a
162 * postmaster restart.
163 *
164 * (Note that we only make this check when we would otherwise sleep on
165 * our latch. We might still continue running for a while if the
166 * postmaster is killed in mid-query, or even through multiple queries
167 * if we never have to wait for read. We don't want to burn too many
168 * cycles checking for this very rare condition, and this should cause
169 * us to exit quickly in most cases.)
170 */
171 if (event.events & WL_POSTMASTER_DEATH)
172 ereport(FATAL,
173 (errcode(ERRCODE_ADMIN_SHUTDOWN),
174 errmsg("terminating connection due to unexpected postmaster exit")));
175
176 /* Handle interrupt. */
177 if (event.events & WL_LATCH_SET)
178 {
179 ResetLatch(MyLatch);
180 ProcessClientReadInterrupt(true);
181
182 /*
183 * We'll retry the read. Most likely it will return immediately
184 * because there's still no data available, and we'll wait for the
185 * socket to become ready again.
186 */
187 }
188 goto retry;
189 }
190
191 /*
192 * Process interrupts that happened during a successful (or non-blocking,
193 * or hard-failed) read.
194 */
195 ProcessClientReadInterrupt(false);
196
197 return n;
198 }
199
200 ssize_t
secure_raw_read(Port * port,void * ptr,size_t len)201 secure_raw_read(Port *port, void *ptr, size_t len)
202 {
203 ssize_t n;
204
205 /*
206 * Try to read from the socket without blocking. If it succeeds we're
207 * done, otherwise we'll wait for the socket using the latch mechanism.
208 */
209 #ifdef WIN32
210 pgwin32_noblock = true;
211 #endif
212 n = recv(port->sock, ptr, len, 0);
213 #ifdef WIN32
214 pgwin32_noblock = false;
215 #endif
216
217 return n;
218 }
219
220
221 /*
222 * Write data to a secure connection.
223 */
224 ssize_t
secure_write(Port * port,void * ptr,size_t len)225 secure_write(Port *port, void *ptr, size_t len)
226 {
227 ssize_t n;
228 int waitfor;
229
230 /* Deal with any already-pending interrupt condition. */
231 ProcessClientWriteInterrupt(false);
232
233 retry:
234 waitfor = 0;
235 #ifdef USE_SSL
236 if (port->ssl_in_use)
237 {
238 n = be_tls_write(port, ptr, len, &waitfor);
239 }
240 else
241 #endif
242 {
243 n = secure_raw_write(port, ptr, len);
244 waitfor = WL_SOCKET_WRITEABLE;
245 }
246
247 if (n < 0 && !port->noblock && (errno == EWOULDBLOCK || errno == EAGAIN))
248 {
249 WaitEvent event;
250
251 Assert(waitfor);
252
253 ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
254
255 WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1);
256
257 /* See comments in secure_read. */
258 if (event.events & WL_POSTMASTER_DEATH)
259 ereport(FATAL,
260 (errcode(ERRCODE_ADMIN_SHUTDOWN),
261 errmsg("terminating connection due to unexpected postmaster exit")));
262
263 /* Handle interrupt. */
264 if (event.events & WL_LATCH_SET)
265 {
266 ResetLatch(MyLatch);
267 ProcessClientWriteInterrupt(true);
268
269 /*
270 * We'll retry the write. Most likely it will return immediately
271 * because there's still no buffer space available, and we'll wait
272 * for the socket to become ready again.
273 */
274 }
275 goto retry;
276 }
277
278 /*
279 * Process interrupts that happened during a successful (or non-blocking,
280 * or hard-failed) write.
281 */
282 ProcessClientWriteInterrupt(false);
283
284 return n;
285 }
286
287 ssize_t
secure_raw_write(Port * port,const void * ptr,size_t len)288 secure_raw_write(Port *port, const void *ptr, size_t len)
289 {
290 ssize_t n;
291
292 #ifdef WIN32
293 pgwin32_noblock = true;
294 #endif
295 n = send(port->sock, ptr, len, 0);
296 #ifdef WIN32
297 pgwin32_noblock = false;
298 #endif
299
300 return n;
301 }
302