[tor-commits] [arm/master] Checking if PortForwarding is available

atagar at torproject.org atagar at torproject.org
Tue Jul 12 21:36:33 UTC 2011


commit ed16a0491ad55e16b8ea3fab2abaca7d65bdae46
Author: Damian Johnson <atagar at torproject.org>
Date:   Mon Jul 11 10:20:44 2011 -0700

    Checking if PortForwarding is available
    
    The PortForwarding was added in tor 0.2.3.1-alpha, and requires that
    tor-fw-helper exists in the user's path to function. Checking for both
    of these conditions and dropping the option if they're not met.
---
 src/cli/wizard.py    |   42 +++++++++++++++++++++++++++++++++++++-----
 src/util/torTools.py |   49 ++++++++++++++++++++++++++++---------------------
 2 files changed, 65 insertions(+), 26 deletions(-)

diff --git a/src/cli/wizard.py b/src/cli/wizard.py
index f796e41..efb6d98 100644
--- a/src/cli/wizard.py
+++ b/src/cli/wizard.py
@@ -89,6 +89,9 @@ BRACKETS = ((' ', ' '),
             ('{', '}'),
             ('|', '|'))
 
+# version requirements for options
+VERSION_REQUIREMENTS = {Options.PORTFORWARD: "0.2.3.1-alpha"}
+
 # tor's defaults for config options, used to filter unneeded options
 TOR_DEFAULTS = {Options.BANDWIDTH: "5 MB",
                 Options.REUSE: "10 minutes"}
@@ -232,6 +235,18 @@ def showWizard():
     log.log(log.WARN, msg)
     return
   
+  # gets tor's version
+  torVersion = None
+  try:
+    versionQuery = sysTools.call("tor --version")
+    
+    for line in versionQuery:
+      if line.startswith("Tor version "):
+        torVersion = torTools.parseVersion(line.split(" ")[2])
+        break
+  except IOError, exc:
+    log.log(log.INFO, "'tor --version' query failed: %s" % exc)
+  
   relayType, config = None, {}
   for option in Options.values():
     if option == Options.DIVIDER:
@@ -280,6 +295,18 @@ def showWizard():
   manager = controller.getTorManager()
   relaySelection = RelayType.RESUME if manager.isTorrcAvailable() else RelayType.RELAY
   
+  # excludes options that are either disabled or for a future tor version
+  disabledOpt = list(CONFIG["wizard.disabled"])
+  
+  for opt, optVersion in VERSION_REQUIREMENTS.items():
+    if not torVersion or not torTools.isVersion(torVersion, torTools.parseVersion(optVersion)):
+      disabledOpt.append(opt)
+  
+  # the port forwarding option would only work if tor-fw-helper is in the path
+  if not Options.PORTFORWARD in disabledOpt:
+    if not sysTools.isAvailable("tor-fw-helper"):
+      disabledOpt.append(Options.PORTFORWARD)
+  
   while True:
     if relayType == None:
       selection = promptRelayType(relaySelection)
@@ -292,11 +319,11 @@ def showWizard():
         break
       else: relayType, relaySelection = selection, selection
     else:
-      selection = promptConfigOptions(relayType, config)
+      selection = promptConfigOptions(relayType, config, disabledOpt)
       
       if selection == BACK: relayType = None
       elif selection == NEXT:
-        generatedTorrc = getTorrc(relayType, config)
+        generatedTorrc = getTorrc(relayType, config, disabledOpt)
         
         torrcLocation = manager.getTorrcPath()
         controller.requestRedraw(True)
@@ -404,14 +431,14 @@ def promptRelayType(initialSelection):
   finally:
     cli.popups.finalize()
 
-def promptConfigOptions(relayType, config):
+def promptConfigOptions(relayType, config, disabledOpt):
   """
   Prompts the user for the configuration of an internal relay.
   """
   
   topContent = _splitStr(CONFIG.get("wizard.message.%s" % relayType.lower(), ""), 54)
   
-  options = [config[opt] for opt in RelayOptions[relayType] if not opt in CONFIG["wizard.disabled"]]
+  options = [config[opt] for opt in RelayOptions[relayType] if not opt in disabledOpt]
   options.append(Options.DIVIDER)
   options.append(ConfigOption(BACK, "general", "(to role selection)"))
   options.append(ConfigOption(NEXT, "general", "(to confirm options)"))
@@ -503,7 +530,7 @@ def promptConfigOptions(relayType, config):
   finally:
     cli.popups.finalize()
 
-def getTorrc(relayType, config):
+def getTorrc(relayType, config, disabledOpt):
   """
   Provides the torrc generated for the given options.
   """
@@ -601,6 +628,11 @@ def getTorrc(relayType, config):
   
   templateOptions["BRIDGES"] = "\n".join(bridgeLines)
   
+  # removes disabled options
+  for opt in disabledOpt:
+    if opt.upper() in templateOptions:
+      del templateOptions[opt.upper()]
+  
   # removes options if they match the tor defaults
   for opt in TOR_DEFAULTS:
     if templateOptions[opt.upper()] == TOR_DEFAULTS[opt]:
diff --git a/src/util/torTools.py b/src/util/torTools.py
index 4a18a4f..f81e10a 100644
--- a/src/util/torTools.py
+++ b/src/util/torTools.py
@@ -52,9 +52,8 @@ CONTROLLER = None # singleton Controller instance
 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", "parsedVersion", "pid",
-              "user", "fdLimit", "pathPrefix", "startTime", "authorities",
-              "circuits", "hsPorts")
+              "bwObserved", "bwMeasured", "flags", "pid", "user", "fdLimit",
+              "pathPrefix", "startTime", "authorities", "circuits", "hsPorts")
 CACHE_GETINFO_PREFIX_ARGS = ("ip-to-country/", )
 
 # Tor has a couple messages (in or/router.c) for when our ip address changes:
@@ -301,6 +300,29 @@ def parseVersion(versionStr):
   
   return result
 
+def isVersion(myVersion, minVersion):
+  """
+  Checks if the given version meets a given minimum. Both arguments are
+  expected to be version tuples. To get this from a version string use the
+  parseVersion function.
+  
+  Arguments:
+    myVersion  - tor version tuple
+    minVersion - version tuple to be checked against
+  """
+  
+  if myVersion[:4] == minVersion[:4]:
+    return 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: return True
+      elif myVal < minVal: return False
+    
+    return True # versions match (should have been caught above...)
+
 def getConn():
   """
   Singleton constructor for a Controller. Be aware that this starts as being
@@ -890,23 +912,10 @@ class Controller(TorCtl.PostEventListener):
     
     result = False
     if self.isAlive():
-      myVersion = self._getRelayAttr("parsedVersion", None)
+      myVersion = parseVersion(self.getInfo("version", ""))
       
-      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
+      if not myVersion: result = False
+      else: result = isVersion(myVersion, minVersion)
     
     self.connLock.release()
     
@@ -1853,8 +1862,6 @@ class Controller(TorCtl.PostEventListener):
           if line.startswith("s "):
             result = line[2:].split()
             break
-      elif key == "parsedVersion":
-        result = parseVersion(self.getInfo("version", ""))
       elif key == "pid":
         result = self.getInfo("process/pid")
         





More information about the tor-commits mailing list