diff options
author | Pierre Ossman <ossman@cendio.se> | 2019-04-01 14:22:01 +0200 |
---|---|---|
committer | Pierre Ossman <ossman@cendio.se> | 2019-04-01 14:22:01 +0200 |
commit | 88a94ed13ac4574d762cbf1486a701cde2ba1f9b (patch) | |
tree | cc996a13d2bd7c829a40152e242c17e065d6638b /common/rfb/VNCSConnectionST.cxx | |
parent | 7240f62ddc06643f982456c05c11d8afe5422069 (diff) | |
download | tigervnc-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.cxx | 22 |
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()); } |