mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
Break out OpenSSL-specific code to separate files.
This refactoring is in preparation for adding support for other SSL implementations, with no user-visible effects. There are now two #defines, USE_OPENSSL which is defined when building with OpenSSL, and USE_SSL which is defined when building with any SSL implementation. Currently, OpenSSL is the only implementation so the two #defines go together, but USE_SSL is supposed to be used for implementation-independent code. The libpq SSL code is changed to use a custom BIO, which does all the raw I/O, like we've been doing in the backend for a long time. That makes it possible to use MSG_NOSIGNAL to block SIGPIPE when using SSL, which avoids a couple of syscall for each send(). Probably doesn't make much performance difference in practice - the SSL encryption is expensive enough to mask the effect - but it was a natural result of this refactoring. Based on a patch by Martijn van Oosterhout from 2006. Briefly reviewed by Alvaro Herrera, Andreas Karlsson, Jeff Janes.
This commit is contained in:
@ -44,6 +44,10 @@ OBJS += ip.o md5.o
|
||||
# utils/mb
|
||||
OBJS += encnames.o wchar.o
|
||||
|
||||
ifeq ($(with_openssl),yes)
|
||||
OBJS += fe-secure-openssl.o
|
||||
endif
|
||||
|
||||
ifeq ($(PORTNAME), cygwin)
|
||||
override shlib = cyg$(NAME)$(DLSUFFIX)
|
||||
endif
|
||||
|
@ -1961,7 +1961,7 @@ keep_going: /* We will come back to here until there is
|
||||
conn->allow_ssl_try = false;
|
||||
}
|
||||
if (conn->allow_ssl_try && !conn->wait_ssl_try &&
|
||||
conn->ssl == NULL)
|
||||
!conn->ssl_in_use)
|
||||
{
|
||||
ProtocolVersion pv;
|
||||
|
||||
@ -2040,7 +2040,7 @@ keep_going: /* We will come back to here until there is
|
||||
* On first time through, get the postmaster's response to our
|
||||
* SSL negotiation packet.
|
||||
*/
|
||||
if (conn->ssl == NULL)
|
||||
if (!conn->ssl_in_use)
|
||||
{
|
||||
/*
|
||||
* We use pqReadData here since it has the logic to
|
||||
@ -2310,7 +2310,7 @@ keep_going: /* We will come back to here until there is
|
||||
* connection already, then retry with an SSL connection
|
||||
*/
|
||||
if (conn->sslmode[0] == 'a' /* "allow" */
|
||||
&& conn->ssl == NULL
|
||||
&& !conn->ssl_in_use
|
||||
&& conn->allow_ssl_try
|
||||
&& conn->wait_ssl_try)
|
||||
{
|
||||
@ -2709,6 +2709,7 @@ makeEmptyPGconn(void)
|
||||
#ifdef USE_SSL
|
||||
conn->allow_ssl_try = true;
|
||||
conn->wait_ssl_try = false;
|
||||
conn->ssl_in_use = false;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -751,7 +751,7 @@ retry3:
|
||||
*/
|
||||
|
||||
#ifdef USE_SSL
|
||||
if (conn->ssl)
|
||||
if (conn->ssl_in_use)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@ -1051,7 +1051,7 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_SSL
|
||||
#ifdef USE_OPENSSL
|
||||
/* Check for SSL library buffering read bytes */
|
||||
if (forRead && conn->ssl && SSL_pending(conn->ssl) > 0)
|
||||
{
|
||||
|
1468
src/interfaces/libpq/fe-secure-openssl.c
Normal file
1468
src/interfaces/libpq/fe-secure-openssl.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -73,14 +73,14 @@ typedef struct
|
||||
#endif
|
||||
#endif /* ENABLE_SSPI */
|
||||
|
||||
#ifdef USE_SSL
|
||||
#ifdef USE_OPENSSL
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
|
||||
#define USE_SSL_ENGINE
|
||||
#endif
|
||||
#endif /* USE_SSL */
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
/*
|
||||
* POSTGRES backend dependent Constants.
|
||||
@ -427,6 +427,8 @@ struct pg_conn
|
||||
bool allow_ssl_try; /* Allowed to try SSL negotiation */
|
||||
bool wait_ssl_try; /* Delay SSL negotiation until after
|
||||
* attempting normal connection */
|
||||
bool ssl_in_use;
|
||||
#ifdef USE_OPENSSL
|
||||
SSL *ssl; /* SSL status, if have SSL connection */
|
||||
X509 *peer; /* X509 cert of server */
|
||||
#ifdef USE_SSL_ENGINE
|
||||
@ -435,6 +437,7 @@ struct pg_conn
|
||||
void *engine; /* dummy field to keep struct the same if
|
||||
* OpenSSL version changes */
|
||||
#endif
|
||||
#endif /* USE_OPENSSL */
|
||||
#endif /* USE_SSL */
|
||||
|
||||
#ifdef ENABLE_GSS
|
||||
@ -482,6 +485,24 @@ struct pg_cancel
|
||||
*/
|
||||
extern char *const pgresStatus[];
|
||||
|
||||
|
||||
#ifdef USE_SSL
|
||||
|
||||
#ifndef WIN32
|
||||
#define USER_CERT_FILE ".postgresql/postgresql.crt"
|
||||
#define USER_KEY_FILE ".postgresql/postgresql.key"
|
||||
#define ROOT_CERT_FILE ".postgresql/root.crt"
|
||||
#define ROOT_CRL_FILE ".postgresql/root.crl"
|
||||
#else
|
||||
/* On Windows, the "home" directory is already PostgreSQL-specific */
|
||||
#define USER_CERT_FILE "postgresql.crt"
|
||||
#define USER_KEY_FILE "postgresql.key"
|
||||
#define ROOT_CERT_FILE "root.crt"
|
||||
#define ROOT_CRL_FILE "root.crl"
|
||||
#endif
|
||||
|
||||
#endif /* USE_SSL */
|
||||
|
||||
/* ----------------
|
||||
* Internal functions of libpq
|
||||
* Functions declared here need to be visible across files of libpq,
|
||||
@ -603,6 +624,8 @@ extern PostgresPollingStatusType pqsecure_open_client(PGconn *);
|
||||
extern void pqsecure_close(PGconn *);
|
||||
extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len);
|
||||
extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len);
|
||||
extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len);
|
||||
extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len);
|
||||
|
||||
#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
|
||||
extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
|
||||
@ -610,6 +633,16 @@ extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending,
|
||||
bool got_epipe);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The SSL implementatation provides these functions (fe-secure-openssl.c)
|
||||
*/
|
||||
extern void pgtls_init_library(bool do_ssl, int do_crypto);
|
||||
extern int pgtls_init(PGconn *conn);
|
||||
extern PostgresPollingStatusType pgtls_open_client(PGconn *conn);
|
||||
extern void pgtls_close(PGconn *conn);
|
||||
extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len);
|
||||
extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
|
||||
|
||||
/*
|
||||
* this is so that we can check if a connection is non-blocking internally
|
||||
* without the overhead of a function call
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
# Will build a static library libpq(d).lib
|
||||
# and a dynamic library libpq(d).dll with import library libpq(d)dll.lib
|
||||
# USE_SSL=1 will compile with OpenSSL
|
||||
# USE_OPENSSL=1 will compile with OpenSSL
|
||||
# USE_KFW=1 will compile with kfw(kerberos for Windows)
|
||||
# DEBUG=1 compiles with debugging symbols
|
||||
# ENABLE_THREAD_SAFETY=1 compiles with threading enabled
|
||||
@ -124,6 +124,9 @@ CLEAN :
|
||||
-@erase "$(OUTDIR)\$(OUTFILENAME).dll.manifest"
|
||||
-@erase "$(OUTDIR)\*.idb"
|
||||
-@erase pg_config_paths.h"
|
||||
!IFDEF USE_OPENSSL
|
||||
-@erase "$(INTDIR)\fe-secure-openssl.obj"
|
||||
!ENDIF
|
||||
|
||||
|
||||
LIB32=link.exe -lib
|
||||
@ -164,6 +167,9 @@ LIB32_OBJS= \
|
||||
"$(INTDIR)\win32error.obj" \
|
||||
"$(INTDIR)\win32setlocale.obj" \
|
||||
"$(INTDIR)\pthread-win32.obj"
|
||||
!IFDEF USE_OPENSSL
|
||||
LIB32_OBJS=$(LIB32_OBJS) "$(INTDIR)\fe-secure-openssl.obj"
|
||||
!ENDIF
|
||||
|
||||
|
||||
config: ..\..\include\pg_config.h ..\..\include\pg_config_ext.h pg_config_paths.h ..\..\include\pg_config_os.h
|
||||
@ -189,8 +195,8 @@ CPP_PROJ=/nologo /W3 /EHsc $(OPT) /I "..\..\include" /I "..\..\include\port\win3
|
||||
/Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c \
|
||||
/D "_CRT_SECURE_NO_DEPRECATE" $(ADD_DEFINES)
|
||||
|
||||
!IFDEF USE_SSL
|
||||
CPP_PROJ=$(CPP_PROJ) /D USE_SSL
|
||||
!IFDEF USE_OPENSSL
|
||||
CPP_PROJ=$(CPP_PROJ) /D USE_OPENSSL
|
||||
SSL_LIBS=ssleay32.lib libeay32.lib gdi32.lib
|
||||
!ENDIF
|
||||
|
||||
|
Reference in New Issue
Block a user