* first or subsequent packet, just send the same kind of password
* packet.
*/
+ conn->current_auth_response = AUTH_RESPONSE_GSS;
if (pqPacketSend(conn, PqMsg_GSSResponse,
goutbuf.value, goutbuf.length) != STATUS_OK)
{
*/
if (outbuf.pBuffers[0].cbBuffer > 0)
{
+ conn->current_auth_response = AUTH_RESPONSE_GSS;
if (pqPacketSend(conn, PqMsg_GSSResponse,
outbuf.pBuffers[0].pvBuffer, outbuf.pBuffers[0].cbBuffer))
{
if (pqPutnchar(initialresponse, initialresponselen, conn))
goto error;
}
+ conn->current_auth_response = AUTH_RESPONSE_SASL_INITIAL;
if (pqPutMsgEnd(conn))
goto error;
+
if (pqFlush(conn))
goto error;
/*
* Send the SASL response to the server.
*/
+ conn->current_auth_response = AUTH_RESPONSE_SASL;
res = pqPacketSend(conn, PqMsg_SASLResponse, output, outputlen);
free(output);
default:
return STATUS_ERROR;
}
+ conn->current_auth_response = AUTH_RESPONSE_PASSWORD;
ret = pqPacketSend(conn, PqMsg_PasswordMessage,
pwd_to_send, strlen(pwd_to_send) + 1);
free(crypt_pwd);
pqTraceOutputString(f, message, cursor, false);
}
+static void
+pqTraceOutput_GSSResponse(FILE *f, const char *message, int *cursor,
+ int length, bool regress)
+{
+ fprintf(f, "GSSResponse\t");
+ pqTraceOutputNchar(f, length - *cursor + 1, message, cursor, regress);
+}
+
+static void
+pqTraceOutput_PasswordMessage(FILE *f, const char *message, int *cursor)
+{
+ fprintf(f, "PasswordMessage\t");
+ pqTraceOutputString(f, message, cursor, false);
+}
+
+static void
+pqTraceOutput_SASLInitialResponse(FILE *f, const char *message, int *cursor,
+ bool regress)
+{
+ int initialResponse;
+
+ fprintf(f, "SASLInitialResponse\t");
+ pqTraceOutputString(f, message, cursor, false);
+ initialResponse = pqTraceOutputInt32(f, message, cursor, false);
+ if (initialResponse != -1)
+ pqTraceOutputNchar(f, initialResponse, message, cursor, regress);
+}
+
+static void
+pqTraceOutput_SASLResponse(FILE *f, const char *message, int *cursor,
+ int length, bool regress)
+{
+ fprintf(f, "SASLResponse\t");
+ pqTraceOutputNchar(f, length - *cursor + 1, message, cursor, regress);
+}
+
static void
pqTraceOutput_FunctionCall(FILE *f, const char *message, int *cursor, bool regress)
{
case PqMsg_CopyFail:
pqTraceOutput_CopyFail(conn->Pfdebug, message, &logCursor);
break;
+ case PqMsg_GSSResponse:
+ Assert(PqMsg_GSSResponse == PqMsg_PasswordMessage);
+ Assert(PqMsg_GSSResponse == PqMsg_SASLInitialResponse);
+ Assert(PqMsg_GSSResponse == PqMsg_SASLResponse);
+
+ /*
+ * These messages share a common type byte, so we discriminate by
+ * having the code store the auth type separately.
+ */
+ switch (conn->current_auth_response)
+ {
+ case AUTH_RESPONSE_GSS:
+ pqTraceOutput_GSSResponse(conn->Pfdebug, message,
+ &logCursor, length, regress);
+ break;
+ case AUTH_RESPONSE_PASSWORD:
+ pqTraceOutput_PasswordMessage(conn->Pfdebug, message,
+ &logCursor);
+ break;
+ case AUTH_RESPONSE_SASL_INITIAL:
+ pqTraceOutput_SASLInitialResponse(conn->Pfdebug, message,
+ &logCursor, regress);
+ break;
+ case AUTH_RESPONSE_SASL:
+ pqTraceOutput_SASLResponse(conn->Pfdebug, message,
+ &logCursor, length, regress);
+ break;
+ default:
+ fprintf(conn->Pfdebug, "UnknownAuthenticationResponse");
+ break;
+ }
+ conn->current_auth_response = '\0';
+ break;
case PqMsg_FunctionCall:
pqTraceOutput_FunctionCall(conn->Pfdebug, message, &logCursor, regress);
break;
PGQUERY_CLOSE /* Close Statement or Portal */
} PGQueryClass;
+
+/*
+ * valid values for pg_conn->current_auth_response. These are just for
+ * libpq internal use: since authentication response types all use the
+ * protocol byte 'p', fe-trace.c needs a way to distinguish them in order
+ * to print them correctly.
+ */
+#define AUTH_RESPONSE_GSS 'G'
+#define AUTH_RESPONSE_PASSWORD 'P'
+#define AUTH_RESPONSE_SASL_INITIAL 'I'
+#define AUTH_RESPONSE_SASL 'S'
+
/*
* An entry in the pending command queue.
*/
* codes */
bool client_finished_auth; /* have we finished our half of the
* authentication exchange? */
-
+ char current_auth_response; /* used by pqTraceOutputMessage to
+ * know which auth response we're
+ * sending */
/* Transient state needed while establishing connection */
PGTargetServerType target_server_type; /* desired session properties */