PostgreSQL Source Code  git master
fe-secure.c File Reference
#include "postgres_fe.h"
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include "fe-auth.h"
#include "libpq-fe.h"
#include "libpq-int.h"
Include dependency graph for fe-secure.c:

Go to the source code of this file.

Macros

#define SIGPIPE_MASKED(conn)   ((conn)->sigpipe_so || (conn)->sigpipe_flag)
 
#define DECLARE_SIGPIPE_INFO(spinfo)   pqsigfunc spinfo = NULL
 
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
 
#define REMEMBER_EPIPE(spinfo, cond)
 
#define RESTORE_SIGPIPE(conn, spinfo)
 

Functions

int PQsslInUse (PGconn *conn)
 
void PQinitSSL (int do_init)
 
void PQinitOpenSSL (int do_ssl, int do_crypto)
 
int pqsecure_initialize (PGconn *conn, bool do_ssl, bool do_crypto)
 
PostgresPollingStatusType pqsecure_open_client (PGconn *conn)
 
void pqsecure_close (PGconn *conn)
 
ssize_t pqsecure_read (PGconn *conn, void *ptr, size_t len)
 
ssize_t pqsecure_raw_read (PGconn *conn, void *ptr, size_t len)
 
ssize_t pqsecure_write (PGconn *conn, const void *ptr, size_t len)
 
ssize_t pqsecure_raw_write (PGconn *conn, const void *ptr, size_t len)
 
void * PQgetssl (PGconn *conn)
 
void * PQsslStruct (PGconn *conn, const char *struct_name)
 
const char * PQsslAttribute (PGconn *conn, const char *attribute_name)
 
const char *const * PQsslAttributeNames (PGconn *conn)
 
PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL (void)
 
void PQsetSSLKeyPassHook_OpenSSL (PQsslKeyPassHook_OpenSSL_type hook)
 
int PQdefaultSSLKeyPassHook_OpenSSL (char *buf, int size, PGconn *conn)
 
void * PQgetgssctx (PGconn *conn)
 
int PQgssEncInUse (PGconn *conn)
 

Macro Definition Documentation

◆ DECLARE_SIGPIPE_INFO

#define DECLARE_SIGPIPE_INFO (   spinfo)    pqsigfunc spinfo = NULL

Definition at line 95 of file fe-secure.c.

◆ DISABLE_SIGPIPE

#define DISABLE_SIGPIPE (   conn,
  spinfo,
  failaction 
)
Value:
do { \
spinfo = pqsignal(SIGPIPE, SIG_IGN); \
} while (0)
#define SIGPIPE_MASKED(conn)
Definition: fe-secure.c:57
pqsigfunc pqsignal(int signo, pqsigfunc func)
PGconn * conn
Definition: streamutil.c:54
#define SIGPIPE
Definition: win32_port.h:181
#define SIG_IGN
Definition: win32_port.h:173

Definition at line 97 of file fe-secure.c.

◆ REMEMBER_EPIPE

#define REMEMBER_EPIPE (   spinfo,
  cond 
)

Definition at line 103 of file fe-secure.c.

◆ RESTORE_SIGPIPE

#define RESTORE_SIGPIPE (   conn,
  spinfo 
)
Value:
do { \
pqsignal(SIGPIPE, spinfo); \
} while (0)

Definition at line 105 of file fe-secure.c.

◆ SIGPIPE_MASKED

#define SIGPIPE_MASKED (   conn)    ((conn)->sigpipe_so || (conn)->sigpipe_flag)

Definition at line 57 of file fe-secure.c.

Function Documentation

◆ PQdefaultSSLKeyPassHook_OpenSSL()

int PQdefaultSSLKeyPassHook_OpenSSL ( char *  buf,
int  size,
PGconn conn 
)

Definition at line 503 of file fe-secure.c.

504 {
505  return 0;
506 }

◆ PQgetgssctx()

void* PQgetgssctx ( PGconn conn)

Definition at line 513 of file fe-secure.c.

514 {
515  return NULL;
516 }

◆ PQgetssl()

void* PQgetssl ( PGconn conn)

Definition at line 458 of file fe-secure.c.

459 {
460  return NULL;
461 }

◆ PQgetSSLKeyPassHook_OpenSSL()

PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL ( void  )

Definition at line 491 of file fe-secure.c.

492 {
493  return NULL;
494 }

◆ PQgssEncInUse()

int PQgssEncInUse ( PGconn conn)

Definition at line 519 of file fe-secure.c.

520 {
521  return 0;
522 }

◆ PQinitOpenSSL()

void PQinitOpenSSL ( int  do_ssl,
int  do_crypto 
)

Definition at line 149 of file fe-secure.c.

150 {
151 #ifdef USE_SSL
152  pgtls_init_library(do_ssl, do_crypto);
153 #endif
154 }
void pgtls_init_library(bool do_ssl, int do_crypto)

References pgtls_init_library().

◆ PQinitSSL()

void PQinitSSL ( int  do_init)

Definition at line 137 of file fe-secure.c.

138 {
139 #ifdef USE_SSL
141 #endif
142 }
static void do_init(void)
Definition: pg_ctl.c:895

References do_init(), and pgtls_init_library().

◆ pqsecure_close()

void pqsecure_close ( PGconn conn)

Definition at line 189 of file fe-secure.c.

190 {
191 #ifdef USE_SSL
192  pgtls_close(conn);
193 #endif
194 }
void pgtls_close(PGconn *conn)

References conn, and pgtls_close().

Referenced by pqDropConnection().

◆ pqsecure_initialize()

int pqsecure_initialize ( PGconn conn,
bool  do_ssl,
bool  do_crypto 
)

Definition at line 160 of file fe-secure.c.

161 {
162  int r = 0;
163 
164 #ifdef USE_SSL
165  r = pgtls_init(conn, do_ssl, do_crypto);
166 #endif
167 
168  return r;
169 }
int pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)

References conn, and pgtls_init().

Referenced by PQconnectPoll().

◆ pqsecure_open_client()

PostgresPollingStatusType pqsecure_open_client ( PGconn conn)

Definition at line 175 of file fe-secure.c.

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 }
PostgresPollingStatusType pgtls_open_client(PGconn *conn)
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:86

References conn, PGRES_POLLING_FAILED, and pgtls_open_client().

Referenced by PQconnectPoll().

◆ pqsecure_raw_read()

ssize_t pqsecure_raw_read ( PGconn conn,
void *  ptr,
size_t  len 
)

Definition at line 230 of file fe-secure.c.

231 {
232  ssize_t n;
233  int result_errno = 0;
234  char sebuf[PG_STRERROR_R_BUFLEN];
235 
236  n = recv(conn->sock, ptr, len, 0);
237 
238  if (n < 0)
239  {
240  result_errno = SOCK_ERRNO;
241 
242  /* Set error message if appropriate */
243  switch (result_errno)
244  {
245 #ifdef EAGAIN
246  case EAGAIN:
247 #endif
248 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
249  case EWOULDBLOCK:
250 #endif
251  case EINTR:
252  /* no error message, caller is expected to retry */
253  break;
254 
255  case EPIPE:
256  case ECONNRESET:
257  libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
258  "\tThis probably means the server terminated abnormally\n"
259  "\tbefore or while processing the request.");
260  break;
261 
262  default:
263  libpq_append_conn_error(conn, "could not receive data from server: %s",
264  SOCK_STRERROR(result_errno,
265  sebuf, sizeof(sebuf)));
266  break;
267  }
268  }
269 
270  /* ensure we return the intended errno to caller */
271  SOCK_ERRNO_SET(result_errno);
272 
273  return n;
274 }
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1312
#define SOCK_STRERROR
Definition: libpq-int.h:904
#define SOCK_ERRNO
Definition: libpq-int.h:903
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:905
const void size_t len
#define PG_STRERROR_R_BUFLEN
Definition: port.h:256
pgsocket sock
Definition: libpq-int.h:447
#define EINTR
Definition: win32_port.h:369
#define EWOULDBLOCK
Definition: win32_port.h:375
#define recv(s, buf, len, flags)
Definition: win32_port.h:493
#define ECONNRESET
Definition: win32_port.h:379
#define EAGAIN
Definition: win32_port.h:367

References conn, EAGAIN, ECONNRESET, EINTR, EWOULDBLOCK, len, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, recv, pg_conn::sock, SOCK_ERRNO, SOCK_ERRNO_SET, and SOCK_STRERROR.

Referenced by gss_read(), my_sock_read(), pg_GSS_read(), and pqsecure_read().

◆ pqsecure_raw_write()

ssize_t pqsecure_raw_write ( PGconn conn,
const void *  ptr,
size_t  len 
)

Definition at line 346 of file fe-secure.c.

347 {
348  ssize_t n;
349  int flags = 0;
350  int result_errno = 0;
351  char msgbuf[1024];
352  char sebuf[PG_STRERROR_R_BUFLEN];
353 
354  DECLARE_SIGPIPE_INFO(spinfo);
355 
356  /*
357  * If we already had a write failure, we will never again try to send data
358  * on that connection. Even if the kernel would let us, we've probably
359  * lost message boundary sync with the server. conn->write_failed
360  * therefore persists until the connection is reset, and we just discard
361  * all data presented to be written.
362  */
363  if (conn->write_failed)
364  return len;
365 
366 #ifdef MSG_NOSIGNAL
367  if (conn->sigpipe_flag)
368  flags |= MSG_NOSIGNAL;
369 
370 retry_masked:
371 #endif /* MSG_NOSIGNAL */
372 
373  DISABLE_SIGPIPE(conn, spinfo, return -1);
374 
375  n = send(conn->sock, ptr, len, flags);
376 
377  if (n < 0)
378  {
379  result_errno = SOCK_ERRNO;
380 
381  /*
382  * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available
383  * on this machine. So, clear sigpipe_flag so we don't try the flag
384  * again, and retry the send().
385  */
386 #ifdef MSG_NOSIGNAL
387  if (flags != 0 && result_errno == EINVAL)
388  {
389  conn->sigpipe_flag = false;
390  flags = 0;
391  goto retry_masked;
392  }
393 #endif /* MSG_NOSIGNAL */
394 
395  /* Set error message if appropriate */
396  switch (result_errno)
397  {
398 #ifdef EAGAIN
399  case EAGAIN:
400 #endif
401 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
402  case EWOULDBLOCK:
403 #endif
404  case EINTR:
405  /* no error message, caller is expected to retry */
406  break;
407 
408  case EPIPE:
409  /* Set flag for EPIPE */
410  REMEMBER_EPIPE(spinfo, true);
411 
412  /* FALL THRU */
413 
414  case ECONNRESET:
415  conn->write_failed = true;
416  /* Store error message in conn->write_err_msg, if possible */
417  /* (strdup failure is OK, we'll cope later) */
418  snprintf(msgbuf, sizeof(msgbuf),
419  libpq_gettext("server closed the connection unexpectedly\n"
420  "\tThis probably means the server terminated abnormally\n"
421  "\tbefore or while processing the request."));
422  /* keep newline out of translated string */
423  strlcat(msgbuf, "\n", sizeof(msgbuf));
424  conn->write_err_msg = strdup(msgbuf);
425  /* Now claim the write succeeded */
426  n = len;
427  break;
428 
429  default:
430  conn->write_failed = true;
431  /* Store error message in conn->write_err_msg, if possible */
432  /* (strdup failure is OK, we'll cope later) */
433  snprintf(msgbuf, sizeof(msgbuf),
434  libpq_gettext("could not send data to server: %s"),
435  SOCK_STRERROR(result_errno,
436  sebuf, sizeof(sebuf)));
437  /* keep newline out of translated string */
438  strlcat(msgbuf, "\n", sizeof(msgbuf));
439  conn->write_err_msg = strdup(msgbuf);
440  /* Now claim the write succeeded */
441  n = len;
442  break;
443  }
444  }
445 
446  RESTORE_SIGPIPE(conn, spinfo);
447 
448  /* ensure we return the intended errno to caller */
449  SOCK_ERRNO_SET(result_errno);
450 
451  return n;
452 }
#define REMEMBER_EPIPE(spinfo, cond)
Definition: fe-secure.c:103
#define DISABLE_SIGPIPE(conn, spinfo, failaction)
Definition: fe-secure.c:97
#define DECLARE_SIGPIPE_INFO(spinfo)
Definition: fe-secure.c:95
#define RESTORE_SIGPIPE(conn, spinfo)
Definition: fe-secure.c:105
#define libpq_gettext(x)
Definition: libpq-int.h:882
#define snprintf
Definition: port.h:238
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: strlcat.c:33
char * write_err_msg
Definition: libpq-int.h:458
bool sigpipe_flag
Definition: libpq-int.h:456
bool write_failed
Definition: libpq-int.h:457
#define send(s, buf, len, flags)
Definition: win32_port.h:494

References conn, DECLARE_SIGPIPE_INFO, DISABLE_SIGPIPE, EAGAIN, ECONNRESET, EINTR, EWOULDBLOCK, len, libpq_gettext, PG_STRERROR_R_BUFLEN, REMEMBER_EPIPE, RESTORE_SIGPIPE, send, pg_conn::sigpipe_flag, snprintf, pg_conn::sock, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, strlcat(), pg_conn::write_err_msg, and pg_conn::write_failed.

Referenced by my_sock_write(), pg_GSS_write(), pqsecure_open_gss(), and pqsecure_write().

◆ pqsecure_read()

ssize_t pqsecure_read ( PGconn conn,
void *  ptr,
size_t  len 
)

Definition at line 204 of file fe-secure.c.

205 {
206  ssize_t n;
207 
208 #ifdef USE_SSL
209  if (conn->ssl_in_use)
210  {
211  n = pgtls_read(conn, ptr, len);
212  }
213  else
214 #endif
215 #ifdef ENABLE_GSS
216  if (conn->gssenc)
217  {
218  n = pg_GSS_read(conn, ptr, len);
219  }
220  else
221 #endif
222  {
223  n = pqsecure_raw_read(conn, ptr, len);
224  }
225 
226  return n;
227 }
ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len)
ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len)
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:230
bool ssl_in_use
Definition: libpq-int.h:520

References conn, len, pg_GSS_read(), pgtls_read(), pqsecure_raw_read(), and pg_conn::ssl_in_use.

Referenced by pqReadData().

◆ pqsecure_write()

ssize_t pqsecure_write ( PGconn conn,
const void *  ptr,
size_t  len 
)

Definition at line 297 of file fe-secure.c.

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 }
ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len)
ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len)
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:346

References conn, len, pg_GSS_write(), pgtls_write(), pqsecure_raw_write(), and pg_conn::ssl_in_use.

Referenced by pqSendSome().

◆ PQsetSSLKeyPassHook_OpenSSL()

void PQsetSSLKeyPassHook_OpenSSL ( PQsslKeyPassHook_OpenSSL_type  hook)

Definition at line 497 of file fe-secure.c.

498 {
499  return;
500 }

◆ PQsslAttribute()

const char* PQsslAttribute ( PGconn conn,
const char *  attribute_name 
)

Definition at line 470 of file fe-secure.c.

471 {
472  return NULL;
473 }

◆ PQsslAttributeNames()

const char* const* PQsslAttributeNames ( PGconn conn)

Definition at line 476 of file fe-secure.c.

477 {
478  static const char *const result[] = {NULL};
479 
480  return result;
481 }

◆ PQsslInUse()

int PQsslInUse ( PGconn conn)

Definition at line 125 of file fe-secure.c.

126 {
127  if (!conn)
128  return 0;
129  return conn->ssl_in_use;
130 }

References conn, and pg_conn::ssl_in_use.

Referenced by printSSLInfo().

◆ PQsslStruct()

void* PQsslStruct ( PGconn conn,
const char *  struct_name 
)

Definition at line 464 of file fe-secure.c.

465 {
466  return NULL;
467 }