Skip to content

Commit ea92f3a

Browse files
committed
libpq: Trace frontend authentication challenges
If tracing was enabled during connection startup, these messages would previously be listed in the trace output as something like this: F 54 Unknown message: 70 mismatched message length: consumed 4, expected 54 With this commit their type and contents are now correctly listed: F 36 StartupMessage 3 0 "user" "foo" "database" "alvherre" F 54 SASLInitialResponse "SCRAM-SHA-256" 32 'n,,n=,r=nq5zEPR/VREHEpOAZzH8Rujm' F 108 SASLResponse 'c=biws,r=nq5zEPR/VREHEpOAZzH8RujmVtWZDQ8glcrvy9OMNw7ZqFUn,p=BBwAKe0WjSvigB6RsmmArAC+hwucLeuwJrR5C/HQD5M=' Author: Jelte Fennema-Nio <postgres@jeltef.nl> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CAGECzQSoPHtZ4xe0raJ6FYSEiPPS+YWXBhOGo+Y1YecLgknF3g@mail.gmail.com
1 parent 12d6c72 commit ea92f3a

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

src/interfaces/libpq/fe-auth.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pg_GSS_continue(PGconn *conn, int payloadlen)
124124
* first or subsequent packet, just send the same kind of password
125125
* packet.
126126
*/
127+
conn->current_auth_response = AUTH_RESPONSE_GSS;
127128
if (pqPacketSend(conn, PqMsg_GSSResponse,
128129
goutbuf.value, goutbuf.length) != STATUS_OK)
129130
{
@@ -324,6 +325,7 @@ pg_SSPI_continue(PGconn *conn, int payloadlen)
324325
*/
325326
if (outbuf.pBuffers[0].cbBuffer > 0)
326327
{
328+
conn->current_auth_response = AUTH_RESPONSE_GSS;
327329
if (pqPacketSend(conn, PqMsg_GSSResponse,
328330
outbuf.pBuffers[0].pvBuffer, outbuf.pBuffers[0].cbBuffer))
329331
{
@@ -597,8 +599,10 @@ pg_SASL_init(PGconn *conn, int payloadlen)
597599
if (pqPutnchar(initialresponse, initialresponselen, conn))
598600
goto error;
599601
}
602+
conn->current_auth_response = AUTH_RESPONSE_SASL_INITIAL;
600603
if (pqPutMsgEnd(conn))
601604
goto error;
605+
602606
if (pqFlush(conn))
603607
goto error;
604608

@@ -683,6 +687,7 @@ pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
683687
/*
684688
* Send the SASL response to the server.
685689
*/
690+
conn->current_auth_response = AUTH_RESPONSE_SASL;
686691
res = pqPacketSend(conn, PqMsg_SASLResponse, output, outputlen);
687692
free(output);
688693

@@ -754,6 +759,7 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
754759
default:
755760
return STATUS_ERROR;
756761
}
762+
conn->current_auth_response = AUTH_RESPONSE_PASSWORD;
757763
ret = pqPacketSend(conn, PqMsg_PasswordMessage,
758764
pwd_to_send, strlen(pwd_to_send) + 1);
759765
free(crypt_pwd);

src/interfaces/libpq/fe-trace.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,42 @@ pqTraceOutput_CopyFail(FILE *f, const char *message, int *cursor)
354354
pqTraceOutputString(f, message, cursor, false);
355355
}
356356

357+
static void
358+
pqTraceOutput_GSSResponse(FILE *f, const char *message, int *cursor,
359+
int length, bool regress)
360+
{
361+
fprintf(f, "GSSResponse\t");
362+
pqTraceOutputNchar(f, length - *cursor + 1, message, cursor, regress);
363+
}
364+
365+
static void
366+
pqTraceOutput_PasswordMessage(FILE *f, const char *message, int *cursor)
367+
{
368+
fprintf(f, "PasswordMessage\t");
369+
pqTraceOutputString(f, message, cursor, false);
370+
}
371+
372+
static void
373+
pqTraceOutput_SASLInitialResponse(FILE *f, const char *message, int *cursor,
374+
bool regress)
375+
{
376+
int initialResponse;
377+
378+
fprintf(f, "SASLInitialResponse\t");
379+
pqTraceOutputString(f, message, cursor, false);
380+
initialResponse = pqTraceOutputInt32(f, message, cursor, false);
381+
if (initialResponse != -1)
382+
pqTraceOutputNchar(f, initialResponse, message, cursor, regress);
383+
}
384+
385+
static void
386+
pqTraceOutput_SASLResponse(FILE *f, const char *message, int *cursor,
387+
int length, bool regress)
388+
{
389+
fprintf(f, "SASLResponse\t");
390+
pqTraceOutputNchar(f, length - *cursor + 1, message, cursor, regress);
391+
}
392+
357393
static void
358394
pqTraceOutput_FunctionCall(FILE *f, const char *message, int *cursor, bool regress)
359395
{
@@ -610,6 +646,39 @@ pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer)
610646
case PqMsg_CopyFail:
611647
pqTraceOutput_CopyFail(conn->Pfdebug, message, &logCursor);
612648
break;
649+
case PqMsg_GSSResponse:
650+
Assert(PqMsg_GSSResponse == PqMsg_PasswordMessage);
651+
Assert(PqMsg_GSSResponse == PqMsg_SASLInitialResponse);
652+
Assert(PqMsg_GSSResponse == PqMsg_SASLResponse);
653+
654+
/*
655+
* These messages share a common type byte, so we discriminate by
656+
* having the code store the auth type separately.
657+
*/
658+
switch (conn->current_auth_response)
659+
{
660+
case AUTH_RESPONSE_GSS:
661+
pqTraceOutput_GSSResponse(conn->Pfdebug, message,
662+
&logCursor, length, regress);
663+
break;
664+
case AUTH_RESPONSE_PASSWORD:
665+
pqTraceOutput_PasswordMessage(conn->Pfdebug, message,
666+
&logCursor);
667+
break;
668+
case AUTH_RESPONSE_SASL_INITIAL:
669+
pqTraceOutput_SASLInitialResponse(conn->Pfdebug, message,
670+
&logCursor, regress);
671+
break;
672+
case AUTH_RESPONSE_SASL:
673+
pqTraceOutput_SASLResponse(conn->Pfdebug, message,
674+
&logCursor, length, regress);
675+
break;
676+
default:
677+
fprintf(conn->Pfdebug, "UnknownAuthenticationResponse");
678+
break;
679+
}
680+
conn->current_auth_response = '\0';
681+
break;
613682
case PqMsg_FunctionCall:
614683
pqTraceOutput_FunctionCall(conn->Pfdebug, message, &logCursor, regress);
615684
break;

src/interfaces/libpq/libpq-int.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,18 @@ typedef enum
331331
PGQUERY_CLOSE /* Close Statement or Portal */
332332
} PGQueryClass;
333333

334+
335+
/*
336+
* valid values for pg_conn->current_auth_response. These are just for
337+
* libpq internal use: since authentication response types all use the
338+
* protocol byte 'p', fe-trace.c needs a way to distinguish them in order
339+
* to print them correctly.
340+
*/
341+
#define AUTH_RESPONSE_GSS 'G'
342+
#define AUTH_RESPONSE_PASSWORD 'P'
343+
#define AUTH_RESPONSE_SASL_INITIAL 'I'
344+
#define AUTH_RESPONSE_SASL 'S'
345+
334346
/*
335347
* An entry in the pending command queue.
336348
*/
@@ -490,7 +502,9 @@ struct pg_conn
490502
* codes */
491503
bool client_finished_auth; /* have we finished our half of the
492504
* authentication exchange? */
493-
505+
char current_auth_response; /* used by pqTraceOutputMessage to
506+
* know which auth response we're
507+
* sending */
494508

495509
/* Transient state needed while establishing connection */
496510
PGTargetServerType target_server_type; /* desired session properties */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy