summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/postgres_fdw/expected/postgres_fdw.out2
-rw-r--r--doc/src/sgml/libpq.sgml31
-rw-r--r--src/interfaces/libpq/fe-connect.c6
-rw-r--r--src/interfaces/libpq/fe-secure-openssl.c22
-rw-r--r--src/interfaces/libpq/libpq-int.h1
5 files changed, 61 insertions, 1 deletions
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index 9d472d2d3d..eeb6ae79d0 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -8917,7 +8917,7 @@ DO $d$
END;
$d$;
ERROR: invalid option "password"
-HINT: Valid options in this context are: service, passfile, channel_binding, connect_timeout, dbname, host, hostaddr, port, options, application_name, keepalives, keepalives_idle, keepalives_interval, keepalives_count, tcp_user_timeout, sslmode, sslcompression, sslcert, sslkey, sslrootcert, sslcrl, sslcrldir, requirepeer, ssl_min_protocol_version, ssl_max_protocol_version, gssencmode, krbsrvname, gsslib, target_session_attrs, use_remote_estimate, fdw_startup_cost, fdw_tuple_cost, extensions, updatable, fetch_size, batch_size, async_capable, keep_connections
+HINT: Valid options in this context are: service, passfile, channel_binding, connect_timeout, dbname, host, hostaddr, port, options, application_name, keepalives, keepalives_idle, keepalives_interval, keepalives_count, tcp_user_timeout, sslmode, sslcompression, sslcert, sslkey, sslrootcert, sslcrl, sslcrldir, sslsni, requirepeer, ssl_min_protocol_version, ssl_max_protocol_version, gssencmode, krbsrvname, gsslib, target_session_attrs, use_remote_estimate, fdw_startup_cost, fdw_tuple_cost, extensions, updatable, fetch_size, batch_size, async_capable, keep_connections
CONTEXT: SQL statement "ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw')"
PL/pgSQL function inline_code_block line 3 at EXECUTE
-- If we add a password for our user mapping instead, we should get a different
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 3ec458ce09..52622fe4c1 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1777,6 +1777,27 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
</listitem>
</varlistentry>
+ <varlistentry id="libpq-connect-sslsni" xreflabel="sslsni">
+ <term><literal>sslsni</literal><indexterm><primary>Server Name Indication</primary></indexterm></term>
+ <listitem>
+ <para>
+ By default, libpq sets the TLS extension <quote>Server Name
+ Indication</quote> (SNI) on SSL-enabled connections. See <ulink
+ url="https://tools.ietf.org/html/rfc6066#section-3">RFC 6066</ulink>
+ for details. By setting this parameter to 0, this is turned off.
+ </para>
+
+ <para>
+ The Server Name Indication can be used by SSL-aware proxies to route
+ connections without having to decrypt the SSL stream. (Note that this
+ requires a proxy that is aware of the PostgreSQL protocol handshake,
+ not just any SSL proxy.) However, SNI makes the destination host name
+ appear in cleartext in the network traffic, so it might be undesirable
+ in some cases.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="libpq-connect-requirepeer" xreflabel="requirepeer">
<term><literal>requirepeer</literal></term>
<listitem>
@@ -7800,6 +7821,16 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
<listitem>
<para>
<indexterm>
+ <primary><envar>PGSSLSNI</envar></primary>
+ </indexterm>
+ <envar>PGSSLSNI</envar> behaves the same as the <xref
+ linkend="libpq-connect-sslsni"/> connection parameter.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <indexterm>
<primary><envar>PGREQUIREPEER</envar></primary>
</indexterm>
<envar>PGREQUIREPEER</envar> behaves the same as the <xref
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 56a8266bc3..aa654dd6a8 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -303,6 +303,10 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
"SSL-Revocation-List-Dir", "", 64,
offsetof(struct pg_conn, sslcrldir)},
+ {"sslsni", "PGSSLSNI", "1", NULL,
+ "SSL-SNI", "", 1,
+ offsetof(struct pg_conn, sslsni)},
+
{"requirepeer", "PGREQUIREPEER", NULL, NULL,
"Require-Peer", "", 10,
offsetof(struct pg_conn, requirepeer)},
@@ -4095,6 +4099,8 @@ freePGconn(PGconn *conn)
free(conn->sslcrldir);
if (conn->sslcompression)
free(conn->sslcompression);
+ if (conn->sslsni)
+ free(conn->sslsni);
if (conn->requirepeer)
free(conn->requirepeer);
if (conn->ssl_min_protocol_version)
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 9c2222c1d1..6f357dfbfe 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1083,6 +1083,28 @@ initialize_SSL(PGconn *conn)
SSL_context = NULL;
/*
+ * Set Server Name Indication (SNI), if enabled by connection parameters.
+ * Per RFC 6066, do not set it if the host is a literal IP address (IPv4
+ * or IPv6).
+ */
+ if (conn->sslsni && conn->sslsni[0] &&
+ !(strspn(conn->pghost, "0123456789.") == strlen(conn->pghost) ||
+ strchr(conn->pghost, ':')))
+ {
+ if (SSL_set_tlsext_host_name(conn->ssl, conn->pghost) != 1)
+ {
+ char *err = SSLerrmessage(ERR_get_error());
+
+ appendPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("could not set SSL Server Name Indication (SNI): %s\n"),
+ err);
+ SSLerrfree(err);
+ SSL_CTX_free(SSL_context);
+ return -1;
+ }
+ }
+
+ /*
* Read the SSL key. If a key is specified, treat it as an engine:key
* combination if there is colon present - we don't support files with
* colon in the name. The exception is if the second character is a colon,
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 3f7907127e..e81dc37906 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -383,6 +383,7 @@ struct pg_conn
char *sslrootcert; /* root certificate filename */
char *sslcrl; /* certificate revocation list filename */
char *sslcrldir; /* certificate revocation list directory name */
+ char *sslsni; /* use SSL SNI extension (0 or 1) */
char *requirepeer; /* required peer credentials for local sockets */
char *gssencmode; /* GSS mode (require,prefer,disable) */
char *krbsrvname; /* Kerberos service name */