1 /*-------------------------------------------------------------------------
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.
9 * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
14 * src/interfaces/libpq/fe-secure.c
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.
22 *-------------------------------------------------------------------------
25 #include "postgres_fe.h"
33 #include "libpq-int.h"
38 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #ifdef HAVE_NETINET_TCP_H
43 #include <netinet/tcp.h>
45 #include <arpa/inet.h>
50 #ifdef ENABLE_THREAD_SAFETY
52 #include "pthread-win32.h"
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.
65 #define SIGPIPE_MASKED(conn) ((conn)->sigpipe_so || (conn)->sigpipe_flag)
67 #ifdef ENABLE_THREAD_SAFETY
76 #define DECLARE_SIGPIPE_INFO(spinfo) struct sigpipe_info spinfo
78 #define DISABLE_SIGPIPE(conn, spinfo, failaction) \
80 (spinfo).got_epipe = false; \
81 if (!SIGPIPE_MASKED(conn)) \
83 if (pq_block_sigpipe(&(spinfo).oldsigmask, \
84 &(spinfo).sigpipe_pending) < 0) \
89 #define REMEMBER_EPIPE(spinfo, cond) \
92 (spinfo).got_epipe = true; \
95 #define RESTORE_SIGPIPE(conn, spinfo) \
97 if (!SIGPIPE_MASKED(conn)) \
98 pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
99 (spinfo).got_epipe); \
101 #else /* !ENABLE_THREAD_SAFETY */
103 #define DECLARE_SIGPIPE_INFO(spinfo) pqsigfunc spinfo = NULL
105 #define DISABLE_SIGPIPE(conn, spinfo, failaction) \
107 if (!SIGPIPE_MASKED(conn)) \
108 spinfo = pqsignal(SIGPIPE, SIG_IGN); \
111 #define REMEMBER_EPIPE(spinfo, cond)
113 #define RESTORE_SIGPIPE(conn, spinfo) \
115 if (!SIGPIPE_MASKED(conn)) \
116 pqsignal(SIGPIPE, spinfo); \
118 #endif /* ENABLE_THREAD_SAFETY */
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)
127 /* ------------------------------------------------------------ */
128 /* Procedures common to all secure sessions */
129 /* ------------------------------------------------------------ */
133 * Exported function to allow application to tell us it's already
134 * initialized OpenSSL.
137 PQinitSSL(int do_init)
140 pgtls_init_library(do_init, do_init);
145 * Exported function to allow application to tell us it's already
146 * initialized OpenSSL and/or libcrypto.
149 PQinitOpenSSL(int do_ssl, int do_crypto)
152 pgtls_init_library(do_ssl, do_crypto);
157 * Initialize global SSL context
160 pqsecure_initialize(PGconn *conn)
165 r = pgtls_init(conn);
172 * Begin or continue negotiating a secure session.
174 PostgresPollingStatusType
175 pqsecure_open_client(PGconn *conn)
178 return pgtls_open_client(conn);
180 /* shouldn't get here */
181 return PGRES_POLLING_FAILED;
186 * Close secure session.
189 pqsecure_close(PGconn *conn)
192 if (conn->ssl_in_use)
198 * Read data from a secure connection.
200 * On failure, this function is responsible for putting a suitable message
201 * into conn->errorMessage. The caller must still inspect errno, but only
202 * to determine whether to continue/retry after error.
205 pqsecure_read(PGconn *conn, void *ptr, size_t len)
210 if (conn->ssl_in_use)
212 n = pgtls_read(conn, ptr, len);
217 n = pqsecure_raw_read(conn, ptr, len);
224 pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
227 int result_errno = 0;
230 n = recv(conn->sock, ptr, len, 0);
234 result_errno = SOCK_ERRNO;
236 /* Set error message if appropriate */
237 switch (result_errno)
242 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
246 /* no error message, caller is expected to retry */
251 printfPQExpBuffer(&conn->errorMessage,
253 "server closed the connection unexpectedly\n"
254 "\tThis probably means the server terminated abnormally\n"
255 "\tbefore or while processing the request.\n"));
260 printfPQExpBuffer(&conn->errorMessage,
261 libpq_gettext("could not receive data from server: %s\n"),
262 SOCK_STRERROR(result_errno,
263 sebuf, sizeof(sebuf)));
268 /* ensure we return the intended errno to caller */
269 SOCK_ERRNO_SET(result_errno);
275 * Write data to a secure connection.
277 * On failure, this function is responsible for putting a suitable message
278 * into conn->errorMessage. The caller must still inspect errno, but only
279 * to determine whether to continue/retry after error.
282 pqsecure_write(PGconn *conn, const void *ptr, size_t len)
287 if (conn->ssl_in_use)
289 n = pgtls_write(conn, ptr, len);
294 n = pqsecure_raw_write(conn, ptr, len);
301 pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
305 int result_errno = 0;
308 DECLARE_SIGPIPE_INFO(spinfo);
311 if (conn->sigpipe_flag)
312 flags |= MSG_NOSIGNAL;
315 #endif /* MSG_NOSIGNAL */
317 DISABLE_SIGPIPE(conn, spinfo, return -1);
319 n = send(conn->sock, ptr, len, flags);
323 result_errno = SOCK_ERRNO;
326 * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't
327 * available on this machine. So, clear sigpipe_flag so we don't
328 * try the flag again, and retry the send().
331 if (flags != 0 && result_errno == EINVAL)
333 conn->sigpipe_flag = false;
337 #endif /* MSG_NOSIGNAL */
339 /* Set error message if appropriate */
340 switch (result_errno)
345 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
349 /* no error message, caller is expected to retry */
353 /* Set flag for EPIPE */
354 REMEMBER_EPIPE(spinfo, true);
360 printfPQExpBuffer(&conn->errorMessage,
362 "server closed the connection unexpectedly\n"
363 "\tThis probably means the server terminated abnormally\n"
364 "\tbefore or while processing the request.\n"));
368 printfPQExpBuffer(&conn->errorMessage,
369 libpq_gettext("could not send data to server: %s\n"),
370 SOCK_STRERROR(result_errno,
371 sebuf, sizeof(sebuf)));
376 RESTORE_SIGPIPE(conn, spinfo);
378 /* ensure we return the intended errno to caller */
379 SOCK_ERRNO_SET(result_errno);
386 PQgetssl(PGconn *conn)
393 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
396 * Block SIGPIPE for this thread. This prevents send()/write() from exiting
400 pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
402 sigset_t sigpipe_sigset;
405 sigemptyset(&sigpipe_sigset);
406 sigaddset(&sigpipe_sigset, SIGPIPE);
408 /* Block SIGPIPE and save previous mask for later reset */
409 SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
413 /* We can have a pending SIGPIPE only if it was blocked before */
414 if (sigismember(osigset, SIGPIPE))
416 /* Is there a pending SIGPIPE? */
417 if (sigpending(&sigset) != 0)
420 if (sigismember(&sigset, SIGPIPE))
421 *sigpipe_pending = true;
423 *sigpipe_pending = false;
426 *sigpipe_pending = false;
432 * Discard any pending SIGPIPE and reset the signal mask.
434 * Note: we are effectively assuming here that the C library doesn't queue
435 * up multiple SIGPIPE events. If it did, then we'd accidentally leave
436 * ours in the queue when an event was already pending and we got another.
437 * As long as it doesn't queue multiple events, we're OK because the caller
438 * can't tell the difference.
440 * The caller should say got_epipe = FALSE if it is certain that it
441 * didn't get an EPIPE error; in that case we'll skip the clear operation
442 * and things are definitely OK, queuing or no. If it got one or might have
443 * gotten one, pass got_epipe = TRUE.
445 * We do not want this to change errno, since if it did that could lose
446 * the error code from a preceding send(). We essentially assume that if
447 * we were able to do pq_block_sigpipe(), this can't fail.
450 pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
452 int save_errno = SOCK_ERRNO;
456 /* Clear SIGPIPE only if none was pending */
457 if (got_epipe && !sigpipe_pending)
459 if (sigpending(&sigset) == 0 &&
460 sigismember(&sigset, SIGPIPE))
462 sigset_t sigpipe_sigset;
464 sigemptyset(&sigpipe_sigset);
465 sigaddset(&sigpipe_sigset, SIGPIPE);
467 sigwait(&sigpipe_sigset, &signo);
471 /* Restore saved block mask */
472 pthread_sigmask(SIG_SETMASK, osigset, NULL);
474 SOCK_ERRNO_SET(save_errno);
477 #endif /* ENABLE_THREAD_SAFETY && !WIN32 */