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
69struct 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
132int
133PQsslInUse(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 */
144void
145PQinitSSL(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 */
156void
157PQinitOpenSSL(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 */
167int
168pqsecure_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 */
182PostgresPollingStatusType
183pqsecure_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 */
196void
197pqsecure_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 */
212ssize_t
213pqsecure_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
238ssize_t
239pqsecure_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 */
296ssize_t
297pqsecure_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
322ssize_t
323pqsecure_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
336retry_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
410void *
411PQgetssl(PGconn *conn)
412{
413 return NULL;
414}
415
416void *
417PQsslStruct(PGconn *conn, const char *struct_name)
418{
419 return NULL;
420}
421
422const char *
423PQsslAttribute(PGconn *conn, const char *attribute_name)
424{
425 return NULL;
426}
427
428const char *const *
429PQsslAttributeNames(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
440void *
441PQgetgssctx(PGconn *conn)
442{
443 return NULL;
444}
445
446int
447PQgssEncInUse(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 */
461int
462pq_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 */
511void
512pq_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