1
0
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:
Heikki Linnakangas
2014-08-11 11:54:19 +03:00
parent 6aa61580e0
commit 680513ab79
26 changed files with 2782 additions and 2428 deletions

View File

@ -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

View File

@ -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
/*

View File

@ -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)
{

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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