commit 91f6c3bb2a5a4f4bb9a822f1280a4c250aeacdcd Author: Damian Johnson atagar@torproject.org Date: Sat Dec 6 12:50:14 2014 -0800
Don't use the socket module to validate that IP addresses are valid
This largely reverts commit 25771fe. Evidently the socket builtin doens't always know what an IPv6 address looks like...
https://trac.torproject.org/projects/tor/ticket/13904 --- stem/util/connection.py | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-)
diff --git a/stem/util/connection.py b/stem/util/connection.py index df918d2..f5ca3f4 100644 --- a/stem/util/connection.py +++ b/stem/util/connection.py @@ -46,7 +46,6 @@ import hmac import os import platform import re -import socket
import stem.util.proc import stem.util.system @@ -334,12 +333,23 @@ def is_valid_ipv4_address(address): :returns: **True** if input is a valid IPv4 address, **False** otherwise """
- try: - packed = socket.inet_pton(socket.AF_INET, address) - return socket.inet_ntop(socket.AF_INET, packed) == address - except (TypeError, socket.error): + if not isinstance(address, (bytes, unicode)): return False
+ # checks if theres four period separated values + + if address.count('.') != 3: + return False + + # checks that each value in the octet are decimal values between 0-255 + for entry in address.split('.'): + if not entry.isdigit() or int(entry) < 0 or int(entry) > 255: + return False + elif entry[0] == '0' and len(entry) > 1: + return False # leading zeros, for instance in '1.2.3.001' + + return True +
def is_valid_ipv6_address(address, allow_brackets = False): """ @@ -355,11 +365,24 @@ def is_valid_ipv6_address(address, allow_brackets = False): if address.startswith('[') and address.endswith(']'): address = address[1:-1]
- try: - socket.inet_pton(socket.AF_INET6, address) - return True - except (TypeError, socket.error): - return False + # addresses are made up of eight colon separated groups of four hex digits + # with leading zeros being optional + # https://en.wikipedia.org/wiki/IPv6#Address_format + + colon_count = address.count(':') + + if colon_count > 7: + return False # too many groups + elif colon_count != 7 and '::' not in address: + return False # not enough groups and none are collapsed + elif address.count('::') > 1 or ':::' in address: + return False # multiple groupings of zeros can't be collapsed + + for entry in address.split(':'): + if not re.match('^[0-9a-fA-f]{0,4}$', entry): + return False + + return True
def is_valid_port(entry, allow_zero = False):
tor-commits@lists.torproject.org