#ifdef USE_SSL
/*
- * If SSL is enabled and we haven't already got it running,
- * request it instead of sending the startup message.
+ * If SSL is enabled and we haven't already got encryption of
+ * some sort running, request SSL instead of sending the
+ * startup message.
*/
if (conn->allow_ssl_try && !conn->wait_ssl_try &&
- !conn->ssl_in_use)
+ !conn->ssl_in_use
+#ifdef ENABLE_GSS
+ && !conn->gssenc
+#endif
+ )
{
ProtocolVersion pv;
}
/* Otherwise, proceed with normal startup */
conn->allow_ssl_try = false;
+ /* We can proceed using this connection */
conn->status = CONNECTION_MADE;
return PGRES_POLLING_WRITING;
}
* don't hang up the socket, though.
*/
conn->try_gss = false;
- pqDropConnection(conn, true);
- conn->status = CONNECTION_NEEDED;
+ need_new_connection = true;
goto keep_going;
}
}
conn->try_gss = false;
+ /* We can proceed using this connection */
conn->status = CONNECTION_MADE;
return PGRES_POLLING_WRITING;
}
* the current connection to do so, though.
*/
conn->try_gss = false;
- pqDropConnection(conn, true);
- conn->status = CONNECTION_NEEDED;
+ need_new_connection = true;
goto keep_going;
}
return pollres;
*/
if (conn->gssenc && conn->gssencmode[0] == 'p')
{
- /* postmaster expects us to drop the connection */
+ /* only retry once */
conn->try_gss = false;
- pqDropConnection(conn, true);
- conn->status = CONNECTION_NEEDED;
+ need_new_connection = true;
goto keep_going;
}
#endif
/*
* Fetch all errors of a specific type and append to "str".
+ * Each error string is preceded by a space.
*/
static void
-pg_GSS_error_int(PQExpBuffer str, const char *mprefix,
- OM_uint32 stat, int type)
+pg_GSS_error_int(PQExpBuffer str, OM_uint32 stat, int type)
{
OM_uint32 lmin_s;
gss_buffer_desc lmsg;
do
{
- gss_display_status(&lmin_s, stat, type,
- GSS_C_NO_OID, &msg_ctx, &lmsg);
- appendPQExpBuffer(str, "%s: %s\n", mprefix, (char *) lmsg.value);
+ if (gss_display_status(&lmin_s, stat, type, GSS_C_NO_OID,
+ &msg_ctx, &lmsg) != GSS_S_COMPLETE)
+ break;
+ appendPQExpBuffer(str, " %s", (char *) lmsg.value);
gss_release_buffer(&lmin_s, &lmsg);
} while (msg_ctx);
}
OM_uint32 maj_stat, OM_uint32 min_stat)
{
resetPQExpBuffer(&conn->errorMessage);
-
- /* Fetch major error codes */
- pg_GSS_error_int(&conn->errorMessage, mprefix, maj_stat, GSS_C_GSS_CODE);
-
- /* Add the minor codes as well */
- pg_GSS_error_int(&conn->errorMessage, mprefix, min_stat, GSS_C_MECH_CODE);
+ appendPQExpBuffer(&conn->errorMessage, "%s:", mprefix);
+ pg_GSS_error_int(&conn->errorMessage, maj_stat, GSS_C_GSS_CODE);
+ appendPQExpBufferChar(&conn->errorMessage, ':');
+ pg_GSS_error_int(&conn->errorMessage, min_stat, GSS_C_MECH_CODE);
+ appendPQExpBufferChar(&conn->errorMessage, '\n');
}
/*
* Import service principal name so the proper ticket can be acquired by
* the GSSAPI system.
*/
- maxlen = NI_MAXHOST + strlen(conn->krbsrvname) + 2;
+ maxlen = strlen(conn->krbsrvname) + strlen(host) + 2;
temp_gbuf.value = (char *) malloc(maxlen);
if (!temp_gbuf.value)
{
if (output.length == 0)
{
/*
- * We're done - hooray! Kind of gross, but we need to disable SSL
- * here so that we don't accidentally tunnel one over the other.
+ * We're done - hooray! Set flag to tell the low-level I/O routines
+ * to do GSS wrapping/unwrapping.
*/
-#ifdef USE_SSL
- conn->allow_ssl_try = false;
-#endif
+ conn->gssenc = true;
/* Clean up */
gss_release_cred(&minor, &conn->gcred);
conn->gcred = GSS_C_NO_CREDENTIAL;
- conn->gssenc = true;
gss_release_buffer(&minor, &output);
/*