Added IPv6 normalization and comparison to Addr object

This commit is contained in:
Joona Hoikkala
2016-03-20 18:09:43 +02:00
parent d508a47e51
commit 8fbe7de625
2 changed files with 52 additions and 4 deletions
+44 -4
View File
@@ -104,8 +104,9 @@ class Addr(object):
:param str port: port number or \*, or ""
"""
def __init__(self, tup):
def __init__(self, tup, ipv6=False):
self.tup = tup
self.ipv6 = ipv6
@classmethod
def fromstring(cls, str_addr):
@@ -117,7 +118,7 @@ class Addr(object):
port = ''
if len(str_addr) > endIndex + 2 and str_addr[endIndex + 1] == ':':
port = str_addr[endIndex + 2:]
return cls((host, port))
return cls((host, port), True)
else:
tup = str_addr.partition(':')
return cls((tup[0], tup[2]))
@@ -129,7 +130,15 @@ class Addr(object):
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.tup == other.tup
if self.ipv6:
# import ipdb;ipdb.set_trace()
return (other.ipv6 and
self._normalize_ipv6(self.tup[0]) ==
self._normalize_ipv6(other.tup[0]) and
self.tup[1] == other.tup[1])
else:
return self.tup == other.tup
return False
def __hash__(self):
@@ -145,7 +154,38 @@ class Addr(object):
def get_addr_obj(self, port):
"""Return new address object with same addr and new port."""
return self.__class__((self.tup[0], port))
return self.__class__((self.tup[0], port), self.ipv6)
def _normalize_ipv6(self, addr):
"""Return IPv6 address in normalized form, helper function"""
addr = addr.lstrip("[")
addr = addr.rstrip("]")
return self._explode_ipv6(addr)
def get_ipv6_exploded(self):
"""Return IPv6 in normalized form"""
if self.ipv6:
return ":".join(self._normalize_ipv6(self.tup[0]))
return ""
def _explode_ipv6(self, addr):
"""Explode IPv6 address for comparison"""
result = ['0', '0', '0', '0', '0', '0', '0', '0']
addr_list = addr.split(":")
append_to_end = False
for i in range(0, len(addr_list)):
block = addr_list[i]
if len(block) == 0:
append_to_end = True
continue
elif len(block) > 1:
# remove trailing zeros
block = block.lstrip("0")
if not append_to_end:
result[i] = str(block)
else:
result[i-len(addr_list)] = str(block)
return result
class TLSSNI01(object):
+8
View File
@@ -98,6 +98,10 @@ class AddrTest(unittest.TestCase):
self.assertEqual(self.addr5.get_port(), "*")
self.assertEqual(self.addr6.get_addr(), "[fe00::1]")
self.assertEqual(self.addr6.get_port(), "80")
self.assertEqual(self.addr6.get_ipv6_exploded(),
"fe00:0:0:0:0:0:0:1")
self.assertEqual(self.addr1.get_ipv6_exploded(),
"")
def test_str(self):
self.assertEqual(str(self.addr1), "192.168.1.1")
@@ -123,6 +127,10 @@ class AddrTest(unittest.TestCase):
self.assertEqual(self.addr4, self.addr4.get_addr_obj(""))
self.assertNotEqual(self.addr4, self.addr5)
self.assertFalse(self.addr4 == 3333)
from letsencrypt.plugins.common import Addr
self.assertEqual(self.addr4, Addr.fromstring("[fe00:0:0::1]"))
self.assertEqual(self.addr4, Addr.fromstring("[fe00:0::0:0:1]"))
def test_set_inclusion(self):
from letsencrypt.plugins.common import Addr