From e946ed8b13f6f16b67b73962bca5bee9e7e1449d Mon Sep 17 00:00:00 2001 From: Cameron Dale Date: Sat, 21 Jun 2008 12:59:43 -0700 Subject: [PATCH] Prevent BitTorrent nodes from infiltrating the DHT. --- apt_p2p_Khashmir/actions.py | 14 ++++++++++++-- apt_p2p_Khashmir/krpc.py | 9 ++++++--- apt_p2p_Khashmir/util.py | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/apt_p2p_Khashmir/actions.py b/apt_p2p_Khashmir/actions.py index c49959f..8542706 100644 --- a/apt_p2p_Khashmir/actions.py +++ b/apt_p2p_Khashmir/actions.py @@ -196,8 +196,16 @@ class ActionBase: if self.finished or self.answered.has_key(node.id): # a day late and a dollar short return - self.answered[node.id] = 1 - self.processResponse(dict) + try: + # Process the response + self.processResponse(dict) + self.answered[node.id] = 1 + except Exception, e: + # Unexpected error with the response + log.msg("action %s failed on %s/%s: %r" % (self.action, node.host, node.port, e)) + if node.id != self.caller.node.id: + self.caller.nodeFailed(node) + self.failed[node.id] = 1 if self.outstanding.has_key(node.id): self.outstanding_results -= self.outstanding[node.id] del self.outstanding[node.id] @@ -220,6 +228,8 @@ class ActionBase: Not called by default, but suitable for being called by L{processResponse} in a recursive node search. """ + if nodes and type(nodes) != list: + raise ValueError, "got a malformed response, from bittorrent perhaps" for compact_node in nodes: node_contact = uncompact(compact_node) node = self.caller.Node(node_contact) diff --git a/apt_p2p_Khashmir/krpc.py b/apt_p2p_Khashmir/krpc.py index c3dcfb6..9290cac 100644 --- a/apt_p2p_Khashmir/krpc.py +++ b/apt_p2p_Khashmir/krpc.py @@ -100,6 +100,8 @@ def verifyMessage(msg): raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "response not specified") if type(msg[RSP]) != dict: raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "response is not a dictionary") +# if 'nodes' in msg[RSP] and type(msg[RSP]['nodes']) != list: +# raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "wrong type of node, this is not bittorrent") elif msg[TYP] == ERR: if ERR not in msg: raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "error not specified") @@ -117,6 +119,8 @@ def verifyMessage(msg): raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "no transaction ID specified") if type(msg[TID]) != str: raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "transaction id is not a string") + if len(msg[TID]) != 20: + raise KrpcError, (KRPC_ERROR_MALFORMED_PACKET, "wrong type of node, this is not bittorrent") class hostbroker(protocol.DatagramProtocol): """The factory for the KRPC protocol. @@ -349,7 +353,7 @@ class KRPC: msg = bdecode(data) except Exception, e: if self.config.get('SPEW', False): - log.msg("krpc bdecode error: ") + log.msg("krpc bdecode error from %r: " % (addr, )) log.err(e) return @@ -357,8 +361,7 @@ class KRPC: try: verifyMessage(msg) except Exception, e: - log.msg("krpc message verification error: ") - log.err(e) + log.msg("krpc message verification error from %r: %r" % (addr, e)) return if self.config.get('SPEW', False): diff --git a/apt_p2p_Khashmir/util.py b/apt_p2p_Khashmir/util.py index dba9d8b..8c010ba 100644 --- a/apt_p2p_Khashmir/util.py +++ b/apt_p2p_Khashmir/util.py @@ -36,7 +36,7 @@ def uncompact(s): @raise ValueError: if the compact representation doesn't exist """ if (len(s) != HASH_LENGTH+6): - raise ValueError + raise ValueError, "not compact node info: %r" % (s, ) id = s[:HASH_LENGTH] host = '.'.join([str(ord(i)) for i in s[HASH_LENGTH:(HASH_LENGTH+4)]]) port = (ord(s[HASH_LENGTH+4]) << 8) | ord(s[HASH_LENGTH+5]) -- 2.39.5