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 | |
41 | char *ssl_library; |
42 | char *ssl_cert_file; |
43 | char *ssl_key_file; |
44 | char *ssl_ca_file; |
45 | char *ssl_crl_file; |
46 | char *ssl_dh_params_file; |
47 | char *ssl_passphrase_command; |
48 | bool ssl_passphrase_command_supports_reload; |
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. */ |
58 | char *SSLECDHCurve; |
59 | |
60 | /* GUC variable: if false, prefer client ciphers */ |
61 | bool SSLPreferServerCiphers; |
62 | |
63 | int ssl_min_protocol_version; |
64 | int ssl_max_protocol_version; |
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 |
91 | secure_destroy(void) |
92 | { |
93 | #ifdef USE_SSL |
94 | be_tls_destroy(); |
95 | #endif |
96 | } |
97 | |
98 | /* |
99 | * Indicate if we have loaded the root CA store to verify certificates |
100 | */ |
101 | bool |
102 | secure_loaded_verify_locations(void) |
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 |
115 | secure_open_server(Port *port) |
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 |
134 | secure_close(Port *port) |
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. */ |
152 | ProcessClientReadInterrupt(false); |
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, |
186 | WAIT_EVENT_CLIENT_READ); |
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 | { |
213 | ResetLatch(MyLatch); |
214 | ProcessClientReadInterrupt(true); |
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 | */ |
229 | ProcessClientReadInterrupt(false); |
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. */ |
265 | ProcessClientWriteInterrupt(false); |
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, |
298 | WAIT_EVENT_CLIENT_WRITE); |
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 | { |
309 | ResetLatch(MyLatch); |
310 | ProcessClientWriteInterrupt(true); |
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 | */ |
325 | ProcessClientWriteInterrupt(false); |
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 | } |
345 | |