aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb/VNCSConnectionST.cxx
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2019-04-01 14:22:01 +0200
committerPierre Ossman <ossman@cendio.se>2019-04-01 14:22:01 +0200
commit88a94ed13ac4574d762cbf1486a701cde2ba1f9b (patch)
treecc996a13d2bd7c829a40152e242c17e065d6638b /common/rfb/VNCSConnectionST.cxx
parent7240f62ddc06643f982456c05c11d8afe5422069 (diff)
downloadtigervnc-88a94ed13ac4574d762cbf1486a701cde2ba1f9b.tar.gz
tigervnc-88a94ed13ac4574d762cbf1486a701cde2ba1f9b.zip
Add delay on authentication failures
This provides some basic rate limiting that will make it difficult for an attacker to brute force passwords. Only relevant when the blacklist is disabled as otherwise the attacker only gets a very limited number of attempts.
Diffstat (limited to 'common/rfb/VNCSConnectionST.cxx')
-rw-r--r--common/rfb/VNCSConnectionST.cxx22
1 files changed, 21 insertions, 1 deletions
diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx
index ea5c52aa..fe00dab6 100644
--- a/common/rfb/VNCSConnectionST.cxx
+++ b/common/rfb/VNCSConnectionST.cxx
@@ -52,7 +52,8 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
losslessTimer(this), server(server_),
updateRenderedCursor(false), removeRenderedCursor(false),
continuousUpdates(false), encodeManager(this), idleTimer(this),
- pointerEventTime(0), clientHasCursor(false)
+ pointerEventTime(0), clientHasCursor(false),
+ authFailureTimer(this)
{
setStreams(&sock->inStream(), &sock->outStream());
peerEndpoint.buf = sock->getPeerEndpoint();
@@ -151,6 +152,15 @@ void VNCSConnectionST::processMessages()
sock->cork(true);
while (getInStream()->checkNoWait(1)) {
+ // Silently drop any data if we are currently delaying an
+ // authentication failure response as otherwise we would close
+ // the connection on unexpected data, and an attacker could use
+ // that to detect our delayed state.
+ if (state() == RFBSTATE_SECURITY_FAILURE) {
+ getInStream()->skip(1);
+ continue;
+ }
+
if (pendingSyncFence) {
syncFence = true;
pendingSyncFence = false;
@@ -407,6 +417,14 @@ void VNCSConnectionST::authSuccess()
updates.add_changed(server->getPixelBuffer()->getRect());
}
+void VNCSConnectionST::authFailure(const char* reason)
+{
+ // Introduce a slight delay of the authentication failure response
+ // to make it difficult to brute force a password
+ authFailureMsg.replaceBuf(strDup(reason));
+ authFailureTimer.start(100);
+}
+
void VNCSConnectionST::queryConnection(const char* userName)
{
server->queryConnection(this, userName);
@@ -745,6 +763,8 @@ bool VNCSConnectionST::handleTimeout(Timer* t)
if ((t == &congestionTimer) ||
(t == &losslessTimer))
writeFramebufferUpdate();
+ else if (t == &authFailureTimer)
+ SConnection::authFailure(authFailureMsg.buf);
} catch (rdr::Exception& e) {
close(e.str());
}