Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbbf9c28

Browse files
committed
libpq: Handle NegotiateProtocolVersion message
Before, receiving a NegotiateProtocolVersion message would result in aconfusing error message like expected authentication request from server, but received vThis adds proper handling of this protocol message and produces anon-topic error message from it.Reviewed-by: Jacob Champion <jchampion@timescale.com>Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>Discussion:https://www.postgresql.org/message-id/flat/f9c7862f-b864-8ef7-a861-c4638c83e209%40enterprisedb.com
1 parentdce92e5 commitbbf9c28

File tree

3 files changed

+73
-5
lines changed

3 files changed

+73
-5
lines changed

‎src/interfaces/libpq/fe-connect.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3194,10 +3194,11 @@ PQconnectPoll(PGconn *conn)
31943194

31953195
/*
31963196
* Validate message type: we expect only an authentication
3197-
* request or an error here. Anything else probably means
3198-
* it's not Postgres on the other end at all.
3197+
* request, NegotiateProtocolVersion, or an error here.
3198+
* Anything else probably means it's not Postgres on the other
3199+
* end at all.
31993200
*/
3200-
if (!(beresp=='R'||beresp=='E'))
3201+
if (!(beresp=='R'||beresp=='v'||beresp=='E'))
32013202
{
32023203
libpq_append_conn_error(conn,"expected authentication request from server, but received %c",
32033204
beresp);
@@ -3214,14 +3215,15 @@ PQconnectPoll(PGconn *conn)
32143215
/*
32153216
* Try to validate message length before using it.
32163217
* Authentication requests can't be very large, although GSS
3217-
* auth requests may not be that small. Errors can be a
3218+
* auth requests may not be that small. Same for
3219+
* NegotiateProtocolVersion. Errors can be a
32183220
* little larger, but not huge. If we see a large apparent
32193221
* length in an error, it means we're really talking to a
32203222
* pre-3.0-protocol server; cope. (Before version 14, the
32213223
* server also used the old protocol for errors that happened
32223224
* before processing the startup packet.)
32233225
*/
3224-
if (beresp=='R'&& (msgLength<8||msgLength>2000))
3226+
if ((beresp=='R'||beresp=='v')&& (msgLength<8||msgLength>2000))
32253227
{
32263228
libpq_append_conn_error(conn,"expected authentication request from server, but received %c",
32273229
beresp);
@@ -3351,6 +3353,16 @@ PQconnectPoll(PGconn *conn)
33513353

33523354
gotoerror_return;
33533355
}
3356+
elseif (beresp=='v')
3357+
{
3358+
if (pqGetNegotiateProtocolVersion3(conn))
3359+
{
3360+
gotoerror_return;
3361+
}
3362+
/* OK, we read the message; mark data consumed */
3363+
conn->inStart=conn->inCursor;
3364+
gotoerror_return;
3365+
}
33543366

33553367
/* It is an authentication request. */
33563368
conn->auth_req_received= true;

‎src/interfaces/libpq/fe-protocol3.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,61 @@ reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding)
13851385
}
13861386

13871387

1388+
/*
1389+
* Attempt to read a NegotiateProtocolVersion message.
1390+
* Entry: 'v' message type and length have already been consumed.
1391+
* Exit: returns 0 if successfully consumed message.
1392+
* returns EOF if not enough data.
1393+
*/
1394+
int
1395+
pqGetNegotiateProtocolVersion3(PGconn*conn)
1396+
{
1397+
inttmp;
1398+
ProtocolVersiontheir_version;
1399+
intnum;
1400+
PQExpBufferDatabuf;
1401+
1402+
if (pqGetInt(&tmp,4,conn)!=0)
1403+
returnEOF;
1404+
their_version=tmp;
1405+
1406+
if (pqGetInt(&num,4,conn)!=0)
1407+
returnEOF;
1408+
1409+
initPQExpBuffer(&buf);
1410+
for (inti=0;i<num;i++)
1411+
{
1412+
if (pqGets(&conn->workBuffer,conn))
1413+
{
1414+
termPQExpBuffer(&buf);
1415+
returnEOF;
1416+
}
1417+
if (buf.len>0)
1418+
appendPQExpBufferChar(&buf,' ');
1419+
appendPQExpBufferStr(&buf,conn->workBuffer.data);
1420+
}
1421+
1422+
if (their_version<conn->pversion)
1423+
appendPQExpBuffer(&conn->errorMessage,
1424+
libpq_gettext("protocol version not supported by server: client uses %u.%u, server supports up to %u.%u\n"),
1425+
PG_PROTOCOL_MAJOR(conn->pversion),PG_PROTOCOL_MINOR(conn->pversion),
1426+
PG_PROTOCOL_MAJOR(their_version),PG_PROTOCOL_MINOR(their_version));
1427+
if (num>0)
1428+
appendPQExpBuffer(&conn->errorMessage,
1429+
libpq_ngettext("protocol extension not supported by server: %s\n",
1430+
"protocol extensions not supported by server: %s\n",num),
1431+
buf.data);
1432+
1433+
/* neither -- server shouldn't have sent it */
1434+
if (!(their_version<conn->pversion)&& !(num>0))
1435+
appendPQExpBuffer(&conn->errorMessage,
1436+
libpq_gettext("invalid %s message"),"NegotiateProtocolVersion");
1437+
1438+
termPQExpBuffer(&buf);
1439+
return0;
1440+
}
1441+
1442+
13881443
/*
13891444
* Attempt to read a ParameterStatus message.
13901445
* This is possible in several places, so we break it out as a subroutine.

‎src/interfaces/libpq/libpq-int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ extern void pqParseInput3(PGconn *conn);
685685
externintpqGetErrorNotice3(PGconn*conn,boolisError);
686686
externvoidpqBuildErrorMessage3(PQExpBuffermsg,constPGresult*res,
687687
PGVerbosityverbosity,PGContextVisibilityshow_context);
688+
externintpqGetNegotiateProtocolVersion3(PGconn*conn);
688689
externintpqGetCopyData3(PGconn*conn,char**buffer,intasync);
689690
externintpqGetline3(PGconn*conn,char*s,intmaxlen);
690691
externintpqGetlineAsync3(PGconn*conn,char*buffer,intbufsize);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp