Indexing list-like objects by 0L in Bridges.getConfigLine
This bug occurs because, in the function bridgedb.Bridges.getConfigLine()
, the following lines determine ― when a request comes in ― the client's position in the hashring:
if not request: request = 'default'
digest = get_hmac_fn('Order-Or-Addresses')(request)
pos = long(digest[:8], 16) # lower 8 bytes -> long
Later on, in the same function, pos
modulo the number of addresses this Bridge
has, is used to index the collected/filtered addresses. Similarly, pos
modulo the number of ports in the portlist is used to index the portlist:
# default ip, orport should get a chance at being selected
if isinstance(self.ip, addressClass):
addresses.insert(0,(self.ip, addr.PortList(self.orport)))
if addresses:
address,portlist = addresses[pos % len(addresses)]
if isinstance(address, ipaddr.IPv6Address): ip = "[%s]"%address
else: ip = "%s"%address
orport = portlist[pos % len(portlist)]
Meaning that the fewer number of addresses/ports there are, the higher the chance that the pos
will be modulo some small number which is a factor. For example, if there is only one address, this would be something like:
>>>from bridgedb import Bridges
>>> digest = Bridges.get_hmac_fn('Order-Or-Addresses')('default')
>>> pos = long(digest[:8], 16)
>>> pos
3790090317L
>>> pos % 1
0L
Which causes the following bug. What is extra strange is that the ValueError from trying to index these list-like things with a 0L
doesn't seem to occur on the addresses, only on the orport = portlist[…
line. Though, it's also worth noting that the 'default'
value used in the hmac generation is usually a client's IP address, truncated to the /24. This means that this indexing-by-0L bug will occur
rather indeterminately.
(bridgedb)∃!isisⒶwintermute:(fix/9462-refactor-netstatus-parsers_r9462C *+$=)~/code/torproject/bridgedb ∴ bridgedb
Unhandled Error
Traceback (most recent call last):
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 571, in dataReceived
why = self.lineReceived(line)
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/twisted/web/http.py", line 1619, in lineReceived
self.allContentReceived()
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/twisted/web/http.py", line 1694, in allContentReceived
req.requestReceived(command, path, version)
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/twisted/web/http.py", line 790, in requestReceived
self.process()
--- <exception caught here> ---
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/twisted/web/server.py", line 189, in process
self.render(resrc)
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/twisted/web/server.py", line 238, in render
body = resrc.render(self)
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/bridgedb-0.0.1_274_g594a221_dirty-py2.7.egg/bridgedb/HTTPServer.py", line 140, in render
return self.getBridgeRequestAnswer(request)
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/bridgedb-0.0.1_274_g594a221_dirty-py2.7.egg/bridgedb/HTTPServer.py", line 218, in getBridgeRequestAnswer
) for b in bridges)
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/bridgedb-0.0.1_274_g594a221_dirty-py2.7.egg/bridgedb/HTTPServer.py", line 218, in <genexpr>
) for b in bridges)
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/bridgedb-0.0.1_274_g594a221_dirty-py2.7.egg/bridgedb/Bridges.py", line 192, in getConfigLine
orport = portlist[pos % len(portlist)]
File "/home/isis/.virtualenvs/bridgedb/local/lib/python2.7/site-packages/bridgedb-0.0.1_274_g594a221_dirty-py2.7.egg/bridgedb/parse/addr.py", line 372, in __getitem__
return portlist[portlist.index(port)]
exceptions.ValueError: 0L is not in list
^C