PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
fe-secure.c
Go to the documentation of this file.
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-2017, 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 /*
133  * Exported function to allow application to tell us it's already
134  * initialized OpenSSL.
135  */
136 void
138 {
139 #ifdef USE_SSL
140  pgtls_init_library(do_init, do_init);
141 #endif
142 }
143 
144 /*
145  * Exported function to allow application to tell us it's already
146  * initialized OpenSSL and/or libcrypto.
147  */
148 void
149 PQinitOpenSSL(int do_ssl, int do_crypto)
150 {
151 #ifdef USE_SSL
152  pgtls_init_library(do_ssl, do_crypto);
153 #endif
154 }
155 
156 /*
157  * Initialize global SSL context
158  */
159 int
161 {
162  int r = 0;
163 
164 #ifdef USE_SSL
165  r = pgtls_init(conn);
166 #endif
167 
168  return r;
169 }
170 
171 /*
172  * Begin or continue negotiating a secure session.
173  */
176 {
177 #ifdef USE_SSL
178  return pgtls_open_client(conn);
179 #else
180  /* shouldn't get here */
181  return PGRES_POLLING_FAILED;
182 #endif
183 }
184 
185 /*
186  * Close secure session.
187  */
188 void
190 {
191 #ifdef USE_SSL
192  if (conn->ssl_in_use)
193  pgtls_close(conn);
194 #endif
195 }
196 
197 /*
198  * Read data from a secure connection.
199  *
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.
203  */
204 ssize_t
205 pqsecure_read(PGconn *conn, void *ptr, size_t len)
206 {
207  ssize_t n;
208 
209 #ifdef USE_SSL
210  if (conn->ssl_in_use)
211  {
212  n = pgtls_read(conn, ptr, len);
213  }
214  else
215 #endif
216  {
217  n = pqsecure_raw_read(conn, ptr, len);
218  }
219 
220  return n;
221 }
222 
223 ssize_t
224 pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
225 {
226  ssize_t n;
227  int result_errno = 0;
228  char sebuf[256];
229 
230  n = recv(conn->sock, ptr, len, 0);
231 
232  if (n < 0)
233  {
234  result_errno = SOCK_ERRNO;
235 
236  /* Set error message if appropriate */
237  switch (result_errno)
238  {
239 #ifdef EAGAIN
240  case EAGAIN:
241 #endif
242 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
243  case EWOULDBLOCK:
244 #endif
245  case EINTR:
246  /* no error message, caller is expected to retry */
247  break;
248 
249 #ifdef ECONNRESET
250  case ECONNRESET:
253  "server closed the connection unexpectedly\n"
254  "\tThis probably means the server terminated abnormally\n"
255  "\tbefore or while processing the request.\n"));
256  break;
257 #endif
258 
259  default:
261  libpq_gettext("could not receive data from server: %s\n"),
262  SOCK_STRERROR(result_errno,
263  sebuf, sizeof(sebuf)));
264  break;
265  }
266  }
267 
268  /* ensure we return the intended errno to caller */
269  SOCK_ERRNO_SET(result_errno);
270 
271  return n;
272 }
273 
274 /*
275  * Write data to a secure connection.
276  *
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.
280  */
281 ssize_t
282 pqsecure_write(PGconn *conn, const void *ptr, size_t len)
283 {
284  ssize_t n;
285 
286 #ifdef USE_SSL
287  if (conn->ssl_in_use)
288  {
289  n = pgtls_write(conn, ptr, len);
290  }
291  else
292 #endif
293  {
294  n = pqsecure_raw_write(conn, ptr, len);
295  }
296 
297  return n;
298 }
299 
300 ssize_t
301 pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
302 {
303  ssize_t n;
304  int flags = 0;
305  int result_errno = 0;
306  char sebuf[256];
307 
308  DECLARE_SIGPIPE_INFO(spinfo);
309 
310 #ifdef MSG_NOSIGNAL
311  if (conn->sigpipe_flag)
312  flags |= MSG_NOSIGNAL;
313 
314 retry_masked:
315 #endif /* MSG_NOSIGNAL */
316 
317  DISABLE_SIGPIPE(conn, spinfo, return -1);
318 
319  n = send(conn->sock, ptr, len, flags);
320 
321  if (n < 0)
322  {
323  result_errno = SOCK_ERRNO;
324 
325  /*
326  * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
327  * on this machine. So, clear sigpipe_flag so we don't try the flag
328  * again, and retry the send().
329  */
330 #ifdef MSG_NOSIGNAL
331  if (flags != 0 && result_errno == EINVAL)
332  {
333  conn->sigpipe_flag = false;
334  flags = 0;
335  goto retry_masked;
336  }
337 #endif /* MSG_NOSIGNAL */
338 
339  /* Set error message if appropriate */
340  switch (result_errno)
341  {
342 #ifdef EAGAIN
343  case EAGAIN:
344 #endif
345 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
346  case EWOULDBLOCK:
347 #endif
348  case EINTR:
349  /* no error message, caller is expected to retry */
350  break;
351 
352  case EPIPE:
353  /* Set flag for EPIPE */
354  REMEMBER_EPIPE(spinfo, true);
355  /* FALL THRU */
356 
357 #ifdef ECONNRESET
358  case ECONNRESET:
359 #endif
362  "server closed the connection unexpectedly\n"
363  "\tThis probably means the server terminated abnormally\n"
364  "\tbefore or while processing the request.\n"));
365  break;
366 
367  default:
369  libpq_gettext("could not send data to server: %s\n"),
370  SOCK_STRERROR(result_errno,
371  sebuf, sizeof(sebuf)));
372  break;
373  }
374  }
375 
376  RESTORE_SIGPIPE(conn, spinfo);
377 
378  /* ensure we return the intended errno to caller */
379  SOCK_ERRNO_SET(result_errno);
380 
381  return n;
382 }
383 
384 /* Dummy versions of SSL info functions, when built without SSL support */
385 #ifndef USE_SSL
386 
387 int
389 {
390  return 0;
391 }
392 
393 void *
395 {
396  return NULL;
397 }
398 
399 void *
400 PQsslStruct(PGconn *conn, const char *struct_name)
401 {
402  return NULL;
403 }
404 
405 const char *
406 PQsslAttribute(PGconn *conn, const char *attribute_name)
407 {
408  return NULL;
409 }
410 
411 const char *const *
413 {
414  static const char *const result[] = {NULL};
415 
416  return result;
417 }
418 #endif /* USE_SSL */
419 
420 
421 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
422 
423 /*
424  * Block SIGPIPE for this thread. This prevents send()/write() from exiting
425  * the application.
426  */
427 int
428 pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
429 {
430  sigset_t sigpipe_sigset;
431  sigset_t sigset;
432 
433  sigemptyset(&sigpipe_sigset);
434  sigaddset(&sigpipe_sigset, SIGPIPE);
435 
436  /* Block SIGPIPE and save previous mask for later reset */
437  SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
438  if (SOCK_ERRNO)
439  return -1;
440 
441  /* We can have a pending SIGPIPE only if it was blocked before */
442  if (sigismember(osigset, SIGPIPE))
443  {
444  /* Is there a pending SIGPIPE? */
445  if (sigpending(&sigset) != 0)
446  return -1;
447 
448  if (sigismember(&sigset, SIGPIPE))
449  *sigpipe_pending = true;
450  else
451  *sigpipe_pending = false;
452  }
453  else
454  *sigpipe_pending = false;
455 
456  return 0;
457 }
458 
459 /*
460  * Discard any pending SIGPIPE and reset the signal mask.
461  *
462  * Note: we are effectively assuming here that the C library doesn't queue
463  * up multiple SIGPIPE events. If it did, then we'd accidentally leave
464  * ours in the queue when an event was already pending and we got another.
465  * As long as it doesn't queue multiple events, we're OK because the caller
466  * can't tell the difference.
467  *
468  * The caller should say got_epipe = FALSE if it is certain that it
469  * didn't get an EPIPE error; in that case we'll skip the clear operation
470  * and things are definitely OK, queuing or no. If it got one or might have
471  * gotten one, pass got_epipe = TRUE.
472  *
473  * We do not want this to change errno, since if it did that could lose
474  * the error code from a preceding send(). We essentially assume that if
475  * we were able to do pq_block_sigpipe(), this can't fail.
476  */
477 void
478 pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
479 {
480  int save_errno = SOCK_ERRNO;
481  int signo;
482  sigset_t sigset;
483 
484  /* Clear SIGPIPE only if none was pending */
485  if (got_epipe && !sigpipe_pending)
486  {
487  if (sigpending(&sigset) == 0 &&
488  sigismember(&sigset, SIGPIPE))
489  {
490  sigset_t sigpipe_sigset;
491 
492  sigemptyset(&sigpipe_sigset);
493  sigaddset(&sigpipe_sigset, SIGPIPE);
494 
495  sigwait(&sigpipe_sigset, &signo);
496  }
497  }
498 
499  /* Restore saved block mask */
500  pthread_sigmask(SIG_SETMASK, osigset, NULL);
501 
502  SOCK_ERRNO_SET(save_errno);
503 }
504 
505 #endif /* ENABLE_THREAD_SAFETY && !WIN32 */
#define send(s, buf, len, flags)
Definition: win32.h:386
#define EWOULDBLOCK
Definition: win32.h:301
bool sigpipe_flag
Definition: libpq-int.h:413
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
#define DECLARE_SIGPIPE_INFO(spinfo)
Definition: fe-secure.c:103
void pqsecure_close(PGconn *conn)
Definition: fe-secure.c:189
const char *const * PQsslAttributeNames(PGconn *conn)
Definition: fe-secure.c:412
ssize_t pqsecure_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:205
int sigwait(const sigset_t *set, int *sig)
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
Definition: fe-secure.c:406
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:224
#define recv(s, buf, len, flags)
Definition: win32.h:385
PostgresPollingStatusType pgtls_open_client(PGconn *conn)
#define ECONNRESET
Definition: win32.h:305
#define EAGAIN
Definition: win32.h:293
#define SOCK_STRERROR
Definition: libpq-int.h:703
ssize_t pqsecure_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:282
#define SOCK_ERRNO
Definition: libpq-int.h:702
PGconn * conn
Definition: streamutil.c:45
void * PQgetssl(PGconn *conn)
Definition: fe-secure.c:394
PostgresPollingStatusType pqsecure_open_client(PGconn *conn)
Definition: fe-secure.c:175
void * PQsslStruct(PGconn *conn, const char *struct_name)
Definition: fe-secure.c:400
#define RESTORE_SIGPIPE(conn, spinfo)
Definition: fe-secure.c:113
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:704
pgsocket sock
Definition: libpq-int.h:402
void pgtls_close(PGconn *conn)
ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len)
ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len)
#define REMEMBER_EPIPE(spinfo, cond)
Definition: fe-secure.c:111
void PQinitOpenSSL(int do_ssl, int do_crypto)
Definition: fe-secure.c:149
#define EINTR
Definition: win32.h:295
int pqsecure_initialize(PGconn *conn)
Definition: fe-secure.c:160
#define SIGPIPE
Definition: win32.h:201
PQExpBufferData errorMessage
Definition: libpq-int.h:498
int PQsslInUse(PGconn *conn)
Definition: fe-secure.c:388
#define NULL
Definition: c.h:226
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:301
static void do_init(void)
Definition: pg_ctl.c:840
PostgresPollingStatusType
Definition: libpq-fe.h:72
void PQinitSSL(int do_init)
Definition: fe-secure.c:137
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
Definition: fe-secure.c:105
void pgtls_init_library(bool do_ssl, int do_crypto)
int pgtls_init(PGconn *conn)
#define libpq_gettext(x)
Definition: libpq-int.h:689