[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [bridgedb/master] Move base64 re-padding logic into separate function.
commit 2a3c688715d4ac4dd5ad1dae46be14ed65623d5b
Author: Isis Lovecruft <isis@xxxxxxxxxxxxxx>
Date: Wed Dec 11 13:23:15 2013 +0000
Move base64 re-padding logic into separate function.
This logic is not specific to parsing networkstatus descriptors, so for now
I've placed it in parse.parseUnpaddedBase64() â?? though it could live somewhere
else later.
---
lib/bridgedb/parse/__init__.py | 38 +++++++++++++++++++++++++++++++++++
lib/bridgedb/parse/networkstatus.py | 28 ++++++++++----------------
2 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/lib/bridgedb/parse/__init__.py b/lib/bridgedb/parse/__init__.py
index f4b75d1..0618dae 100644
--- a/lib/bridgedb/parse/__init__.py
+++ b/lib/bridgedb/parse/__init__.py
@@ -26,6 +26,16 @@
\__ :mod:`bridgedb.parse.versions`
"""
+from __future__ import absolute_import
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import binascii
+
+
+class InvalidBase64(ValueError):
+ """Cannot decode base64 value."""
+
def padBase64(b64string):
"""Re-add any stripped equals sign character padding to a b64 string.
@@ -50,3 +60,31 @@ def padBase64(b64string):
b64string += '=' * addchars
return b64string
+
+def parseUnpaddedBase64(field):
+ """Parse an unpadded, base64-encoded field.
+
+ The **field** will be re-padded, if need be, and then base64 decoded.
+
+ :param str field: Should be some base64-encoded thing, with any trailing
+ '=' characters removed.
+ :raises: :exc:`InvalidBase64`, if there is an error in either unpadding or
+ decoding **field**.
+ :rtype: str
+ :returns: The base64-decoded **field**.
+ """
+ if field.endswith('='):
+ raise InvalidBase64("Unpadded, base64-encoded networkstatus field "\
+ "must not end with '=': %r" % field)
+
+ try:
+ paddedField = padBase64(field) # Add the trailing equals sign back in
+ except ValueError as error:
+ raise InvalidBase64(error)
+
+ debasedField = binascii.a2b_base64(paddedField)
+ if not debasedField:
+ raise InvalidBase64("Base64-encoded networkstatus field %r is invalid!"
+ % field)
+
+ return debasedField
diff --git a/lib/bridgedb/parse/networkstatus.py b/lib/bridgedb/parse/networkstatus.py
index 7fd9e18..09c9a65 100644
--- a/lib/bridgedb/parse/networkstatus.py
+++ b/lib/bridgedb/parse/networkstatus.py
@@ -32,7 +32,8 @@ import warnings
from twisted.python.log import showwarning
from bridgedb.parse import addr
-from bridgedb.parse import padBase64
+from bridgedb.parse import parseUnpaddedBase64
+from bridgedb.parse import InvalidBase64
class NetworkstatusParsingError(Exception):
@@ -103,19 +104,10 @@ def parseRLine(line):
nickname, ID = fields[:2]
isValidRouterNickname(nickname)
- if ID.endswith('='):
- raise InvalidNetworkstatusRouterIdentity(
- "Skipping networkstatus parsing for router with nickname "\
- "'%s':\n Unpadded, base64-encoded networkstatus router identity "\
- "string ends with '=': %r" % (nickname, ID))
- paddedID = padBase64(ID) # Add the trailing equals sign back in
- debasedID = binascii.a2b_base64(paddedID)
- if not debasedID:
- raise InvalidNetworkstatusRouterIdentity(
- "Skipping networkstatus parsing for router with nickname "\
- "'%s':\n Base64-encoding for networkstatus router identity "\
- "string is invalid!\n Line: %r" % (nickname, line))
- ID = debasedID
+ try:
+ ID = parseUnpaddedBase64(ID)
+ except InvalidBase64 as error:
+ raise InvalidNetworkstatusRouterIdentity(error)
except NetworkstatusParsingError as error:
logging.error(error)
@@ -128,16 +120,18 @@ def parseRLine(line):
ID = None
else:
try:
- paddedDigest = padBase64(fields[2])
- descDigest = binascii.b2a_base64(paddedDigest)
+ descDigest = parseUnpaddedBase64(fields[2])
timestamp = time.mktime(time.strptime(" ".join(fields[3:5]),
"%Y-%m-%d %H:%M:%S"))
ORaddr = fields[5]
ORport = fields[6]
dirport = fields[7]
- except (AttributeError, ValueError, IndexError) as error:
+ except InvalidBase64 as error:
logging.error(error)
descDigest = None
+ except (AttributeError, ValueError, IndexError) as error:
+ logging.error(error)
+ timestamp = None
finally:
return (nickname, ID, descDigest, timestamp, ORaddr, ORport, dirport)
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits