commit ed16a0491ad55e16b8ea3fab2abaca7d65bdae46
Author: Damian Johnson <atagar(a)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")