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