commit 1c02df654c45d25471200f9252bc133481e3ecdf Author: Philipp Winter phw@torproject.org Date: Mon Mar 3 23:59:27 2014 +0100
Stop processing data after authentication failed.
If the client did not authenticate after MAX_HANDSHAKE_LENGTH bytes, authentication has failed. For obfuscation, we keep the connection open a while longer but we stop processing all data from that point on to prevent denial-of-service attacks. (Partial) patch by Yawning Angel. For previous discussion, see: https://bugs.torproject.org/11092. --- obfsproxy/transports/scramblesuit/const.py | 3 ++- obfsproxy/transports/scramblesuit/scramblesuit.py | 30 +++++++++++++++------ 2 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/obfsproxy/transports/scramblesuit/const.py b/obfsproxy/transports/scramblesuit/const.py index ca3ec4d..8addabc 100644 --- a/obfsproxy/transports/scramblesuit/const.py +++ b/obfsproxy/transports/scramblesuit/const.py @@ -96,7 +96,8 @@ SHARED_SECRET_LENGTH = 20
# States which are used for the protocol state machine. ST_WAIT_FOR_AUTH = 0 -ST_CONNECTED = 1 +ST_AUTH_FAILED = 1 +ST_CONNECTED = 2
# File which holds the client's session tickets. CLIENT_TICKET_FILE = "session_ticket.yaml" diff --git a/obfsproxy/transports/scramblesuit/scramblesuit.py b/obfsproxy/transports/scramblesuit/scramblesuit.py index da2a32d..7e96044 100644 --- a/obfsproxy/transports/scramblesuit/scramblesuit.py +++ b/obfsproxy/transports/scramblesuit/scramblesuit.py @@ -459,7 +459,19 @@ class ScrambleSuitTransport( base.BaseTransport ): payload or authentication data. """
- if self.weAreServer and (self.protoState == const.ST_WAIT_FOR_AUTH): + if self.weAreServer and (self.protoState == const.ST_AUTH_FAILED): + + self.drainedHandshake += len(data) + data.drain(len(data)) + + if self.drainedHandshake > self.srvState.closingThreshold: + log.info("Terminating connection after having received >= %d" + " bytes because client could not " + "authenticate." % self.srvState.closingThreshold) + self.circuit.close() + return + + elif self.weAreServer and (self.protoState == const.ST_WAIT_FOR_AUTH):
# First, try to interpret the incoming data as session ticket. if self.receiveTicket(data): @@ -484,14 +496,16 @@ class ScrambleSuitTransport( base.BaseTransport ):
self.sendTicketAndSeed()
- else: - if len(data) > self.srvState.closingThreshold: - log.info("Terminating connection after having received %d" - " bytes because client could not " - "authenticate." % len(data)) - self.circuit.close() - return + elif len(data) > const.MAX_HANDSHAKE_LENGTH: + self.protoState = const.ST_AUTH_FAILED + self.drainedHandshake = len(data) + data.drain(self.drainedHandshake) + log.info("No successful authentication after having " \ + "received >= %d bytes. Now ignoring client." % \ + const.MAX_HANDSHAKE_LENGTH) + return
+ else: log.debug("Authentication unsuccessful so far. " "Waiting for more data.") return
tor-commits@lists.torproject.org