postgresql-master-ssl-protocols-v2.diff
text/x-diff
Filename: postgresql-master-ssl-protocols-v2.diff
Type: text/x-diff
Part: 0
Patch
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| doc/src/sgml/config.sgml | 0 | 0 |
| doc/src/sgml/libpq.sgml | 0 | 0 |
| src/backend/libpq/be-secure.c | 0 | 0 |
| src/backend/libpq/be-secure-openssl.c | 0 | 0 |
| src/backend/libpq/Makefile | 0 | 0 |
| src/backend/libpq/openssl.c | 0 | 0 |
| src/backend/utils/misc/guc.c | 0 | 0 |
| src/backend/utils/misc/postgresql.conf.sample | 0 | 0 |
| src/include/libpq/libpq.h | 0 | 0 |
| src/include/libpq/openssl.h | 0 | 0 |
| src/interfaces/libpq/fe-connect.c | 0 | 0 |
| src/interfaces/libpq/fe-secure-openssl.c | 0 | 0 |
| src/interfaces/libpq/libpq-int.h | 0 | 0 |
| src/interfaces/libpq/Makefile | 0 | 0 |
>From 7cd60e962ce5e7fc10dc52ed9c92b0b2b5c4c7f1 Mon Sep 17 00:00:00 2001
From: Alex Shulgin <ash@commandprompt.com>
Date: Wed, 19 Nov 2014 19:49:29 +0300
Subject: [PATCH] DRAFT: ssl_protocols GUC
---
doc/src/sgml/config.sgml | 29 ++++++
doc/src/sgml/libpq.sgml | 25 ++++++
src/backend/libpq/Makefile | 2 +-
src/backend/libpq/be-secure-openssl.c | 29 ++++--
src/backend/libpq/be-secure.c | 3 +-
src/backend/libpq/openssl.c | 124 ++++++++++++++++++++++++++
src/backend/utils/misc/guc.c | 15 ++++
src/backend/utils/misc/postgresql.conf.sample | 1 +
src/include/libpq/libpq.h | 1 +
src/include/libpq/openssl.h | 50 +++++++++++
src/interfaces/libpq/Makefile | 8 +-
src/interfaces/libpq/fe-connect.c | 4 +
src/interfaces/libpq/fe-secure-openssl.c | 18 +++-
src/interfaces/libpq/libpq-int.h | 1 +
14 files changed, 300 insertions(+), 10 deletions(-)
create mode 100644 src/backend/libpq/openssl.c
create mode 100644 src/include/libpq/openssl.h
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
new file mode 100644
index ab8c263..8b701df
*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
*************** include_dir 'conf.d'
*** 1027,1032 ****
--- 1027,1061 ----
</listitem>
</varlistentry>
+ <varlistentry id="guc-ssl-protocols" xreflabel="ssl_protocols">
+ <term><varname>ssl_protocols</varname> (<type>string</type>)
+ <indexterm>
+ <primary><varname>ssl_protocols</> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Specifies a colon-separated list of <acronym>SSL</> protocols that are
+ allowed to be used on secure connections. Each entry in the list can
+ be prefixed by a <literal>+</> (add to the current list)
+ or <literal>-</> (remove from the current list). If no prefix is used,
+ the list is replaced with the specified protocol.
+ </para>
+ <para>
+ The full list of supported protocols can be found in the
+ the <application>openssl</> manual page. In addition to the names of
+ individual protocols, the following keywords can be
+ used: <literal>ALL</> (all protocols supported by the underlying
+ crypto library), <literal>SSL</> (all supported versions
+ of <acronym>SSL</>) and <literal>TLS</> (all supported versions
+ of <acronym>TLS</>).
+ </para>
+ <para>
+ The default is <literal>ALL:-SSL</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-ssl-ciphers" xreflabel="ssl_ciphers">
<term><varname>ssl_ciphers</varname> (<type>string</type>)
<indexterm>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
new file mode 100644
index e23e91d..9ea71a4
*** a/doc/src/sgml/libpq.sgml
--- b/doc/src/sgml/libpq.sgml
*************** postgresql://%2Fvar%2Flib%2Fpostgresql/d
*** 1230,1235 ****
--- 1230,1250 ----
</listitem>
</varlistentry>
+ <varlistentry id="libpq-connect-sslprotocols" xreflabel="sslprotocols">
+ <term><literal>sslprotocols</literal></term>
+ <listitem>
+ <para>
+ Specifies a colon-separated list of <acronym>SSL</> protocols that are
+ allowed to be used on secure connections.
+ See <xref linkend="guc-ssl-protocols"> server configuration parameter
+ for format.
+ </para>
+ <para>
+ Defaults to <literal>ALL:-SSL</>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="libpq-connect-sslcompression" xreflabel="sslcompression">
<term><literal>sslcompression</literal></term>
<listitem>
*************** myEventProc(PGEventId evtId, void *evtIn
*** 6711,6716 ****
--- 6726,6741 ----
</para>
</listitem>
+ <listitem>
+ <para>
+ <indexterm>
+ <primary><envar>PGSSLPROTOCOLS</envar></primary>
+ </indexterm>
+ <envar>PGSSLPROTOCOLS</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslprotocols"> connection parameter.
+ </para>
+ </listitem>
+
<listitem>
<para>
<indexterm>
diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile
new file mode 100644
index 09410c4..1c058ec
*** a/src/backend/libpq/Makefile
--- b/src/backend/libpq/Makefile
*************** OBJS = be-fsstubs.o be-secure.o auth.o c
*** 18,24 ****
pqformat.o pqmq.o pqsignal.o
ifeq ($(with_openssl),yes)
! OBJS += be-secure-openssl.o
endif
include $(top_srcdir)/src/backend/common.mk
--- 18,24 ----
pqformat.o pqmq.o pqsignal.o
ifeq ($(with_openssl),yes)
! OBJS += be-secure-openssl.o openssl.o
endif
include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
new file mode 100644
index b05364c..3801455
*** a/src/backend/libpq/be-secure-openssl.c
--- b/src/backend/libpq/be-secure-openssl.c
***************
*** 71,76 ****
--- 71,77 ----
#endif
#include "libpq/libpq.h"
+ #include "libpq/openssl.h"
#include "tcop/tcopprot.h"
#include "utils/memutils.h"
*************** KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n
*** 169,175 ****
void
be_tls_init(void)
{
! struct stat buf;
STACK_OF(X509_NAME) *root_cert_list = NULL;
--- 170,178 ----
void
be_tls_init(void)
{
! struct stat buf;
! long protocol_options,
! disallow_ssl_options;
STACK_OF(X509_NAME) *root_cert_list = NULL;
*************** be_tls_init(void)
*** 245,259 ****
SSLerrmessage())));
}
! /* set up ephemeral DH keys, and disallow SSL v2/v3 while at it */
SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
! SSL_CTX_set_options(SSL_context,
! SSL_OP_SINGLE_DH_USE |
! SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
/* set up ephemeral ECDH keys */
initialize_ecdh();
/* set up the allowed cipher list */
if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
elog(FATAL, "could not set the cipher list (no valid ciphers available)");
--- 248,278 ----
SSLerrmessage())));
}
! /* set up ephemeral DH keys */
SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
! SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE);
/* set up ephemeral ECDH keys */
initialize_ecdh();
+ /* set up the allowed protocol list */
+ if (!options_from_ssl_protocols_string(SSLProtocols, &protocol_options))
+ ereport(FATAL,
+ (errmsg("invalid SSL protocol list: %s", SSLProtocols),
+ errhint("are you missing 'ALL:' before '-BADPROTO'?")));
+
+ /* forcibly disallow SSLv2 and SSLv3 */
+ disallow_ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
+
+ if ((protocol_options & disallow_ssl_options) != disallow_ssl_options)
+ {
+ elog(WARNING, "removing SSLv2 and SSLv3 from SSL protocol list");
+ protocol_options |= disallow_ssl_options;
+ }
+ elog(DEBUG2, "disabling SSL protocols: %lx", protocol_options);
+
+ SSL_CTX_set_options(SSL_context, protocol_options);
+
/* set up the allowed cipher list */
if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
elog(FATAL, "could not set the cipher list (no valid ciphers available)");
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
new file mode 100644
index 41ec1ad..a5a5f3f
*** a/src/backend/libpq/be-secure.c
--- b/src/backend/libpq/be-secure.c
*************** int ssl_renegotiation_limit;
*** 52,58 ****
bool ssl_loaded_verify_locations = false;
#endif
! /* GUC variable controlling SSL cipher list */
char *SSLCipherSuites = NULL;
/* GUC variable for default ECHD curve. */
--- 52,59 ----
bool ssl_loaded_verify_locations = false;
#endif
! /* GUC variables controlling SSL protocol and cipher list */
! char *SSLProtocols = NULL;
char *SSLCipherSuites = NULL;
/* GUC variable for default ECHD curve. */
diff --git a/src/backend/libpq/openssl.c b/src/backend/libpq/openssl.c
new file mode 100644
index ...12cf7c0
*** a/src/backend/libpq/openssl.c
--- b/src/backend/libpq/openssl.c
***************
*** 0 ****
--- 1,124 ----
+ /*-------------------------------------------------------------------------
+ *
+ * openssl.c
+ * shared functions for OpenSSL support in the backend and frontend.
+ *
+ *
+ * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/backend/libpq/openssl.c
+ *
+ * Contains functions that both backend and frontend can use to setup a
+ * secure connection.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+ #include "postgres.h"
+
+ #include <openssl/ssl.h>
+ #if SSLEAY_VERSION_NUMBER >= 0x0907000L
+ #include <openssl/conf.h>
+ #endif
+
+ #include "libpq/libpq.h"
+ #include "libpq/openssl.h"
+
+ /*
+ * Parse the SSL allowed protocol list
+ *
+ * The logic here is inverted. OpenSSL does not take a list of
+ * protocols to use, but a list of protocols to avoid. We use the
+ * same bits with the opposite meaning, then invert the result.
+ */
+
+ #define SSL_PROTO_SSLv2 SSL_OP_NO_SSLv2
+ #define SSL_PROTO_SSLv3 SSL_OP_NO_SSLv3
+ #define SSL_PROTO_SSL (SSL_PROTO_SSLv2 | SSL_PROTO_SSLv3)
+ #define SSL_PROTO_TLSv1 SSL_OP_NO_TLSv1
+ #ifdef SSL_OP_NO_TLSv1_1
+ #define SSL_PROTO_TLSv1_1 SSL_OP_NO_TLSv1_1
+ #else
+ #define SSL_PROTO_TLSv1_1 0
+ #endif
+ #ifdef SSL_OP_NO_TLSv1_2
+ #define SSL_PROTO_TLSv1_2 SSL_OP_NO_TLSv1_2
+ #else
+ #define SSL_PROTO_TLSv1_2 0
+ #endif
+ #define SSL_PROTO_TLS (SSL_PROTO_TLSv1 | SSL_PROTO_TLSv1_1 | SSL_PROTO_TLSv1_2)
+ #define SSL_PROTO_ALL (SSL_PROTO_SSL | SSL_PROTO_TLS)
+ #define SSL_PROTO_NONE 0
+
+ #define str_is_token(str, tok, len) \
+ (len == sizeof(tok) - 1 && pg_strncasecmp(str, tok, len) == 0)
+
+
+ bool
+ options_from_ssl_protocols_string(const char *str, long *options)
+ {
+ long result, current;
+ const char *p, *q;
+ int action;
+
+ /*
+ * Iterate over the colon-separated list of protocols. If a protocol is
+ * preceded by a +, it is added to the list. If it is preceded by a -, it
+ * is removed from the list. If it is not preceded by anything, the list
+ * is set to exactly that protocol. "ALL" can be used to indicate all
+ * protocols, "NONE" to indicate no protocols, "SSL" to indicate all SSL
+ * protocols and "TLS" to indicate all TLS protocols.
+ */
+ result = SSL_PROTO_NONE;
+ for (p = q = str; *q; p = q + 1) {
+ for (q = p; *q && *q != ':'; ++q)
+ /* nothing */ ;
+ if (*p == '-' || *p == '+')
+ action = *p++;
+ else
+ action = '=';
+ if (str_is_token(p, "ALL", q - p))
+ current = SSL_PROTO_ALL;
+ else if (str_is_token(p, "NONE", q - p))
+ current = SSL_PROTO_NONE;
+ else if (str_is_token(p, SSL_TXT_SSLV2, q - p))
+ current = SSL_PROTO_SSLv2;
+ else if (str_is_token(p, SSL_TXT_SSLV3, q - p))
+ current = SSL_PROTO_SSLv3;
+ else if (str_is_token(p, "SSL", q - p))
+ current = SSL_PROTO_SSL;
+ else if (str_is_token(p, SSL_TXT_TLSV1, q - p))
+ current = SSL_PROTO_TLSv1;
+ #ifdef SSL_OP_NO_TLSv1_1
+ else if (str_is_token(p, SSL_TXT_TLSV1_1, q - p))
+ current = SSL_PROTO_TLSv1_1;
+ #endif
+ #ifdef SSL_OP_NO_TLSv1_2
+ else if (str_is_token(p, SSL_TXT_TLSV1_2, q - p))
+ current = SSL_PROTO_TLSv1_2;
+ #endif
+ else if (str_is_token(p, "TLS", q - p))
+ current = SSL_PROTO_TLS;
+ else
+ return false;
+ switch (action) {
+ case '+':
+ result |= current;
+ break;
+ case '-':
+ result &= ~current;
+ break;
+ default:
+ result = current;
+ break;
+ }
+ }
+ if (result == SSL_PROTO_NONE)
+ return false;
+
+ *options = (SSL_PROTO_ALL & ~result);
+ return true;
+ }
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
new file mode 100644
index d4d74ba..77b285c
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
*************** static struct config_string ConfigureNam
*** 3235,3240 ****
--- 3235,3255 ----
},
{
+ {"ssl_protocols", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+ gettext_noop("Sets the list of allowed SSL protocols."),
+ NULL,
+ GUC_SUPERUSER_ONLY
+ },
+ &SSLProtocols,
+ #ifdef USE_SSL
+ "ALL:-SSL",
+ #else
+ "none",
+ #endif
+ NULL, NULL, NULL
+ },
+
+ {
{"ssl_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
gettext_noop("Sets the list of allowed SSL ciphers."),
NULL,
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
new file mode 100644
index 4a89cb7..9c2abdb
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 79,84 ****
--- 79,85 ----
#authentication_timeout = 1min # 1s-600s
#ssl = off # (change requires restart)
+ #ssl_protocols = 'ALL:-SSL' # allowed SSL protocols
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
# (change requires restart)
#ssl_prefer_server_ciphers = on # (change requires restart)
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
new file mode 100644
index 2a61a9e..eb8dfee
*** a/src/include/libpq/libpq.h
--- b/src/include/libpq/libpq.h
*************** extern ssize_t secure_raw_write(Port *po
*** 108,113 ****
--- 108,114 ----
extern bool ssl_loaded_verify_locations;
/* GUCs */
+ extern char *SSLProtocols;
extern char *SSLCipherSuites;
extern char *SSLECDHCurve;
extern bool SSLPreferServerCiphers;
diff --git a/src/include/libpq/openssl.h b/src/include/libpq/openssl.h
new file mode 100644
index ...8067774
*** a/src/include/libpq/openssl.h
--- b/src/include/libpq/openssl.h
***************
*** 0 ****
--- 1,50 ----
+ /*-------------------------------------------------------------------------
+ *
+ * openssl.h
+ * declarations of shared functions for OpenSSL support in the backend and
+ * frontend.
+ *
+ *
+ * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/libpq/openssl.h
+ *
+ *-------------------------------------------------------------------------
+ */
+ #ifndef LIBPQ_OPENSSL_H
+ #define LIBPQ_OPENSSL_H
+
+ /*
+ * Parse the list of SSL protocols in the colon-separated format and return a
+ * bitmask of options to be passed to SSL_CTX_set_options().
+ *
+ * Recognized protocol names are SSLv2, SSLv3 and TLSv1.
+ *
+ * In case the OpenSSL version defines SSL_OP_NO_TLSv1_1, the string TLSv1.1
+ * is also recognized (ditto for SSL_OP_NO_TLSv1_2 and TLSv1.2).
+ *
+ * Additionally, SSL means all supported SSL versions, the same goes for TLS.
+ * Furthermore, ALL means all supported protocols (and NONE, well you've
+ * guessed it.)
+ *
+ * A plus sign before the protocol name includes a protocol in the list, minus
+ * removes, otherwise replaces the whole list.
+ *
+ * Example: ALL:-SSL
+ *
+ * The above example includes all supported protocols except all SSL versions
+ * (SSLv2 and SSLv3).
+ *
+ * Since OpenSSL API only let you *exclude* protocols in the options, the
+ * resulting bitmask will have SSL_OP_NO_<protocol> flags set for which there
+ * were protocols listed with a minus sign.
+ *
+ * Returns true on success, false otherwise (i.e. unrecognized protocol
+ * found in the list).
+ *
+ * On success, stores the result of parsing in the options out-parameter.
+ */
+ extern bool options_from_ssl_protocols_string(const char *str, long *options);
+
+ #endif /* LIBPQ_OPENSSL_H */
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
new file mode 100644
index 18d9b85..15c00a3
*** a/src/interfaces/libpq/Makefile
--- b/src/interfaces/libpq/Makefile
*************** OBJS += chklocale.o inet_net_ntop.o nobl
*** 40,51 ****
--- 40,55 ----
# libpgport C files that are needed if identified by configure
OBJS += $(filter crypt.o getaddrinfo.o getpeereid.o inet_aton.o open.o system.o snprintf.o strerror.o strlcpy.o win32error.o win32setlocale.o, $(LIBOBJS))
# backend/libpq
+ backend_c = ip.c md5.c
OBJS += ip.o md5.o
# utils/mb
OBJS += encnames.o wchar.o
ifeq ($(with_openssl),yes)
OBJS += fe-secure-openssl.o
+ # backend/libpq
+ backend_c += openssl.c
+ OBJS += openssl.o
endif
ifeq ($(PORTNAME), cygwin)
*************** backend_src = $(top_srcdir)/src/backend
*** 96,102 ****
chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c inet_net_ntop.c noblock.c open.c system.c pgsleep.c pgstrcasecmp.c pqsignal.c snprintf.c strerror.c strlcpy.c thread.c win32error.c win32setlocale.c: % : $(top_srcdir)/src/port/%
rm -f $@ && $(LN_S) $< .
! ip.c md5.c: % : $(backend_src)/libpq/%
rm -f $@ && $(LN_S) $< .
encnames.c wchar.c: % : $(backend_src)/utils/mb/%
--- 100,106 ----
chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c inet_net_ntop.c noblock.c open.c system.c pgsleep.c pgstrcasecmp.c pqsignal.c snprintf.c strerror.c strlcpy.c thread.c win32error.c win32setlocale.c: % : $(top_srcdir)/src/port/%
rm -f $@ && $(LN_S) $< .
! $(backend_c): % : $(backend_src)/libpq/%
rm -f $@ && $(LN_S) $< .
encnames.c wchar.c: % : $(backend_src)/utils/mb/%
*************** clean distclean: clean-lib
*** 156,162 ****
rm -f inet_net_ntop.c noblock.c pgstrcasecmp.c pqsignal.c thread.c
rm -f chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c open.c system.c snprintf.c strerror.c strlcpy.c win32error.c win32setlocale.c
rm -f pgsleep.c
! rm -f md5.c ip.c
rm -f encnames.c wchar.c
maintainer-clean: distclean maintainer-clean-lib
--- 160,166 ----
rm -f inet_net_ntop.c noblock.c pgstrcasecmp.c pqsignal.c thread.c
rm -f chklocale.c crypt.c getaddrinfo.c getpeereid.c inet_aton.c open.c system.c snprintf.c strerror.c strlcpy.c win32error.c win32setlocale.c
rm -f pgsleep.c
! rm -f $(backend_c)
rm -f encnames.c wchar.c
maintainer-clean: distclean maintainer-clean-lib
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
new file mode 100644
index 703cbac..0e10a58
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
*************** static const internalPQconninfoOption PQ
*** 254,259 ****
--- 254,263 ----
"SSL-Mode", "", 12, /* sizeof("verify-full") == 12 */
offsetof(struct pg_conn, sslmode)},
+ {"sslprotocols", "PGSSLPROTOCOLS", "ALL:-SSL", NULL,
+ "SSL-Protocols", "", 10,
+ offsetof(struct pg_conn, sslprotocols)},
+
{"sslcompression", "PGSSLCOMPRESSION", "1", NULL,
"SSL-Compression", "", 1,
offsetof(struct pg_conn, sslcompression)},
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
new file mode 100644
index 78aa46d..0d174bd
*** a/src/interfaces/libpq/fe-secure-openssl.c
--- b/src/interfaces/libpq/fe-secure-openssl.c
***************
*** 29,34 ****
--- 29,35 ----
#include "libpq-fe.h"
#include "fe-auth.h"
#include "libpq-int.h"
+ #include "libpq/openssl.h"
#ifdef WIN32
#include "win32.h"
*************** pgtls_init(PGconn *conn)
*** 806,811 ****
--- 807,814 ----
if (!SSL_context)
{
+ long protocol_options;
+
if (pq_init_ssl_lib)
{
#if SSLEAY_VERSION_NUMBER >= 0x00907000L
*************** pgtls_init(PGconn *conn)
*** 836,843 ****
return -1;
}
/* Disable old protocol versions */
! SSL_CTX_set_options(SSL_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
/*
* Disable OpenSSL's moving-write-buffer sanity check, because it
--- 839,859 ----
return -1;
}
+ /* set up the allowed protocol list */
+ if (!options_from_ssl_protocols_string(conn->sslprotocols,
+ &protocol_options))
+ {
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("invalid SSL protocols list (are you missing 'ALL:' before '-BADPROTO'?)\n"));
+ #ifdef ENABLE_THREAD_SAFETY
+ pthread_mutex_unlock(&ssl_config_mutex);
+ #endif
+ return -1;
+ }
+
/* Disable old protocol versions */
! protocol_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
! SSL_CTX_set_options(SSL_context, protocol_options);
/*
* Disable OpenSSL's moving-write-buffer sanity check, because it
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
new file mode 100644
index 4ef46ff..d7c2b78
*** a/src/interfaces/libpq/libpq-int.h
--- b/src/interfaces/libpq/libpq-int.h
*************** struct pg_conn
*** 324,329 ****
--- 324,330 ----
char *keepalives_count; /* maximum number of TCP keepalive
* retransmits */
char *sslmode; /* SSL mode (require,prefer,allow,disable) */
+ char *sslprotocols; /* SSL protocols (e.g, "ALL:-SSL") */
char *sslcompression; /* SSL compression (0 or 1) */
char *sslkey; /* client key filename */
char *sslcert; /* client certificate filename */
--
2.1.0