[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Relay length attribute mangled by unpack/repack
commit 72ba79d861972f848d6d777ed38c45663944b7ea
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Thu May 24 13:15:47 2018 -0700
Relay length attribute mangled by unpack/repack
Great catch from plcp!
https://trac.torproject.org/projects/tor/ticket/26060
When getting a circuit response we unpack then repack to get the data we just
read from the socket. This is silly. We only did this to separate the cell
headers from the payload but in doing so we corrupted the relay cell's length
attribute.
Better to just read the raw encrypted data and only construct RelayCells
*after* it has been decrypted.
---
stem/client/__init__.py | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/stem/client/__init__.py b/stem/client/__init__.py
index 281888e7..1d87966f 100644
--- a/stem/client/__init__.py
+++ b/stem/client/__init__.py
@@ -34,7 +34,7 @@ import stem.client.cell
import stem.socket
import stem.util.connection
-from stem.client.datatype import ZERO, Address, KDF, split
+from stem.client.datatype import ZERO, Address, Size, KDF, split
__all__ = [
'cell',
@@ -250,14 +250,32 @@ class Circuit(object):
header, payload = split(cell.pack(self.relay.link_protocol), header_size)
encrypted_payload = header + self.forward_key.update(payload)
- reply = []
+ reply_cells = []
self.relay._orport.send(encrypted_payload)
+ reply = self.relay._orport.recv()
- for cell in stem.client.cell.Cell.unpack(self.relay._orport.recv(), self.relay.link_protocol):
- decrypted = self.backward_key.update(cell.pack(self.relay.link_protocol)[header_size:])
- reply.append(stem.client.cell.RelayCell._unpack(decrypted, self.id, self.relay.link_protocol))
+ # Check that we got the correct number of bytes for a series of RELAY cells
- return reply
+ relay_cell_size = header_size + stem.client.cell.FIXED_PAYLOAD_LEN
+ relay_cell_cmd = stem.client.cell.RelayCell.VALUE
+
+ if len(reply) % relay_cell_size != 0:
+ raise stem.ProtocolError('Circuit response should be a series of RELAY cells, but received an unexpected size for a response: %i' % len(reply))
+
+ while reply:
+ circ_id, reply = Size.SHORT.pop(reply) if self.relay.link_protocol < 4 else Size.LONG.pop(reply)
+ command, reply = Size.CHAR.pop(reply)
+ payload, reply = split(reply, stem.client.cell.FIXED_PAYLOAD_LEN)
+
+ if command != relay_cell_cmd:
+ raise stem.ProtocolError('RELAY cell responses should be %i but was %i' % (relay_cell_cmd, command))
+ elif circ_id != self.id:
+ raise stem.ProtocolError('Response should be for circuit id %i, not %i' % (self.id, circ_id))
+
+ decrypted = self.backward_key.update(payload)
+ reply_cells.append(stem.client.cell.RelayCell._unpack(decrypted, self.id, self.relay.link_protocol))
+
+ return reply_cells
except:
self.forward_digest = orig_digest
self.forward_key = orig_key
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits