1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * fe-secure.c |
4 | * functions related to setting up a secure connection to the backend. |
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/interfaces/libpq/fe-secure.c |
15 | * |
16 | * NOTES |
17 | * |
18 | * We don't provide informational callbacks here (like |
19 | * info_cb() in be-secure.c), since there's no good mechanism to |
20 | * display such information to the user. |
21 | * |
22 | *------------------------------------------------------------------------- |
23 | */ |
24 | |
25 | #include "postgres_fe.h" |
26 | |
27 | #include <signal.h> |
28 | #include <fcntl.h> |
29 | #include <ctype.h> |
30 | |
31 | #include "libpq-fe.h" |
32 | #include "fe-auth.h" |
33 | #include "libpq-int.h" |
34 | |
35 | #ifdef WIN32 |
36 | #include "win32.h" |
37 | #else |
38 | #include <sys/socket.h> |
39 | #include <unistd.h> |
40 | #include <netdb.h> |
41 | #include <netinet/in.h> |
42 | #ifdef HAVE_NETINET_TCP_H |
43 | #include <netinet/tcp.h> |
44 | #endif |
45 | #include <arpa/inet.h> |
46 | #endif |
47 | |
48 | #include <sys/stat.h> |
49 | |
50 | #ifdef ENABLE_THREAD_SAFETY |
51 | #ifdef WIN32 |
52 | #include "pthread-win32.h" |
53 | #else |
54 | #include <pthread.h> |
55 | #endif |
56 | #endif |
57 | |
58 | /* |
59 | * Macros to handle disabling and then restoring the state of SIGPIPE handling. |
60 | * On Windows, these are all no-ops since there's no SIGPIPEs. |
61 | */ |
62 | |
63 | #ifndef WIN32 |
64 | |
65 | #define SIGPIPE_MASKED(conn) ((conn)->sigpipe_so || (conn)->sigpipe_flag) |
66 | |
67 | #ifdef ENABLE_THREAD_SAFETY |
68 | |
69 | struct sigpipe_info |
70 | { |
71 | sigset_t oldsigmask; |
72 | bool sigpipe_pending; |
73 | bool got_epipe; |
74 | }; |
75 | |
76 | #define DECLARE_SIGPIPE_INFO(spinfo) struct sigpipe_info spinfo |
77 | |
78 | #define DISABLE_SIGPIPE(conn, spinfo, failaction) \ |
79 | do { \ |
80 | (spinfo).got_epipe = false; \ |
81 | if (!SIGPIPE_MASKED(conn)) \ |
82 | { \ |
83 | if (pq_block_sigpipe(&(spinfo).oldsigmask, \ |
84 | &(spinfo).sigpipe_pending) < 0) \ |
85 | failaction; \ |
86 | } \ |
87 | } while (0) |
88 | |
89 | #define REMEMBER_EPIPE(spinfo, cond) \ |
90 | do { \ |
91 | if (cond) \ |
92 | (spinfo).got_epipe = true; \ |
93 | } while (0) |
94 | |
95 | #define RESTORE_SIGPIPE(conn, spinfo) \ |
96 | do { \ |
97 | if (!SIGPIPE_MASKED(conn)) \ |
98 | pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \ |
99 | (spinfo).got_epipe); \ |
100 | } while (0) |
101 | #else /* !ENABLE_THREAD_SAFETY */ |
102 | |
103 | #define DECLARE_SIGPIPE_INFO(spinfo) pqsigfunc spinfo = NULL |
104 | |
105 | #define DISABLE_SIGPIPE(conn, spinfo, failaction) \ |
106 | do { \ |
107 | if (!SIGPIPE_MASKED(conn)) \ |
108 | spinfo = pqsignal(SIGPIPE, SIG_IGN); \ |
109 | } while (0) |
110 | |
111 | #define REMEMBER_EPIPE(spinfo, cond) |
112 | |
113 | #define RESTORE_SIGPIPE(conn, spinfo) \ |
114 | do { \ |
115 | if (!SIGPIPE_MASKED(conn)) \ |
116 | pqsignal(SIGPIPE, spinfo); \ |
117 | } while (0) |
118 | #endif /* ENABLE_THREAD_SAFETY */ |
119 | #else /* WIN32 */ |
120 | |
121 | #define DECLARE_SIGPIPE_INFO(spinfo) |
122 | #define DISABLE_SIGPIPE(conn, spinfo, failaction) |
123 | #define REMEMBER_EPIPE(spinfo, cond) |
124 | #define RESTORE_SIGPIPE(conn, spinfo) |
125 | #endif /* WIN32 */ |
126 | |
127 | /* ------------------------------------------------------------ */ |
128 | /* Procedures common to all secure sessions */ |
129 | /* ------------------------------------------------------------ */ |
130 | |
131 | |
132 | int |
133 | PQsslInUse(PGconn *conn) |
134 | { |
135 | if (!conn) |
136 | return 0; |
137 | return conn->ssl_in_use; |
138 | } |
139 | |
140 | /* |
141 | * Exported function to allow application to tell us it's already |
142 | * initialized OpenSSL. |
143 | */ |
144 | void |
145 | PQinitSSL(int do_init) |
146 | { |
147 | #ifdef USE_SSL |
148 | pgtls_init_library(do_init, do_init); |
149 | #endif |
150 | } |
151 | |
152 | /* |
153 | * Exported function to allow application to tell us it's already |
154 | * initialized OpenSSL and/or libcrypto. |
155 | */ |
156 | void |
157 | PQinitOpenSSL(int do_ssl, int do_crypto) |
158 | { |
159 | #ifdef USE_SSL |
160 | pgtls_init_library(do_ssl, do_crypto); |
161 | #endif |
162 | } |
163 | |
164 | /* |
165 | * Initialize global SSL context |
166 | */ |
167 | int |
168 | pqsecure_initialize(PGconn *conn) |
169 | { |
170 | int r = 0; |
171 | |
172 | #ifdef USE_SSL |
173 | r = pgtls_init(conn); |
174 | #endif |
175 | |
176 | return r; |
177 | } |
178 | |
179 | /* |
180 | * Begin or continue negotiating a secure session. |
181 | */ |
182 | PostgresPollingStatusType |
183 | pqsecure_open_client(PGconn *conn) |
184 | { |
185 | #ifdef USE_SSL |
186 | return pgtls_open_client(conn); |
187 | #else |
188 | /* shouldn't get here */ |
189 | return PGRES_POLLING_FAILED; |
190 | #endif |
191 | } |
192 | |
193 | /* |
194 | * Close secure session. |
195 | */ |
196 | void |
197 | pqsecure_close(PGconn *conn) |
198 | { |
199 | #ifdef USE_SSL |
200 | if (conn->ssl_in_use) |
201 | pgtls_close(conn); |
202 | #endif |
203 | } |
204 | |
205 | /* |
206 | * Read data from a secure connection. |
207 | * |
208 | * On failure, this function is responsible for putting a suitable message |
209 | * into conn->errorMessage. The caller must still inspect errno, but only |
210 | * to determine whether to continue/retry after error. |
211 | */ |
212 | ssize_t |
213 | pqsecure_read(PGconn *conn, void *ptr, size_t len) |
214 | { |
215 | ssize_t n; |
216 | |
217 | #ifdef USE_SSL |
218 | if (conn->ssl_in_use) |
219 | { |
220 | n = pgtls_read(conn, ptr, len); |
221 | } |
222 | else |
223 | #endif |
224 | #ifdef ENABLE_GSS |
225 | if (conn->gssenc) |
226 | { |
227 | n = pg_GSS_read(conn, ptr, len); |
228 | } |
229 | else |
230 | #endif |
231 | { |
232 | n = pqsecure_raw_read(conn, ptr, len); |
233 | } |
234 | |
235 | return n; |
236 | } |
237 | |
238 | ssize_t |
239 | pqsecure_raw_read(PGconn *conn, void *ptr, size_t len) |
240 | { |
241 | ssize_t n; |
242 | int result_errno = 0; |
243 | char sebuf[PG_STRERROR_R_BUFLEN]; |
244 | |
245 | n = recv(conn->sock, ptr, len, 0); |
246 | |
247 | if (n < 0) |
248 | { |
249 | result_errno = SOCK_ERRNO; |
250 | |
251 | /* Set error message if appropriate */ |
252 | switch (result_errno) |
253 | { |
254 | #ifdef EAGAIN |
255 | case EAGAIN: |
256 | #endif |
257 | #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) |
258 | case EWOULDBLOCK: |
259 | #endif |
260 | case EINTR: |
261 | /* no error message, caller is expected to retry */ |
262 | break; |
263 | |
264 | #ifdef ECONNRESET |
265 | case ECONNRESET: |
266 | printfPQExpBuffer(&conn->errorMessage, |
267 | libpq_gettext( |
268 | "server closed the connection unexpectedly\n" |
269 | "\tThis probably means the server terminated abnormally\n" |
270 | "\tbefore or while processing the request.\n" )); |
271 | break; |
272 | #endif |
273 | |
274 | default: |
275 | printfPQExpBuffer(&conn->errorMessage, |
276 | libpq_gettext("could not receive data from server: %s\n" ), |
277 | SOCK_STRERROR(result_errno, |
278 | sebuf, sizeof(sebuf))); |
279 | break; |
280 | } |
281 | } |
282 | |
283 | /* ensure we return the intended errno to caller */ |
284 | SOCK_ERRNO_SET(result_errno); |
285 | |
286 | return n; |
287 | } |
288 | |
289 | /* |
290 | * Write data to a secure connection. |
291 | * |
292 | * On failure, this function is responsible for putting a suitable message |
293 | * into conn->errorMessage. The caller must still inspect errno, but only |
294 | * to determine whether to continue/retry after error. |
295 | */ |
296 | ssize_t |
297 | pqsecure_write(PGconn *conn, const void *ptr, size_t len) |
298 | { |
299 | ssize_t n; |
300 | |
301 | #ifdef USE_SSL |
302 | if (conn->ssl_in_use) |
303 | { |
304 | n = pgtls_write(conn, ptr, len); |
305 | } |
306 | else |
307 | #endif |
308 | #ifdef ENABLE_GSS |
309 | if (conn->gssenc) |
310 | { |
311 | n = pg_GSS_write(conn, ptr, len); |
312 | } |
313 | else |
314 | #endif |
315 | { |
316 | n = pqsecure_raw_write(conn, ptr, len); |
317 | } |
318 | |
319 | return n; |
320 | } |
321 | |
322 | ssize_t |
323 | pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len) |
324 | { |
325 | ssize_t n; |
326 | int flags = 0; |
327 | int result_errno = 0; |
328 | char sebuf[PG_STRERROR_R_BUFLEN]; |
329 | |
330 | DECLARE_SIGPIPE_INFO(spinfo); |
331 | |
332 | #ifdef MSG_NOSIGNAL |
333 | if (conn->sigpipe_flag) |
334 | flags |= MSG_NOSIGNAL; |
335 | |
336 | retry_masked: |
337 | #endif /* MSG_NOSIGNAL */ |
338 | |
339 | DISABLE_SIGPIPE(conn, spinfo, return -1); |
340 | |
341 | n = send(conn->sock, ptr, len, flags); |
342 | |
343 | if (n < 0) |
344 | { |
345 | result_errno = SOCK_ERRNO; |
346 | |
347 | /* |
348 | * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available |
349 | * on this machine. So, clear sigpipe_flag so we don't try the flag |
350 | * again, and retry the send(). |
351 | */ |
352 | #ifdef MSG_NOSIGNAL |
353 | if (flags != 0 && result_errno == EINVAL) |
354 | { |
355 | conn->sigpipe_flag = false; |
356 | flags = 0; |
357 | goto retry_masked; |
358 | } |
359 | #endif /* MSG_NOSIGNAL */ |
360 | |
361 | /* Set error message if appropriate */ |
362 | switch (result_errno) |
363 | { |
364 | #ifdef EAGAIN |
365 | case EAGAIN: |
366 | #endif |
367 | #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) |
368 | case EWOULDBLOCK: |
369 | #endif |
370 | case EINTR: |
371 | /* no error message, caller is expected to retry */ |
372 | break; |
373 | |
374 | case EPIPE: |
375 | /* Set flag for EPIPE */ |
376 | REMEMBER_EPIPE(spinfo, true); |
377 | |
378 | #ifdef ECONNRESET |
379 | /* FALL THRU */ |
380 | |
381 | case ECONNRESET: |
382 | #endif |
383 | printfPQExpBuffer(&conn->errorMessage, |
384 | libpq_gettext( |
385 | "server closed the connection unexpectedly\n" |
386 | "\tThis probably means the server terminated abnormally\n" |
387 | "\tbefore or while processing the request.\n" )); |
388 | break; |
389 | |
390 | default: |
391 | printfPQExpBuffer(&conn->errorMessage, |
392 | libpq_gettext("could not send data to server: %s\n" ), |
393 | SOCK_STRERROR(result_errno, |
394 | sebuf, sizeof(sebuf))); |
395 | break; |
396 | } |
397 | } |
398 | |
399 | RESTORE_SIGPIPE(conn, spinfo); |
400 | |
401 | /* ensure we return the intended errno to caller */ |
402 | SOCK_ERRNO_SET(result_errno); |
403 | |
404 | return n; |
405 | } |
406 | |
407 | /* Dummy versions of SSL info functions, when built without SSL support */ |
408 | #ifndef USE_SSL |
409 | |
410 | void * |
411 | PQgetssl(PGconn *conn) |
412 | { |
413 | return NULL; |
414 | } |
415 | |
416 | void * |
417 | PQsslStruct(PGconn *conn, const char *struct_name) |
418 | { |
419 | return NULL; |
420 | } |
421 | |
422 | const char * |
423 | PQsslAttribute(PGconn *conn, const char *attribute_name) |
424 | { |
425 | return NULL; |
426 | } |
427 | |
428 | const char *const * |
429 | PQsslAttributeNames(PGconn *conn) |
430 | { |
431 | static const char *const result[] = {NULL}; |
432 | |
433 | return result; |
434 | } |
435 | #endif /* USE_SSL */ |
436 | |
437 | /* Dummy version of GSSAPI information functions, when built without GSS support */ |
438 | #ifndef ENABLE_GSS |
439 | |
440 | void * |
441 | PQgetgssctx(PGconn *conn) |
442 | { |
443 | return NULL; |
444 | } |
445 | |
446 | int |
447 | PQgssEncInUse(PGconn *conn) |
448 | { |
449 | return 0; |
450 | } |
451 | |
452 | #endif /* ENABLE_GSS */ |
453 | |
454 | |
455 | #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) |
456 | |
457 | /* |
458 | * Block SIGPIPE for this thread. This prevents send()/write() from exiting |
459 | * the application. |
460 | */ |
461 | int |
462 | pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending) |
463 | { |
464 | sigset_t sigpipe_sigset; |
465 | sigset_t sigset; |
466 | |
467 | sigemptyset(&sigpipe_sigset); |
468 | sigaddset(&sigpipe_sigset, SIGPIPE); |
469 | |
470 | /* Block SIGPIPE and save previous mask for later reset */ |
471 | SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset)); |
472 | if (SOCK_ERRNO) |
473 | return -1; |
474 | |
475 | /* We can have a pending SIGPIPE only if it was blocked before */ |
476 | if (sigismember(osigset, SIGPIPE)) |
477 | { |
478 | /* Is there a pending SIGPIPE? */ |
479 | if (sigpending(&sigset) != 0) |
480 | return -1; |
481 | |
482 | if (sigismember(&sigset, SIGPIPE)) |
483 | *sigpipe_pending = true; |
484 | else |
485 | *sigpipe_pending = false; |
486 | } |
487 | else |
488 | *sigpipe_pending = false; |
489 | |
490 | return 0; |
491 | } |
492 | |
493 | /* |
494 | * Discard any pending SIGPIPE and reset the signal mask. |
495 | * |
496 | * Note: we are effectively assuming here that the C library doesn't queue |
497 | * up multiple SIGPIPE events. If it did, then we'd accidentally leave |
498 | * ours in the queue when an event was already pending and we got another. |
499 | * As long as it doesn't queue multiple events, we're OK because the caller |
500 | * can't tell the difference. |
501 | * |
502 | * The caller should say got_epipe = false if it is certain that it |
503 | * didn't get an EPIPE error; in that case we'll skip the clear operation |
504 | * and things are definitely OK, queuing or no. If it got one or might have |
505 | * gotten one, pass got_epipe = true. |
506 | * |
507 | * We do not want this to change errno, since if it did that could lose |
508 | * the error code from a preceding send(). We essentially assume that if |
509 | * we were able to do pq_block_sigpipe(), this can't fail. |
510 | */ |
511 | void |
512 | pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe) |
513 | { |
514 | int save_errno = SOCK_ERRNO; |
515 | int signo; |
516 | sigset_t sigset; |
517 | |
518 | /* Clear SIGPIPE only if none was pending */ |
519 | if (got_epipe && !sigpipe_pending) |
520 | { |
521 | if (sigpending(&sigset) == 0 && |
522 | sigismember(&sigset, SIGPIPE)) |
523 | { |
524 | sigset_t sigpipe_sigset; |
525 | |
526 | sigemptyset(&sigpipe_sigset); |
527 | sigaddset(&sigpipe_sigset, SIGPIPE); |
528 | |
529 | sigwait(&sigpipe_sigset, &signo); |
530 | } |
531 | } |
532 | |
533 | /* Restore saved block mask */ |
534 | pthread_sigmask(SIG_SETMASK, osigset, NULL); |
535 | |
536 | SOCK_ERRNO_SET(save_errno); |
537 | } |
538 | |
539 | #endif /* ENABLE_THREAD_SAFETY && !WIN32 */ |
540 | |