[tor-commits] r24455: {arm} Torrc validation requires 'GETINFO config-text' which was in (arm/trunk/src/util)

Damian Johnson atagar1 at gmail.com
Sun Mar 27 06:08:00 UTC 2011


Author: atagar
Date: 2011-03-27 06:07:59 +0000 (Sun, 27 Mar 2011)
New Revision: 24455

Modified:
   arm/trunk/src/util/torConfig.py
   arm/trunk/src/util/torTools.py
Log:
Torrc validation requires 'GETINFO config-text' which was introduced in Tor verison 0.2.2.7 (as per https://trac.torproject.org/projects/tor/ticket/2501). Skipping validation if we don't meet that requirement.



Modified: arm/trunk/src/util/torConfig.py
===================================================================
--- arm/trunk/src/util/torConfig.py	2011-03-27 02:58:34 UTC (rev 24454)
+++ arm/trunk/src/util/torConfig.py	2011-03-27 06:07:59 UTC (rev 24455)
@@ -628,13 +628,23 @@
     
     self.valsLock.acquire()
     
+    # The torrc validation relies on 'GETINFO config-text' which was
+    # introduced in tor 0.2.2.7-alpha so if we're using an earlier version
+    # (or configured to skip torrc validation) then this is a no-op. For more
+    # information see:
+    # https://trac.torproject.org/projects/tor/ticket/2501
+    
     if not self.isLoaded(): returnVal = None
-    elif not CONFIG["features.torrc.validate"]: returnVal = {}
     else:
-      if self.corrections == None:
-        self.corrections = validate(self.contents)
+      skipValidation = not CONFIG["features.torrc.validate"]
+      skipValidation |= not torTools.getConn().isVersion("0.2.2.7-alpha")
       
-      returnVal = list(self.corrections)
+      if skipValidation: returnVal = {}
+      else:
+        if self.corrections == None:
+          self.corrections = validate(self.contents)
+        
+        returnVal = list(self.corrections)
     
     self.valsLock.release()
     return returnVal

Modified: arm/trunk/src/util/torTools.py
===================================================================
--- arm/trunk/src/util/torTools.py	2011-03-27 02:58:34 UTC (rev 24454)
+++ arm/trunk/src/util/torTools.py	2011-03-27 06:07:59 UTC (rev 24455)
@@ -54,8 +54,8 @@
 CACHE_ARGS = ("version", "config-file", "exit-policy/default", "fingerprint",
               "config/names", "info/names", "features/names", "events/names",
               "nsEntry", "descEntry", "address", "bwRate", "bwBurst",
-              "bwObserved", "bwMeasured", "flags", "pid", "pathPrefix",
-              "startTime", "authorities", "circuits")
+              "bwObserved", "bwMeasured", "flags", "parsedVersion", "pid",
+              "pathPrefix", "startTime", "authorities", "circuits")
 
 # Tor has a couple messages (in or/router.c) for when our ip address changes:
 # "Our IP Address has changed from <previous> to <current>; rebuilding
@@ -217,6 +217,41 @@
   log.log(CONFIG["log.unknownBsdJailId"], "Failed to figure out the FreeBSD jail id. Assuming 0.")
   return 0
 
+def parseVersion(versionStr):
+  """
+  Parses the given version string into its expected components, for instance...
+  '0.2.2.13-alpha (git-feb8c1b5f67f2c6f)'
+  
+  would provide:
+  (0, 2, 2, 13, 'alpha')
+  
+  If the input isn't recognized then this returns None.
+  
+  Arguments:
+    versionStr - version string to be parsed
+  """
+  
+  # crops off extra arguments, for instance:
+  # '0.2.2.13-alpha (git-feb8c1b5f67f2c6f)' -> '0.2.2.13-alpha'
+  versionStr = versionStr.split()[0]
+  
+  result = None
+  if versionStr.count(".") in (2, 3):
+    # parses the optional suffix ('alpha', 'release', etc)
+    if versionStr.count("-") == 1:
+      versionStr, versionSuffix = versionStr.split("-")
+    else: versionSuffix = ""
+    
+    # Parses the numeric portion of the version. This can have three or four
+    # entries depending on if an optional patch level was provided.
+    try:
+      versionComp = [int(entry) for entry in versionStr.split(".")]
+      if len(versionComp) == 3: versionComp += [0]
+      result = tuple(versionComp + [versionSuffix])
+    except ValueError: pass
+  
+  return result
+
 def getConn():
   """
   Singleton constructor for a Controller. Be aware that this starts as being
@@ -702,6 +737,53 @@
     
     return self._getRelayAttr("flags", default)
   
+  def isVersion(self, minVersionStr):
+    """
+    Checks if we meet the given version. Recognized versions are of the form:
+    <major>.<minor>.<micro>[.<patch>][-<status_tag>]
+    
+    for instance, "0.2.2.13-alpha" or "0.2.1.5". This raises a ValueError if
+    the input isn't recognized, and returns False if unable to fetch our
+    instance's version.
+    
+    According to the spec the status_tag is purely informal, so it's ignored
+    in comparisons.
+    
+    Arguments:
+      minVersionStr - version to be compared against
+    """
+    
+    minVersion = parseVersion(minVersionStr)
+    
+    if minVersion == None:
+      raise ValueError("unrecognized version: %s" % minVersionStr)
+    
+    self.connLock.acquire()
+    
+    result = False
+    if self.isAlive():
+      myVersion = self._getRelayAttr("parsedVersion", None)
+      
+      if not myVersion:
+        result = False
+      elif myVersion[:4] == minVersion[:4]:
+        result = True # versions match
+      else:
+        # compares each of the numeric portions of the version
+        for i in range(4):
+          myVal, minVal = myVersion[i], minVersion[i]
+          
+          if myVal > minVal:
+            result = True
+            break
+          elif myVal < minVal:
+            result = False
+            break
+    
+    self.connLock.release()
+    
+    return result
+  
   def getMyPid(self):
     """
     Provides the pid of the attached tor process (None if no controller exists
@@ -1515,6 +1597,8 @@
           if line.startswith("s "):
             result = line[2:].split()
             break
+      elif key == "parsedVersion":
+        result = parseVersion(self.getInfo("version", ""))
       elif key == "pid":
         result = getPid(int(self.getOption("ControlPort", 9051)), self.getOption("PidFile"))
       elif key == "pathPrefix":



More information about the tor-commits mailing list