[Pkg-privacy-commits] [obfsproxy] 180/353: Better use of exceptions in Extended ORPort code.
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 13:01:57 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository obfsproxy.
commit aef13f6121911326a7fd9bdb7281b7ea93bdba0d
Author: George Kadianakis <desnacked at riseup.net>
Date: Mon Dec 24 20:12:54 2012 +0200
Better use of exceptions in Extended ORPort code.
---
obfsproxy/network/extended_orport.py | 131 ++++++++++++++++++++++-------------
1 file changed, 83 insertions(+), 48 deletions(-)
diff --git a/obfsproxy/network/extended_orport.py b/obfsproxy/network/extended_orport.py
index 3c238c5..28475f1 100644
--- a/obfsproxy/network/extended_orport.py
+++ b/obfsproxy/network/extended_orport.py
@@ -14,7 +14,7 @@ log = logging.get_obfslogger()
# Authentication states:
STATE_WAIT_FOR_AUTH_TYPES = 1
STATE_WAIT_FOR_SERVER_NONCE = 2
-STATE_WAIT_FOR_RESULTS = 3
+STATE_WAIT_FOR_AUTH_RESULTS = 3
STATE_WAIT_FOR_OKAY = 4
STATE_OPEN = 5
@@ -121,25 +121,61 @@ class ExtORPortProtocol(network.GenericProtocol):
self.buffer.write(data_rcvd)
if self.state == STATE_WAIT_FOR_AUTH_TYPES:
- self._get_auth_types()
+ try:
+ self._handle_auth_types()
+ except NeedMoreData:
+ return
+ except UnsupportedAuthTypes, err:
+ log.warning("Extended ORPort Cookie Authentication failed: %s" % err)
+ self.close()
+ return
+
+ self.state = STATE_WAIT_FOR_SERVER_NONCE
if self.state == STATE_WAIT_FOR_SERVER_NONCE:
try:
- self._get_server_nonce_and_hash()
- except CouldNotReadCookie, err:
+ self._handle_server_nonce_and_hash()
+ except NeedMoreData:
+ return
+ except (CouldNotReadCookie, RcvdInvalidAuth) as err:
log.warning("Extended ORPort Cookie Authentication failed: %s" % err)
self.close()
return
- if self.state == STATE_WAIT_FOR_RESULTS:
+ self.state = STATE_WAIT_FOR_AUTH_RESULTS
+
+ if self.state == STATE_WAIT_FOR_AUTH_RESULTS:
try:
- self._get_auth_results()
+ self._handle_auth_results()
+ except NeedMoreData:
+ return
+ except AuthFailed, err:
+ log.warning("Extended ORPort Cookie Authentication failed: %s" % err)
+ self.close()
+ return
+
+ # We've finished the Extended ORPort authentication
+ # protocol. Now send all the Extended ORPort commands we
+ # want to send.
+ try:
+ self._send_ext_orport_commands()
except CouldNotWriteExtCommand:
self.close()
return
+ self.state = STATE_WAIT_FOR_OKAY
+
if self.state == STATE_WAIT_FOR_OKAY:
- self._get_okay()
+ try:
+ self._handle_okay()
+ except NeedMoreData:
+ return
+ except ExtORPortProtocolFailed as err:
+ log.warning("Extended ORPort Cookie Authentication failed: %s" % err)
+ self.close()
+ return
+
+ self.state = STATE_OPEN
if self.state == STATE_OPEN:
# We are done with the Extended ORPort protocol, we now
@@ -148,19 +184,34 @@ class ExtORPortProtocol(network.GenericProtocol):
self.circuit.setUpstreamConnection(self)
self.circuit.dataReceived(self.buffer, self)
- def _get_auth_types(self):
+ def _send_ext_orport_commands(self):
+ """
+ Send all the Extended ORPort commands we want to send.
+
+ Throws CouldNotWriteExtCommand.
+ """
+
+ # Send the actual IP address of our client to the Extended
+ # ORPort, then signal that we are done and that we want to
+ # start transferring application-data.
+ self._write_ext_orport_command(EXT_OR_CMD_TB_USERADDR, '%s:%s' % (self.peer_addr.host, self.peer_addr.port))
+ self._write_ext_orport_command(EXT_OR_CMD_TB_DONE, '')
+
+ def _handle_auth_types(self):
"""
Read authentication types that the server supports, select
one, and send it to the server.
+
+ Throws NeedMoreData and UnsupportedAuthTypes.
"""
if len(self.buffer) < 2:
- return
+ raise NeedMoreData('Not enough data')
data = self.buffer.peek()
if '\x00' not in data: # haven't received EndAuthTypes yet
log.debug("%s: Got some auth types data but no EndAuthTypes yet." % self.name)
- return
+ raise NeedMoreData('Not EndAuthTypes.')
# Drain all data up to (and including) the EndAuthTypes.
log.debug("%s: About to drain %d bytes from %d." % \
@@ -168,9 +219,7 @@ class ExtORPortProtocol(network.GenericProtocol):
data = self.buffer.read(data.index('\x00')+1)
if '\x01' not in data:
- log.debug("%s: Could not find supported auth type." % self.name)
- self.close()
- return
+ raise UnsupportedAuthTypes("%s: Could not find supported auth type (%s)." % (self.name, repr(data)))
# Send back chosen auth type.
self.write("\x01") # Static, since we only support auth type '1' atm.
@@ -181,15 +230,15 @@ class ExtORPortProtocol(network.GenericProtocol):
# the future, when we have more than one auth types.
self.write(self.client_nonce)
- self.state = STATE_WAIT_FOR_SERVER_NONCE
-
- def _get_server_nonce_and_hash(self):
+ def _handle_server_nonce_and_hash(self):
"""
Get the server's nonce and hash, validate them and send our own hash.
+
+ Throws NeedMoreData and RcvdInvalidAuth and CouldNotReadCookie.
"""
if len(self.buffer) < AUTH_HASH_LEN + AUTH_NONCE_LEN:
- return
+ raise NeedMoreData('Need more data')
server_hash = self.buffer.read(AUTH_HASH_LEN)
server_nonce = self.buffer.read(AUTH_NONCE_LEN)
@@ -202,9 +251,7 @@ class ExtORPortProtocol(network.GenericProtocol):
(self.name, repr(self.client_nonce), repr(server_nonce), repr(server_hash), repr(proper_server_hash)))
if proper_server_hash != server_hash:
- log.warning("%s: Invalid server hash. Authentication failed." % (self.name))
- self.close()
- return
+ raise RcvdInvalidAuth("%s: Invalid server hash. Authentication failed." % (self.name))
client_hash = hmac_sha256.hmac_sha256_digest(auth_cookie,
AUTH_CLIENT_TO_SERVER_CONST + self.client_nonce + server_nonce)
@@ -212,51 +259,33 @@ class ExtORPortProtocol(network.GenericProtocol):
# Send our hash.
self.write(client_hash)
- self.state = STATE_WAIT_FOR_RESULTS
-
- def _get_auth_results(self):
+ def _handle_auth_results(self):
"""
Get the authentication results. See if the authentication
succeeded or failed, and take appropriate actions.
+
+ Throws NeedMoreData and AuthFailed.
"""
if len(self.buffer) < 1:
- return
+ raise NeedMoreData("Not enough data for body.")
result = self.buffer.read(1)
if result != '\x01':
- log.warning("%s: Authentication failed (%s)!" % (self.name, repr(result)))
- self.close()
- return
+ raise AuthFailed("%s: Authentication failed (%s)!" % (self.name, repr(result)))
log.debug("%s: Authentication successful!" % self.name)
- # We've finished the authentication protocol. Send the actual
- # IP address of our client to the Extended ORPort, then signal
- # that we are done and that we want to start transferring
- # application-data.
- self._write_ext_orport_command(EXT_OR_CMD_TB_USERADDR, '%s:%s' % (self.peer_addr.host, self.peer_addr.port))
- self._write_ext_orport_command(EXT_OR_CMD_TB_DONE, '')
-
- self.state = STATE_WAIT_FOR_OKAY
-
- def _get_okay(self):
+ def _handle_okay(self):
"""
We've sent a DONE command to the Extended ORPort and we
now check if the Extended ORPort liked it or not.
- XXX abstract more
- """
- try:
- cmd, body = self._get_ext_orport_command(self.buffer)
- except NeedMoreData: # return if we need more data
- return
+ Throws NeedMoreData and ExtORPortProtocolFailed.
+ """
+ cmd, _ = self._get_ext_orport_command(self.buffer)
if cmd != EXT_OR_CMD_BT_OKAY:
- log.warning("%s: Unexpected command received (%d) after sending DONE." % (self.name, cmd))
- self.close()
- return
-
- self.state = STATE_OPEN
+ raise ExtORPortProtocolFailed("%s: Unexpected command received (%d) after sending DONE." % (self.name, cmd))
def _get_ext_orport_command(self, buf):
"""
@@ -340,5 +369,11 @@ class ExtORPortServerFactory(network.StaticDestinationClientFactory):
return network.StaticDestinationProtocol(circuit, 'server', addr)
+# XXX Exceptions need more thought and work. Most of these can be generalized.
+class RcvdInvalidAuth(Exception): pass
+class AuthFailed(Exception): pass
+class UnsupportedAuthTypes(Exception): pass
+class ExtORPortProtocolFailed(Exception): pass
+class CouldNotWriteExtCommand(Exception): pass
class CouldNotReadCookie(Exception): pass
class NeedMoreData(Exception): pass
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/obfsproxy.git
More information about the Pkg-privacy-commits
mailing list