v1-2-client-Disable-GSS-encryption-on-old-servers.patch
text/x-diff
Filename: v1-2-client-Disable-GSS-encryption-on-old-servers.patch
Type: text/x-diff
Part: 1
Message:
[PATCH v1] GSSAPI encryption support
Patch
Format: format-patch
Series: patch v1
Subject: client: Disable GSS encryption on old servers
| File | + | − |
|---|---|---|
| src/interfaces/libpq/fe-connect.c | 32 | 2 |
| src/interfaces/libpq/fe-protocol3.c | 5 | 0 |
| src/interfaces/libpq/libpq-int.h | 1 | 0 |
From d5b973752968f87c9bb2ff9434d523657eb4ba67 Mon Sep 17 00:00:00 2001
From: "Robbie Harwood (frozencemetery)" <rharwood@redhat.com>
Date: Mon, 8 Jun 2015 20:16:42 -0400
Subject: client: Disable GSS encryption on old servers
---
src/interfaces/libpq/fe-connect.c | 34 ++++++++++++++++++++++++++++++++--
src/interfaces/libpq/fe-protocol3.c | 5 +++++
src/interfaces/libpq/libpq-int.h | 1 +
3 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index a45f4cb..c6c551a 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -91,8 +91,9 @@ static int ldapServiceLookup(const char *purl, PQconninfoOption *options,
* application_name in a startup packet. We hard-wire the value rather
* than looking into errcodes.h since it reflects historical behavior
* rather than that of the current code.
+ * Servers that do not support GSS encryption will also return this error.
*/
-#define ERRCODE_APPNAME_UNKNOWN "42704"
+#define ERRCODE_UNKNOWN_PARAM "42704"
/* This is part of the protocol so just define it */
#define ERRCODE_INVALID_PASSWORD "28P01"
@@ -2552,6 +2553,35 @@ keep_going: /* We will come back to here until there is
if (res->resultStatus != PGRES_FATAL_ERROR)
appendPQExpBufferStr(&conn->errorMessage,
libpq_gettext("unexpected message from server during startup\n"));
+#ifdef ENABLE_GSS
+ else if (!conn->gss_disable_enc)
+ {
+ /*
+ * We tried to request GSS encryption, but the server
+ * doesn't support it. Hang up and try again. A
+ * connection that doesn't support appname will also
+ * not support GSSAPI encryption, so this check goes
+ * before that check. See comment below.
+ */
+ const char *sqlstate;
+
+ sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
+ if (sqlstate &&
+ strcmp(sqlstate, ERRCODE_UNKNOWN_PARAM) == 0)
+ {
+ OM_uint32 minor;
+
+ PQclear(res);
+ conn->gss_disable_enc = true;
+ /* Must drop the old connection */
+ pqDropConnection(conn);
+ conn->status = CONNECTION_NEEDED;
+ gss_delete_sec_context(&minor, &conn->gctx,
+ GSS_C_NO_BUFFER);
+ goto keep_going;
+ }
+ }
+#endif
else if (conn->send_appname &&
(conn->appname || conn->fbappname))
{
@@ -2569,7 +2599,7 @@ keep_going: /* We will come back to here until there is
sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
if (sqlstate &&
- strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0)
+ strcmp(sqlstate, ERRCODE_UNKNOWN_PARAM) == 0)
{
PQclear(res);
conn->send_appname = false;
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index a847f08..0deaa0f 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -2051,6 +2051,11 @@ build_startup_packet(const PGconn *conn, char *packet,
if (conn->client_encoding_initial && conn->client_encoding_initial[0])
ADD_STARTUP_OPTION("client_encoding", conn->client_encoding_initial);
+#ifdef ENABLE_GSS
+ if (!conn->gss_disable_enc)
+ ADD_STARTUP_OPTION("gss_encrypt", "on");
+#endif
+
/* Add any environment-driven GUC settings needed */
for (next_eo = options; next_eo->envName; next_eo++)
{
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 2175957..1578d76 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -445,6 +445,7 @@ struct pg_conn
gss_name_t gtarg_nam; /* GSS target name */
gss_buffer_desc ginbuf; /* GSS input token */
gss_buffer_desc goutbuf; /* GSS output token */
+ bool gss_disable_enc; /* Does server recognize gss_encrypt? */
#endif
#ifdef ENABLE_SSPI
--
2.1.4