aboutsummaryrefslogtreecommitdiff
path: root/src/backend/postmaster/postmaster.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/postmaster/postmaster.c')
-rw-r--r--src/backend/postmaster/postmaster.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index fe599632d3d..067487fdcb0 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1889,9 +1889,12 @@ initMasks(fd_set *rmask)
* if that's what you want. Return STATUS_ERROR if you don't want to
* send anything to the client, which would typically be appropriate
* if we detect a communications failure.)
+ *
+ * Set secure_done when negotiation of an encrypted layer (currently, TLS or
+ * GSSAPI) is already completed.
*/
static int
-ProcessStartupPacket(Port *port, bool SSLdone)
+ProcessStartupPacket(Port *port, bool secure_done)
{
int32 len;
void *buf;
@@ -1924,9 +1927,10 @@ ProcessStartupPacket(Port *port, bool SSLdone)
if (pq_getbytes(((char *) &len) + 1, 3) == EOF)
{
/* Got a partial length word, so bleat about that */
- ereport(COMMERROR,
- (errcode(ERRCODE_PROTOCOL_VIOLATION),
- errmsg("incomplete startup packet")));
+ if (!secure_done)
+ ereport(COMMERROR,
+ (errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("incomplete startup packet")));
return STATUS_ERROR;
}
@@ -1975,7 +1979,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
return STATUS_ERROR;
}
- if (proto == NEGOTIATE_SSL_CODE && !SSLdone)
+ if (proto == NEGOTIATE_SSL_CODE && !secure_done)
{
char SSLok;
@@ -2008,6 +2012,32 @@ retry1:
/* but not another SSL negotiation request */
return ProcessStartupPacket(port, true);
}
+ else if (proto == NEGOTIATE_GSS_CODE && !secure_done)
+ {
+ char GSSok = 'N';
+#ifdef ENABLE_GSS
+ /* No GSSAPI encryption when on Unix socket */
+ if (!IS_AF_UNIX(port->laddr.addr.ss_family))
+ GSSok = 'G';
+#endif
+
+ while (send(port->sock, &GSSok, 1, 0) != 1)
+ {
+ if (errno == EINTR)
+ continue;
+ ereport(COMMERROR,
+ (errcode_for_socket_access(),
+ errmsg("failed to send GSSAPI negotiation response: %m)")));
+ return STATUS_ERROR; /* close the connection */
+ }
+
+#ifdef ENABLE_GSS
+ if (GSSok == 'G' && secure_open_gssapi(port) == -1)
+ return STATUS_ERROR;
+#endif
+ /* Won't ever see more than one negotiation request */
+ return ProcessStartupPacket(port, true);
+ }
/* Could add additional special packet types here */