Revert changes for SSL compression in libpq
authorMichael Paquier <michael@paquier.xyz>
Wed, 10 Mar 2021 00:35:42 +0000 (09:35 +0900)
committerMichael Paquier <michael@paquier.xyz>
Wed, 10 Mar 2021 00:35:42 +0000 (09:35 +0900)
This partially reverts 096bbf7 and 9d2d457, undoing the libpq changes as
it could cause breakages in distributions that share one single libpq
version across multiple major versions of Postgres for extensions and
applications linking to that.

Note that the backend is unchanged here, and it still disables SSL
compression while simplifying the underlying catalogs that tracked if
compression was enabled or not for a SSL connection.

Per discussion with Tom Lane and Daniel Gustafsson.

Discussion: https://postgr.es/m/YEbq15JKJwIX+S6m@paquier.xyz

contrib/postgres_fdw/expected/postgres_fdw.out
contrib/postgres_fdw/sql/postgres_fdw.sql
doc/src/sgml/libpq.sgml
src/bin/psql/command.c
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-secure-openssl.c
src/interfaces/libpq/libpq-int.h
src/test/ssl/t/001_ssltests.pl

index f17f3b6c294f2aa80eb1a758dcdc2ebeb7c31e11..0649b6b81cd926f0e8158f55eca7616cb48ba93a 100644 (file)
@@ -163,11 +163,11 @@ ALTER SERVER testserver1 OPTIONS (
    keepalives_interval 'value',
    tcp_user_timeout 'value',
    -- requiressl 'value',
+   sslcompression 'value',
    sslmode 'value',
    sslcert 'value',
    sslkey 'value',
    sslrootcert 'value',
-   sslcompression 'value',
    sslcrl 'value',
    --requirepeer 'value',
    krbsrvname 'value',
index be5618f759211df63acf207b7ffe451488e363d5..2b525ea44a88bc5dc432d73a96ce7110a30da1b3 100644 (file)
@@ -177,11 +177,11 @@ ALTER SERVER testserver1 OPTIONS (
    keepalives_interval 'value',
    tcp_user_timeout 'value',
    -- requiressl 'value',
+   sslcompression 'value',
    sslmode 'value',
    sslcert 'value',
    sslkey 'value',
    sslrootcert 'value',
-   sslcompression 'value',
    sslcrl 'value',
    --requirepeer 'value',
    krbsrvname 'value',
index 2e0c06102ee7386a7d187ab1305275c5566d2a74..910e9a81eaf76fc39462895c3756bf3ce9306175 100644 (file)
@@ -1640,7 +1640,26 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
       <term><literal>sslcompression</literal></term>
       <listitem>
        <para>
-        Ignored (formerly, this specified whether to attempt SSL compression).
+        If set to 1, data sent over SSL connections will be compressed.  If
+        set to 0, compression will be disabled.  The default is 0.  This
+        parameter is ignored if a connection without SSL is made.
+       </para>
+
+       <para>
+        SSL compression is nowadays considered insecure and its use is no
+        longer recommended.  <productname>OpenSSL</productname> 1.1.0 disables
+        compression by default, and many operating system distributions
+        disable it in prior versions as well, so setting this parameter to on
+        will not have any effect if the server does not accept compression.
+        <productname>PostgreSQL</productname> 14 disables compression
+        completely in the backend.
+       </para>
+
+       <para>
+        If security is not a primary concern, compression can improve
+        throughput if the network is the bottleneck.  Disabling compression
+        can improve response time and throughput if CPU performance is the
+        limiting factor.
        </para>
       </listitem>
      </varlistentry>
@@ -2533,7 +2552,9 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);
          <term><literal>compression</literal></term>
           <listitem>
            <para>
-            SSL compression is no longer supported, always returns "off".
+            If SSL compression is in use, returns the name of the compression
+            algorithm, or "on" if compression is used but the algorithm is
+            not known. If compression is not in use, returns "off".
            </para>
           </listitem>
          </varlistentry>
@@ -7168,6 +7189,16 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
      </para>
     </listitem>
 
+    <listitem>
+     <para>
+      <indexterm>
+       <primary><envar>PGSSLCOMPRESSION</envar></primary>
+      </indexterm>
+      <envar>PGSSLCOMPRESSION</envar> behaves the same as the <xref
+      linkend="libpq-connect-sslcompression"/> connection parameter.
+     </para>
+    </listitem>
+
     <listitem>
      <para>
       <indexterm>
index 8d6970a4f341eec0120dc7d72ddc42938b3fc61f..c98e3d31d0c711d0bf5d05bf8f61031a172e9e67 100644 (file)
@@ -3509,6 +3509,7 @@ printSSLInfo(void)
    const char *protocol;
    const char *cipher;
    const char *bits;
+   const char *compression;
 
    if (!PQsslInUse(pset.db))
        return;                 /* no SSL */
@@ -3516,11 +3517,13 @@ printSSLInfo(void)
    protocol = PQsslAttribute(pset.db, "protocol");
    cipher = PQsslAttribute(pset.db, "cipher");
    bits = PQsslAttribute(pset.db, "key_bits");
+   compression = PQsslAttribute(pset.db, "compression");
 
-   printf(_("SSL connection (protocol: %s, cipher: %s, bits: %s)\n"),
+   printf(_("SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n"),
           protocol ? protocol : _("unknown"),
           cipher ? cipher : _("unknown"),
-          bits ? bits : _("unknown"));
+          bits ? bits : _("unknown"),
+          (compression && strcmp(compression, "off") != 0) ? _("on") : _("off"));
 }
 
 /*
index aeb64c5bca335d2bea78085810f69157f8672e86..29054bad7b4bb5ffd9327500d05b8e5cd56d8661 100644 (file)
@@ -275,12 +275,9 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
        "SSL-Mode", "", 12,     /* sizeof("verify-full") == 12 */
    offsetof(struct pg_conn, sslmode)},
 
-   /*
-    * "sslcompression" is no longer used, but keep it present for backwards
-    * compatibility.
-    */
-   {"sslcompression", NULL, NULL, NULL,
-   "SSL-Compression", "", 1, -1},
+   {"sslcompression", "PGSSLCOMPRESSION", "0", NULL,
+       "SSL-Compression", "", 1,
+   offsetof(struct pg_conn, sslcompression)},
 
    {"sslcert", "PGSSLCERT", NULL, NULL,
        "SSL-Client-Cert", "", 64,
@@ -4054,6 +4051,8 @@ freePGconn(PGconn *conn)
        free(conn->sslcrl);
    if (conn->sslcrldir)
        free(conn->sslcrldir);
+   if (conn->sslcompression)
+       free(conn->sslcompression);
    if (conn->requirepeer)
        free(conn->requirepeer);
    if (conn->ssl_min_protocol_version)
index c88dd3a118321686c61074490fa25a69417bd89c..0fa10a23b4a5d652913c51ec3fed32c34a988e1e 100644 (file)
@@ -1257,8 +1257,13 @@ initialize_SSL(PGconn *conn)
    if (have_rootcert)
        SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, verify_cb);
 
-   /* disable SSL compression */
-   SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION);
+   /*
+    * Set compression option if necessary.
+    */
+   if (conn->sslcompression && conn->sslcompression[0] == '0')
+       SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION);
+   else
+       SSL_clear_options(conn->ssl, SSL_OP_NO_COMPRESSION);
 
    return 0;
 }
@@ -1548,12 +1553,8 @@ PQsslAttribute(PGconn *conn, const char *attribute_name)
    if (strcmp(attribute_name, "cipher") == 0)
        return SSL_get_cipher(conn->ssl);
 
-   /*
-    * SSL compression is disabled, so even if connecting to an older server
-    * which still supports it, it will not be active.
-    */
    if (strcmp(attribute_name, "compression") == 0)
-       return "off";
+       return SSL_get_current_compression(conn->ssl) ? "on" : "off";
 
    if (strcmp(attribute_name, "protocol") == 0)
        return SSL_get_version(conn->ssl);
index 0965c5ac511be17c6b8d1bcbeec5b3d2bea61766..adf149a76f9cae10e89829f8bd4d2b71d2d8aaa0 100644 (file)
@@ -358,6 +358,7 @@ struct pg_conn
    char       *keepalives_count;   /* maximum number of TCP keepalive
                                     * retransmits */
    char       *sslmode;        /* SSL mode (require,prefer,allow,disable) */
+   char       *sslcompression; /* SSL compression (0 or 1) */
    char       *sslkey;         /* client key filename */
    char       *sslcert;        /* client certificate filename */
    char       *sslpassword;    /* client key file password */
index ee97f6f069725ac79072757f5e9344c409376a76..bfada03d3eb962cdc5ac68486506b4c1e2065090 100644 (file)
@@ -17,7 +17,7 @@ if ($ENV{with_ssl} ne 'openssl')
 }
 else
 {
-   plan tests => 101;
+   plan tests => 100;
 }
 
 #### Some configuration
@@ -157,13 +157,6 @@ test_connect_fails(
    qr/root certificate file "invalid" does not exist/,
    "connect without server root cert sslmode=verify-full");
 
-# Test deprecated SSL parameters, still accepted for backwards
-# compatibility.
-test_connect_ok(
-   $common_connstr,
-   "sslrootcert=invalid sslmode=require sslcompression=1 requiressl=1",
-   "connect with deprecated connection parameters");
-
 # Try with wrong root cert, should fail. (We're using the client CA as the
 # root, but the server's key is signed by the server CA.)
 test_connect_fails($common_connstr,