commit e1a3aba733313c842c24c40ac235c073a548030d Author: Damian Johnson atagar@torproject.org Date: Thu Apr 19 09:23:27 2012 -0700
Allowing for negative uptimes prior to tor 0.1.2.7
Tor 0.1.2.7 fixed a bug which could result in negative uptime values. Making our descriptor parser accept negative uptimes for tor versions with the bug, and fail validation for later versions.
This includes a test with one of the problematic descriptors, checking that we can both parse it, and will fail validation if it was for a later version.
Thanks to Karsten for figuring out where these values were coming from! --- stem/descriptor/server_descriptor.py | 24 +++++++++++++-- test/integ/descriptor/data/negative_uptime | 45 ++++++++++++++++++++++++++++ test/integ/descriptor/server_descriptor.py | 24 +++++++++++++++ 3 files changed, 90 insertions(+), 3 deletions(-)
diff --git a/stem/descriptor/server_descriptor.py b/stem/descriptor/server_descriptor.py index 7823cf0..f3023a2 100644 --- a/stem/descriptor/server_descriptor.py +++ b/stem/descriptor/server_descriptor.py @@ -473,11 +473,22 @@ class ServerDescriptorV3(stem.descriptor.Descriptor): else: self.hidden_service_dir = ["2"] elif keyword == "uptime": - if not value.isdigit(): + # We need to be tolerant of negative uptimes to accomidate a past tor + # bug... + # + # Changes in version 0.1.2.7-alpha - 2007-02-06 + # - If our system clock jumps back in time, don't publish a negative + # uptime in the descriptor. Also, don't let the global rate limiting + # buckets go absurdly negative. + # + # After parsing all of the attributes we'll double check that negative + # uptimes only occured prior to this fix. + + try: + self.uptime = int(value) + except ValueError: if not validate: continue raise ValueError("Uptime line must have an integer value: %s" % value) - - self.uptime = int(value) elif keyword == "contact": self.contact = value elif keyword == "protocols": @@ -533,6 +544,13 @@ class ServerDescriptorV3(stem.descriptor.Descriptor): else: break else: self._unrecognized_lines.append(line) + + # if we have a negative uptime and a tor version that shouldn't exhibit + # this bug then fail validation + + if validate and self.uptime and self.tor_version: + if self.uptime < 0 and self.tor_version >= stem.version.Version("0.1.2.7"): + raise ValueError("Descriptor for version '%s' had a negative uptime value: %i" % (self.tor_version, self.uptime))
def _check_constraints(self, entries, first_keyword, last_keyword): """ diff --git a/test/integ/descriptor/data/negative_uptime b/test/integ/descriptor/data/negative_uptime new file mode 100644 index 0000000..4140d75 --- /dev/null +++ b/test/integ/descriptor/data/negative_uptime @@ -0,0 +1,45 @@ +router TipTor 62.99.247.83 9001 0 9030 +platform Tor 0.1.1.25 on Darwin Power Macintosh +published 2006-12-18 22:42:40 +opt fingerprint 1379 62D4 931D BF08 A24E 8432 88B8 A155 D6D2 AEDD +uptime -31081285 +bandwidth 102400 153600 124131 +onion-key +-----BEGIN RSA PUBLIC KEY----- +MIGJAoGBAOAG0OI7xLpz3gAkJoJdRzKYOvOZ7PL5dQQZJGw+pXVUnXfchwTXLm5o +rAoYolziFjUU+EDaDXCHq1MrQBNbT1kQHqv+OcVjTwuameNVOCgPTIDOxiXfxxoO +zDAEQ91gzcDIBZdV9V64KV8Oz4+NYK3zrGDkIg00pAQjNuwvmZqlAgMBAAE= +-----END RSA PUBLIC KEY----- +signing-key +-----BEGIN RSA PUBLIC KEY----- +MIGJAoGBAKjCkU3eAwbW9ZU42B1l+Itqy4yKoQpRjt6N42mfNFfKZ8Ywd789/jiK +J31QYBhW3JBn1ZFkRwpfKYlbOm0XS2CjlqHuT0Ycp9iphtCIHADIM+3shaSKAIwA +8/wQ2GN9zYiTneUNWRJN5sDja+oU7XfkRI46cpV1Y1lVJyEoKQWpAgMBAAE= +-----END RSA PUBLIC KEY----- +opt write-history 2006-12-18 22:36:20 (900 s) 85896196,91917257,89966503,91506428,91213104,88921400,91039183,91716023,91147326,86173405,88624130,87211145,90976203,91765274,91904016,92475836,91436900,91811938,86244782,91228827,91939844,89829330,89107239,89019495,88925780,91247327,90406742,91088221,91065780,91770795,91408136,89981571,88663478,91555300,91664187,91916304,92079918,87826691,87836934,91162457,91904383,91508890,90270067,91314943,91856008,84648838,86133485,81010341,78078954,85039584,91951911,91327645,92042781,87120087,76812012,87759151,91627062,91881873,91965911,91523086,86332304,86299595,90915708,89321373,91093137,91654532,91836129,91819440,92049427,92014514,89481483,91098381,88852717,91601581,89729803,91256453,89604862,91881660,91942891,91769572,91896895,92224718,91431715,91762404,91709273,92046002,91866341,91561459,91673622,91700186,91659511,92402879,90926431,87060230,91076389,89573325 +opt read-history 2006-12-18 22:36:20 (900 s) 69091643,77959428,74322746,75132861,74637737,68249949,73224421,72744339,73893094,69049631,71480325,68334060,72775510,79560093,78273066,75799097,76810596,78186192,67593073,75998559,77654399,70612520,74383546,74734217,74966593,75402221,80000519,80112418,79005070,80831698,76082779,73232671,71056247,75135941,71903141,78060009,79742551,70250313,66205769,78319432,73988994,74372922,71546410,73545171,74220510,63051559,66646384,68538308,59360208,63812166,75673274,72347320,76357687,66600939,56487705,70648976,70968064,74698003,75944759,74122368,67485399,63305556,68515366,71145401,69625041,68993028,71537081,75025172,75155755,70871549,69489568,74027234,72162369,74396503,76005043,72708060,70567406,73291632,75536033,73865170,69322880,73918987,72020474,76681275,76604577,77208720,75252120,75305805,76861569,77278013,77057424,76937746,72642470,65754315,70138397,73236479 +contact rbr@tip-informatik.at +reject 0.0.0.0/8:* +reject 169.254.0.0/16:* +reject 127.0.0.0/8:* +reject 192.168.0.0/16:* +reject 10.0.0.0/8:* +reject 172.16.0.0/12:* +reject *:25 +reject *:119 +reject *:135-139 +reject *:445 +reject *:465 +reject *:587 +reject *:1214 +reject *:4661-4666 +reject *:6346-6429 +reject *:6699 +reject *:6881-6999 +accept *:* +router-signature +-----BEGIN SIGNATURE----- +XAy56NzQm+LGMnaxBZC0ulmyZxoTNTFxZN0834V/hrfBdEOwMuBZMSsS613OfRK1 +3K/StL29NdLChHt71XCPyxsnbzguBE0Pma6cX4aSNa1WJO4wpc1WipmWdmuVKXHD +RoxIVSJU3qwfjzSbwJiNSLPs4mmQFecsVmG94cZSITY= +-----END SIGNATURE----- diff --git a/test/integ/descriptor/server_descriptor.py b/test/integ/descriptor/server_descriptor.py index 815674a..84732b8 100644 --- a/test/integ/descriptor/server_descriptor.py +++ b/test/integ/descriptor/server_descriptor.py @@ -268,6 +268,30 @@ Qlx9HNCqCY877ztFRC624ja2ql6A2hBcuoYMbkHjcQ4= self.assertTrue(desc.contact.startswith(contact_start)) self.assertTrue(desc.contact.endswith(contact_end))
+ def test_negative_uptime(self): + """ + Parses a descriptor where we are tolerant of a negative uptime, and another + where we shouldn't be. + """ + + descriptor_path = os.path.join(DESCRIPTOR_TEST_DATA, "negative_uptime") + + descriptor_file = open(descriptor_path) + descriptor_contents = descriptor_file.read() + descriptor_file.close() + + desc = stem.descriptor.server_descriptor.RelayDescriptorV3(descriptor_contents) + + self.assertEquals("TipTor", desc.nickname) + self.assertEquals("137962D4931DBF08A24E843288B8A155D6D2AEDD", desc.fingerprint) + self.assertEquals("62.99.247.83", desc.address) + + # modify the relay version so it's after when the negative uptime bug + # should appear + + descriptor_contents = descriptor_contents.replace("Tor 0.1.1.25", "Tor 0.1.2.7") + self.assertRaises(ValueError, stem.descriptor.server_descriptor.RelayDescriptorV3, descriptor_contents) + def test_bridge_descriptor(self): """ Parses a bridge descriptor.
tor-commits@lists.torproject.org