diff options
-rw-r--r-- | contrib/postgres_fdw/expected/postgres_fdw.out | 2 | ||||
-rw-r--r-- | doc/src/sgml/libpq.sgml | 31 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-connect.c | 6 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-secure-openssl.c | 22 | ||||
-rw-r--r-- | src/interfaces/libpq/libpq-int.h | 1 |
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 */ |