PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 <pthread.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.

Data Structures

struct  sigpipe_info
 

Macros

#define SIGPIPE_MASKED(conn)   ((conn)->sigpipe_so || (conn)->sigpipe_flag)
 
#define DECLARE_SIGPIPE_INFO(spinfo)   struct sigpipe_info spinfo
 
#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)
 
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_bytes_pending (PGconn *conn)
 
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)
 
voidPQgetssl (PGconn *conn)
 
voidPQsslStruct (PGconn *conn, const char *struct_name)
 
const charPQsslAttribute (PGconn *conn, const char *attribute_name)
 
const char *constPQsslAttributeNames (PGconn *conn)
 
PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL (void)
 
void PQsetSSLKeyPassHook_OpenSSL (PQsslKeyPassHook_OpenSSL_type hook)
 
int PQdefaultSSLKeyPassHook_OpenSSL (char *buf, int size, PGconn *conn)
 
voidPQgetgssctx (PGconn *conn)
 
int PQgssEncInUse (PGconn *conn)
 
int pq_block_sigpipe (sigset_t *osigset, bool *sigpipe_pending)
 
void pq_reset_sigpipe (sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
 

Macro Definition Documentation

◆ DECLARE_SIGPIPE_INFO

#define DECLARE_SIGPIPE_INFO (   spinfo)    struct sigpipe_info spinfo

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

◆ DISABLE_SIGPIPE

#define DISABLE_SIGPIPE (   conn,
  spinfo,
  failaction 
)
Value:
do { \
(spinfo).got_epipe = false; \
{ \
if (pq_block_sigpipe(&(spinfo).oldsigmask, \
&(spinfo).sigpipe_pending) < 0) \
} \
} while (0)
#define SIGPIPE_MASKED(conn)
Definition fe-secure.c:55
int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
Definition fe-secure.c:528
static int fb(int x)
PGconn * conn
Definition streamutil.c:52

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

67 { \
68 (spinfo).got_epipe = false; \
70 { \
71 if (pq_block_sigpipe(&(spinfo).oldsigmask, \
72 &(spinfo).sigpipe_pending) < 0) \
73 failaction; \
74 } \
75 } while (0)

◆ REMEMBER_EPIPE

#define REMEMBER_EPIPE (   spinfo,
  cond 
)
Value:
do { \
if (cond) \
(spinfo).got_epipe = true; \
} while (0)

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

78 { \
79 if (cond) \
80 (spinfo).got_epipe = true; \
81 } while (0)

◆ RESTORE_SIGPIPE

#define RESTORE_SIGPIPE (   conn,
  spinfo 
)
Value:
do { \
pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
(spinfo).got_epipe); \
} while (0)

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

84 { \
86 pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \
87 (spinfo).got_epipe); \
88 } while (0)

◆ SIGPIPE_MASKED

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

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

Function Documentation

◆ pq_block_sigpipe()

int pq_block_sigpipe ( sigset_t osigset,
bool sigpipe_pending 
)

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

529{
532
535
536 /* Block SIGPIPE and save previous mask for later reset */
538 if (SOCK_ERRNO)
539 return -1;
540
541 /* We can have a pending SIGPIPE only if it was blocked before */
543 {
544 /* Is there a pending SIGPIPE? */
545 if (sigpending(&sigset) != 0)
546 return -1;
547
549 *sigpipe_pending = true;
550 else
551 *sigpipe_pending = false;
552 }
553 else
554 *sigpipe_pending = false;
555
556 return 0;
557}
#define SOCK_ERRNO
Definition oauth-utils.c:86
#define SOCK_ERRNO_SET(e)
Definition oauth-utils.c:87
#define SIGPIPE
Definition win32_port.h:163

References fb(), SIGPIPE, SOCK_ERRNO, and SOCK_ERRNO_SET.

◆ pq_reset_sigpipe()

void pq_reset_sigpipe ( sigset_t osigset,
bool  sigpipe_pending,
bool  got_epipe 
)

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

579{
581 int signo;
583
584 /* Clear SIGPIPE only if none was pending */
585 if (got_epipe && !sigpipe_pending)
586 {
587 if (sigpending(&sigset) == 0 &&
589 {
591
594
596 }
597 }
598
599 /* Restore saved block mask */
601
603}

References fb(), SIGPIPE, SOCK_ERRNO, and SOCK_ERRNO_SET.

◆ PQdefaultSSLKeyPassHook_OpenSSL()

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

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

498{
499 return 0;
500}

◆ PQgetgssctx()

void * PQgetgssctx ( PGconn conn)

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

508{
509 return NULL;
510}

References fb().

◆ PQgetssl()

void * PQgetssl ( PGconn conn)

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

453{
454 return NULL;
455}

References fb().

◆ PQgetSSLKeyPassHook_OpenSSL()

PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL ( void  )

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

486{
487 return NULL;
488}

References fb().

◆ PQgssEncInUse()

int PQgssEncInUse ( PGconn conn)

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

514{
515 return 0;
516}

◆ PQinitOpenSSL()

void PQinitOpenSSL ( int  do_ssl,
int  do_crypto 
)

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

130{
131 /* no-op */
132}

◆ PQinitSSL()

void PQinitSSL ( int  do_init)

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

118{
119 /* no-op */
120}

◆ pqsecure_bytes_pending()

ssize_t pqsecure_bytes_pending ( PGconn conn)

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

256{
257#ifdef USE_SSL
258 if (conn->ssl_in_use)
260#endif
261#ifdef ENABLE_GSS
262 if (conn->gssenc)
264#endif
265
266 /* Plaintext connections have no transport buffer. */
267 return 0;
268}
ssize_t pg_GSS_bytes_pending(PGconn *conn)
ssize_t pgtls_bytes_pending(PGconn *conn)
bool ssl_in_use
Definition libpq-int.h:623

References conn, pg_GSS_bytes_pending(), pgtls_bytes_pending(), and pg_conn::ssl_in_use.

Referenced by pqDrainPending(), pqReadData(), and pqSocketCheck().

◆ pqsecure_close()

void pqsecure_close ( PGconn conn)

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

153{
154#ifdef USE_SSL
156#endif
157}
void pgtls_close(PGconn *conn)

References conn, and pgtls_close().

Referenced by pqDropConnection().

◆ pqsecure_open_client()

PostgresPollingStatusType pqsecure_open_client ( PGconn conn)

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

139{
140#ifdef USE_SSL
141 return pgtls_open_client(conn);
142#else
143 /* shouldn't get here */
145#endif
146}
PostgresPollingStatusType pgtls_open_client(PGconn *conn)
@ PGRES_POLLING_FAILED
Definition libpq-fe.h:121

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 193 of file fe-secure.c.

194{
195 ssize_t n;
196 int result_errno = 0;
198
200
201 n = recv(conn->sock, ptr, len, 0);
202
203 if (n < 0)
204 {
206
207 /* Set error message if appropriate */
208 switch (result_errno)
209 {
210#ifdef EAGAIN
211 case EAGAIN:
212#endif
213#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
214 case EWOULDBLOCK:
215#endif
216 case EINTR:
217 /* no error message, caller is expected to retry */
218 break;
219
220 case EPIPE:
221 case ECONNRESET:
222 libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
223 "\tThis probably means the server terminated abnormally\n"
224 "\tbefore or while processing the request.");
225 break;
226
227 case 0:
228 /* If errno didn't get set, treat it as regular EOF */
229 n = 0;
230 break;
231
232 default:
233 libpq_append_conn_error(conn, "could not receive data from server: %s",
235 sebuf, sizeof(sebuf)));
236 break;
237 }
238 }
239
240 /* ensure we return the intended errno to caller */
242
243 return n;
244}
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition fe-misc.c:1548
#define SOCK_STRERROR
Definition libpq-int.h:983
const void size_t len
#define PG_STRERROR_R_BUFLEN
Definition port.h:279
pgsocket sock
Definition libpq-int.h:502
#define EINTR
Definition win32_port.h:378
#define EWOULDBLOCK
Definition win32_port.h:384
#define recv(s, buf, len, flags)
Definition win32_port.h:518
#define ECONNRESET
Definition win32_port.h:388
#define EAGAIN
Definition win32_port.h:376

References conn, EAGAIN, ECONNRESET, EINTR, EWOULDBLOCK, fb(), 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(), pg_GSS_read(), pgconn_bio_read(), and pqsecure_read().

◆ pqsecure_raw_write()

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

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

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

References conn, DECLARE_SIGPIPE_INFO, DISABLE_SIGPIPE, EAGAIN, ECONNRESET, EINTR, EINVAL, EWOULDBLOCK, fb(), len, libpq_gettext, pg_fallthrough, 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 pg_GSS_write(), pgconn_bio_write(), pqsecure_open_gss(), and pqsecure_write().

◆ pqsecure_read()

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

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

168{
169 ssize_t n;
170
171#ifdef USE_SSL
172 if (conn->ssl_in_use)
173 {
174 n = pgtls_read(conn, ptr, len);
175 }
176 else
177#endif
178#ifdef ENABLE_GSS
179 if (conn->gssenc)
180 {
181 n = pg_GSS_read(conn, ptr, len);
182 }
183 else
184#endif
185 {
186 n = pqsecure_raw_read(conn, ptr, len);
187 }
188
189 return n;
190}
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:193

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

Referenced by pqDrainPending(), and pqReadData_internal().

◆ pqsecure_write()

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

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

292{
293 ssize_t n;
294
295#ifdef USE_SSL
296 if (conn->ssl_in_use)
297 {
298 n = pgtls_write(conn, ptr, len);
299 }
300 else
301#endif
302#ifdef ENABLE_GSS
303 if (conn->gssenc)
304 {
305 n = pg_GSS_write(conn, ptr, len);
306 }
307 else
308#endif
309 {
310 n = pqsecure_raw_write(conn, ptr, len);
311 }
312
313 return n;
314}
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:340

References conn, fb(), 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 491 of file fe-secure.c.

492{
493 return;
494}

◆ PQsslAttribute()

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

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

465{
466 return NULL;
467}

References fb().

◆ PQsslAttributeNames()

const char *const * PQsslAttributeNames ( PGconn conn)

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

471{
472 static const char *const result[] = {NULL};
473
474 return result;
475}
uint32 result

References fb(), and result.

◆ PQsslInUse()

int PQsslInUse ( PGconn conn)

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

104{
105 if (!conn)
106 return 0;
107 return conn->ssl_in_use;
108}

References conn, and pg_conn::ssl_in_use.

Referenced by exec_command_conninfo(), and printSSLInfo().

◆ PQsslStruct()

void * PQsslStruct ( PGconn conn,
const char struct_name 
)

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

459{
460 return NULL;
461}

References fb().