aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces/libpq/fe-connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/libpq/fe-connect.c')
-rw-r--r--src/interfaces/libpq/fe-connect.c129
1 files changed, 28 insertions, 101 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 1739855c634..ea8b35e25a1 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -2483,6 +2483,7 @@ keep_going: /* We will come back to here until there is
int msgLength;
int avail;
AuthRequest areq;
+ int res;
/*
* Scan the message from current point (note that if we find
@@ -2672,116 +2673,50 @@ keep_going: /* We will come back to here until there is
/* We'll come back when there are more data */
return PGRES_POLLING_READING;
}
-
- /* Get the password salt if there is one. */
- if (areq == AUTH_REQ_MD5)
- {
- if (pqGetnchar(conn->md5Salt,
- sizeof(conn->md5Salt), conn))
- {
- /* We'll come back when there are more data */
- return PGRES_POLLING_READING;
- }
- }
-#if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
+ msgLength -= 4;
/*
- * Continue GSSAPI/SSPI authentication
+ * Ensure the password salt is in the input buffer, if it's an
+ * MD5 request. All the other authentication methods that
+ * contain extra data in the authentication request are only
+ * supported in protocol version 3, in which case we already
+ * read the whole message above.
*/
- if (areq == AUTH_REQ_GSS_CONT)
- {
- int llen = msgLength - 4;
-
- /*
- * We can be called repeatedly for the same buffer. Avoid
- * re-allocating the buffer in this case - just re-use the
- * old buffer.
- */
- if (llen != conn->ginbuf.length)
- {
- if (conn->ginbuf.value)
- free(conn->ginbuf.value);
-
- conn->ginbuf.length = llen;
- conn->ginbuf.value = malloc(llen);
- if (!conn->ginbuf.value)
- {
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory allocating GSSAPI buffer (%d)"),
- llen);
- goto error_return;
- }
- }
-
- if (pqGetnchar(conn->ginbuf.value, llen, conn))
- {
- /* We'll come back when there is more data. */
- return PGRES_POLLING_READING;
- }
- }
-#endif
- /* Get additional payload for SASL, if any */
- if ((areq == AUTH_REQ_SASL ||
- areq == AUTH_REQ_SASL_CONT) &&
- msgLength > 4)
+ if (areq == AUTH_REQ_MD5 && PG_PROTOCOL_MAJOR(conn->pversion) < 3)
{
- int llen = msgLength - 4;
+ msgLength += 4;
- /*
- * We can be called repeatedly for the same buffer. Avoid
- * re-allocating the buffer in this case - just re-use the
- * old buffer.
- */
- if (llen != conn->auth_req_inlen)
+ avail = conn->inEnd - conn->inCursor;
+ if (avail < 4)
{
- if (conn->auth_req_inbuf)
- {
- free(conn->auth_req_inbuf);
- conn->auth_req_inbuf = NULL;
- }
-
- conn->auth_req_inlen = llen;
- conn->auth_req_inbuf = malloc(llen + 1);
- if (!conn->auth_req_inbuf)
- {
- printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("out of memory allocating SASL buffer (%d)"),
- llen);
+ /*
+ * Before returning, try to enlarge the input buffer
+ * if needed to hold the whole message; see notes in
+ * pqParseInput3.
+ */
+ if (pqCheckInBufferSpace(conn->inCursor + (size_t) 4,
+ conn))
goto error_return;
- }
- }
-
- if (pqGetnchar(conn->auth_req_inbuf, llen, conn))
- {
- /* We'll come back when there is more data. */
+ /* We'll come back when there is more data */
return PGRES_POLLING_READING;
}
-
- /*
- * For safety and convenience, always ensure the in-buffer
- * is NULL-terminated.
- */
- conn->auth_req_inbuf[llen] = '\0';
}
/*
- * OK, we successfully read the message; mark data consumed
- */
- conn->inStart = conn->inCursor;
-
- /* Respond to the request if necessary. */
-
- /*
+ * Process the rest of the authentication request message, and
+ * respond to it if necessary.
+ *
* Note that conn->pghost must be non-NULL if we are going to
* avoid the Kerberos code doing a hostname look-up.
*/
+ res = pg_fe_sendauth(areq, msgLength, conn);
+ conn->errorMessage.len = strlen(conn->errorMessage.data);
- if (pg_fe_sendauth(areq, conn) != STATUS_OK)
- {
- conn->errorMessage.len = strlen(conn->errorMessage.data);
+ /* OK, we have processed the message; mark data consumed */
+ conn->inStart = conn->inCursor;
+
+ if (res != STATUS_OK)
goto error_return;
- }
- conn->errorMessage.len = strlen(conn->errorMessage.data);
/*
* Just make sure that any data sent by pg_fe_sendauth is
@@ -3522,17 +3457,9 @@ closePGconn(PGconn *conn)
gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER);
if (conn->gtarg_nam)
gss_release_name(&min_s, &conn->gtarg_nam);
- if (conn->ginbuf.length)
- gss_release_buffer(&min_s, &conn->ginbuf);
- if (conn->goutbuf.length)
- gss_release_buffer(&min_s, &conn->goutbuf);
}
#endif
#ifdef ENABLE_SSPI
- if (conn->ginbuf.length)
- free(conn->ginbuf.value);
- conn->ginbuf.length = 0;
- conn->ginbuf.value = NULL;
if (conn->sspitarget)
free(conn->sspitarget);
conn->sspitarget = NULL;