!1796 修复SSL认证模式下中间人攻击的问题

Merge pull request !1796 from buter/master
This commit is contained in:
opengauss-bot
2022-06-11 06:56:01 +00:00
committed by Gitee
4 changed files with 36 additions and 0 deletions

View File

@ -1366,6 +1366,17 @@ static int pq_discardbytes(size_t len)
return 0;
}
/* --------------------------------
* pq_buffer_has_data - is any buffered data available to read?
*
* This will *not* attempt to read more data.
* --------------------------------
*/
bool pq_buffer_has_data(void)
{
return (t_thrd.libpq_cxt.PqRecvPointer < t_thrd.libpq_cxt.PqRecvLength);
}
/* --------------------------------
* pq_getstring - get a null terminated string from connection
*

View File

@ -2610,6 +2610,18 @@ keep_going: /* We will come back to here until there is
*/
pollres = pqsecure_open_client(conn);
if (pollres == PGRES_POLLING_OK) {
/*
* At this point we should have no data already buffered.
* If we do, it was received before we performed the SSL
* handshake, so it wasn't encrypted and indeed may have
* been injected by a man-in-the-middle.
*/
if (conn->inCursor != conn->inEnd) {
appendPQExpBufferStr(&conn->errorMessage,
libpq_gettext("received unencrypted data after SSL response\n"));
goto error_return;
}
/* SSL handshake done, ready to send startup packet */
conn->status = CONNECTION_MADE;
return PGRES_POLLING_WRITING;

View File

@ -3584,6 +3584,18 @@ int ProcessStartupPacket(Port* port, bool SSLdone)
}
#endif
/*
* At this point we should have no data already buffered. If we do,
* it was received before we performed the SSL handshake, so it wasn't
* encrypted and indeed may have been injected by a man-in-the-middle.
* We report this case to the client.
*/
if (pq_buffer_has_data()) {
ereport(FATAL, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("received unencrypted data after SSL request"),
errdetail("This could be either a client-software bug or "
"evidence of an attempted man-in-the-middle attack.")));
}
/* regular startup packet, cancel, etc packet should follow... */
/* but not another SSL negotiation request */
return ProcessStartupPacket(port, true);

View File

@ -56,6 +56,7 @@ extern int pq_getmessage(StringInfo s, int maxlen);
extern int pq_getbyte(void);
extern int pq_peekbyte(void);
extern int pq_getbyte_if_available(unsigned char* c);
extern bool pq_buffer_has_data(void);
extern int pq_putbytes(const char* s, size_t len);
extern int pq_flush(void);
extern int pq_flush_if_writable(void);