diff options
| author | Damian Johnson <atagar@torproject.org> | 2014-12-06 12:50:14 -0800 |
|---|---|---|
| committer | Damian Johnson <atagar@torproject.org> | 2014-12-06 12:50:14 -0800 |
| commit | 91f6c3bb2a5a4f4bb9a822f1280a4c250aeacdcd (patch) | |
| tree | 97ff87288d84a380676395c0cac894684c4f7d77 | |
| parent | 90bb28f44929bcb33b321eb51a27bb247c4ae6ab (diff) | |
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
| -rw-r--r-- | stem/util/connection.py | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/stem/util/connection.py b/stem/util/connection.py index df918d2d..f5ca3f4d 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): |
