From 67ef63a681c9eef27d22975b98b8968cd63ace95 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 8 Mar 2016 17:16:29 -0500
Subject: [PATCH 3/3] GSSAPI authentication cleanup

Become more fussy about what flags we need.  Now that we want to do
encryption, protection and integrity are needed for that to work.  Other
protections are desirable as well, and we should check the flags GSSAPI
returns to us.

Also remove the (now-)redundant definitions that worked around an old
bug with MIT Kerberos on Windows.
---
 src/backend/libpq/auth.c                | 14 +++++++++++---
 src/backend/libpq/be-gssapi-common.c    | 11 -----------
 src/interfaces/libpq/fe-auth.c          | 19 ++++++++++++++++---
 src/interfaces/libpq/fe-gssapi-common.c | 11 -----------
 4 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 20e8953..3ce40a7 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -717,7 +717,8 @@ pg_GSS_recvauth(Port *port)
 	OM_uint32	maj_stat,
 				min_stat,
 				lmin_s,
-				gflags;
+				gflags,
+				target_flags;
 	int			mtype;
 	int			ret;
 	StringInfoData buf;
@@ -815,8 +816,7 @@ pg_GSS_recvauth(Port *port)
 		elog(DEBUG4, "Processing received GSS token of length %u",
 			 (unsigned int) gbuf.length);
 
-		maj_stat = gss_accept_sec_context(
-										  &min_stat,
+		maj_stat = gss_accept_sec_context(&min_stat,
 										  &port->gss->ctx,
 										  port->gss->cred,
 										  &gbuf,
@@ -872,6 +872,14 @@ pg_GSS_recvauth(Port *port)
 		gss_release_cred(&min_stat, &port->gss->cred);
 	}
 
+	target_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
+		GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG;
+	if ((gflags & target_flags) != target_flags)
+	{
+		ereport(FATAL, (errmsg("GSSAPI did no provide required flags")));
+		return STATUS_ERROR;
+	}
+
 	/*
 	 * GSS_S_COMPLETE indicates that authentication is now complete.
 	 *
diff --git a/src/backend/libpq/be-gssapi-common.c b/src/backend/libpq/be-gssapi-common.c
index 541a18e..73b7962 100644
--- a/src/backend/libpq/be-gssapi-common.c
+++ b/src/backend/libpq/be-gssapi-common.c
@@ -17,17 +17,6 @@
 
 #include "postgres.h"
 
-#if defined(WIN32) && !defined(WIN32_ONLY_COMPILER)
-/*
- * MIT Kerberos GSSAPI DLL doesn't properly export the symbols for MingW
- * that contain the OIDs required. Redefine here, values copied
- * from src/athena/auth/krb5/src/lib/gssapi/generic/gssapi_generic.c
- */
-static const gss_OID_desc GSS_C_NT_USER_NAME_desc =
-{10, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"};
-static GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_desc;
-#endif
-
 void
 pg_GSS_error(int severity, char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat)
 {
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 56528f2..76bc3ec 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -57,20 +57,24 @@ pg_GSS_continue(PGconn *conn)
 {
 	OM_uint32	maj_stat,
 				min_stat,
-				lmin_s;
+				lmin_s,
+				req_flags,
+				ret_flags;
 
+	req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG |
+		GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG;
 	maj_stat = gss_init_sec_context(&min_stat,
 									GSS_C_NO_CREDENTIAL,
 									&conn->gctx,
 									conn->gtarg_nam,
 									GSS_C_NO_OID,
-									GSS_C_MUTUAL_FLAG,
+									req_flags,
 									0,
 									GSS_C_NO_CHANNEL_BINDINGS,
 		  (conn->gctx == GSS_C_NO_CONTEXT) ? GSS_C_NO_BUFFER : &conn->ginbuf,
 									NULL,
 									&conn->goutbuf,
-									NULL,
+									&ret_flags,
 									NULL);
 
 	if (conn->gctx != GSS_C_NO_CONTEXT)
@@ -109,8 +113,17 @@ pg_GSS_continue(PGconn *conn)
 	}
 
 	if (maj_stat == GSS_S_COMPLETE)
+	{
 		gss_release_name(&lmin_s, &conn->gtarg_nam);
 
+		if ((ret_flags & req_flags) != req_flags)
+		{
+			printfPQExpBuffer(&conn->errorMessage,
+							  libpq_gettext("GSSAPI did not provide required flags\n"));
+			return STATUS_ERROR;
+		}
+	}
+
 	return STATUS_OK;
 }
 
diff --git a/src/interfaces/libpq/fe-gssapi-common.c b/src/interfaces/libpq/fe-gssapi-common.c
index cd7ae5a..0ad09f7 100644
--- a/src/interfaces/libpq/fe-gssapi-common.c
+++ b/src/interfaces/libpq/fe-gssapi-common.c
@@ -15,17 +15,6 @@
 #include "fe-auth.h"
 #include "fe-gssapi-common.h"
 
-#if defined(WIN32) && !defined(WIN32_ONLY_COMPILER)
-/*
- * MIT Kerberos GSSAPI DLL doesn't properly export the symbols for MingW
- * that contain the OIDs required. Redefine here, values copied
- * from src/athena/auth/krb5/src/lib/gssapi/generic/gssapi_generic.c
- */
-static const gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_desc =
-{10, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"};
-static GSS_DLLIMP gss_OID GSS_C_NT_HOSTBASED_SERVICE = &GSS_C_NT_HOSTBASED_SERVICE_desc;
-#endif
-
 /*
  * Fetch all errors of a specific type and append to "str".
  */
-- 
2.7.0

