[tor-commits] [stem/master] Don't use the socket module to validate that IP addresses are valid

atagar at torproject.org atagar at torproject.org
Sat Dec 6 20:51:36 UTC 2014


commit 91f6c3bb2a5a4f4bb9a822f1280a4c250aeacdcd
Author: Damian Johnson <atagar at 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):



More information about the tor-commits mailing list