Fix assorted error-cleanup bugs in SSL min/max protocol version code.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 2 Feb 2020 18:09:33 +0000 (13:09 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 2 Feb 2020 18:09:33 +0000 (13:09 -0500)
The error exits added to initialize_SSL() failed to clean up the
partially-built SSL_context, and some of them also leaked the
result of SSLerrmessage().  Make them match other error-handling
cases in that function.

The error exits added to connectOptions2() failed to set conn->status
like every other error exit in that function.

In passing, make the SSL_get_peer_certificate() error exit look more
like all the other calls of SSLerrmessage().

Oversights in commit ff8ca5fad.  Coverity whined about leakage of the
SSLerrmessage() results; I noted the rest in manual code review.

src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-secure-openssl.c

index 99cd6c41176598b1562baa73fc8ea84f5c3a9b08..408000af83aaae7ec1d5cf3be3a460cecaacc233 100644 (file)
@@ -1306,6 +1306,7 @@ connectOptions2(PGconn *conn)
         */
        if (!sslVerifyProtocolVersion(conn->sslminprotocolversion))
        {
+               conn->status = CONNECTION_BAD;
                printfPQExpBuffer(&conn->errorMessage,
                                                  libpq_gettext("invalid sslminprotocolversion value: \"%s\"\n"),
                                                  conn->sslminprotocolversion);
@@ -1313,6 +1314,7 @@ connectOptions2(PGconn *conn)
        }
        if (!sslVerifyProtocolVersion(conn->sslmaxprotocolversion))
        {
+               conn->status = CONNECTION_BAD;
                printfPQExpBuffer(&conn->errorMessage,
                                                  libpq_gettext("invalid sslmaxprotocolversion value: \"%s\"\n"),
                                                  conn->sslmaxprotocolversion);
@@ -1329,6 +1331,7 @@ connectOptions2(PGconn *conn)
        if (!sslVerifyProtocolRange(conn->sslminprotocolversion,
                                                                conn->sslmaxprotocolversion))
        {
+               conn->status = CONNECTION_BAD;
                printfPQExpBuffer(&conn->errorMessage,
                                                  libpq_gettext("invalid SSL protocol version range"));
                return false;
index cf142fbaa48162fa835eefbcf869ffcd3ca23bdd..d3a37e1d273f8429ebc1034e21a123bcefeac081 100644 (file)
@@ -854,6 +854,7 @@ initialize_SSL(PGconn *conn)
                        printfPQExpBuffer(&conn->errorMessage,
                                                          libpq_gettext("invalid value \"%s\" for minimum version of SSL protocol\n"),
                                                          conn->sslminprotocolversion);
+                       SSL_CTX_free(SSL_context);
                        return -1;
                }
 
@@ -864,6 +865,8 @@ initialize_SSL(PGconn *conn)
                        printfPQExpBuffer(&conn->errorMessage,
                                                          libpq_gettext("could not set minimum version of SSL protocol: %s\n"),
                                                          err);
+                       SSLerrfree(err);
+                       SSL_CTX_free(SSL_context);
                        return -1;
                }
        }
@@ -880,6 +883,7 @@ initialize_SSL(PGconn *conn)
                        printfPQExpBuffer(&conn->errorMessage,
                                                          libpq_gettext("invalid value \"%s\" for maximum version of SSL protocol\n"),
                                                          conn->sslmaxprotocolversion);
+                       SSL_CTX_free(SSL_context);
                        return -1;
                }
 
@@ -890,6 +894,8 @@ initialize_SSL(PGconn *conn)
                        printfPQExpBuffer(&conn->errorMessage,
                                                          libpq_gettext("could not set maximum version of SSL protocol: %s\n"),
                                                          err);
+                       SSLerrfree(err);
+                       SSL_CTX_free(SSL_context);
                        return -1;
                }
        }
@@ -1321,9 +1327,7 @@ open_client_SSL(PGconn *conn)
        conn->peer = SSL_get_peer_certificate(conn->ssl);
        if (conn->peer == NULL)
        {
-               char       *err;
-
-               err = SSLerrmessage(ERR_get_error());
+               char       *err = SSLerrmessage(ERR_get_error());
 
                printfPQExpBuffer(&conn->errorMessage,
                                                  libpq_gettext("certificate could not be obtained: %s\n"),