commit ec49c74ba52d9410d6f108a4e76dfad063d40500 Author: Damian Johnson atagar@torproject.org Date: Wed Jul 27 12:10:02 2011 -0700
Wizard hooks for configuring system wide torrc
Providing an option to apply the wizard config to the system wide torrc if it's available (user has already done the --init prep). --- src/cli/wizard.py | 98 +++++++++++++++++++++++++++++++++++++++++++++++------ src/settings.cfg | 4 ++ 2 files changed, 91 insertions(+), 11 deletions(-)
diff --git a/src/cli/wizard.py b/src/cli/wizard.py index 08e9d0b..31f2f70 100644 --- a/src/cli/wizard.py +++ b/src/cli/wizard.py @@ -24,7 +24,7 @@ TORRC_TEMPLATE = "resources/torrcTemplate.txt" RelayType = enum.Enum("RESUME", "RELAY", "EXIT", "BRIDGE", "CLIENT")
# all options that can be configured -Options = enum.Enum("DIVIDER", "CONTROL", "NICKNAME", "CONTACT", "NOTIFY", "BANDWIDTH", "LIMIT", "CLIENT", "LOWPORTS", "PORTFORWARD", "STARTUP", "RSHUTDOWN", "CSHUTDOWN", "NOTICE", "POLICY", "WEBSITES", "EMAIL", "IM", "MISC", "PLAINTEXT", "DISTRIBUTE", "BRIDGED", "BRIDGE1", "BRIDGE2", "BRIDGE3", "REUSE") +Options = enum.Enum("DIVIDER", "CONTROL", "NICKNAME", "CONTACT", "NOTIFY", "BANDWIDTH", "LIMIT", "CLIENT", "LOWPORTS", "PORTFORWARD", "SYSTEM", "STARTUP", "RSHUTDOWN", "CSHUTDOWN", "NOTICE", "POLICY", "WEBSITES", "EMAIL", "IM", "MISC", "PLAINTEXT", "DISTRIBUTE", "BRIDGED", "BRIDGE1", "BRIDGE2", "BRIDGE3", "REUSE") RelayOptions = {RelayType.RELAY: (Options.NICKNAME, Options.CONTACT, Options.NOTIFY, @@ -34,7 +34,8 @@ RelayOptions = {RelayType.RELAY: (Options.NICKNAME, Options.LOWPORTS, Options.PORTFORWARD, Options.STARTUP, - Options.RSHUTDOWN), + Options.RSHUTDOWN, + Options.SYSTEM), RelayType.EXIT: (Options.NICKNAME, Options.CONTACT, Options.NOTIFY, @@ -45,6 +46,7 @@ RelayOptions = {RelayType.RELAY: (Options.NICKNAME, Options.PORTFORWARD, Options.STARTUP, Options.RSHUTDOWN, + Options.SYSTEM, Options.DIVIDER, Options.NOTICE, Options.POLICY, @@ -60,13 +62,15 @@ RelayOptions = {RelayType.RELAY: (Options.NICKNAME, Options.LOWPORTS, Options.PORTFORWARD, Options.STARTUP, - Options.RSHUTDOWN), + Options.RSHUTDOWN, + Options.SYSTEM), RelayType.CLIENT: (Options.BRIDGED, Options.BRIDGE1, Options.BRIDGE2, Options.BRIDGE3, Options.REUSE, - Options.CSHUTDOWN)} + Options.CSHUTDOWN, + Options.SYSTEM)}
# option sets CUSTOM_POLICIES = (Options.WEBSITES, Options.EMAIL, Options.IM, Options.MISC, Options.PLAINTEXT) @@ -95,6 +99,12 @@ VERSION_REQUIREMENTS = {Options.PORTFORWARD: "0.2.3.1-alpha"} TOR_DEFAULTS = {Options.BANDWIDTH: "5 MB", Options.REUSE: "10 minutes"}
+# path for the torrc to be placed if replacing the torrc for the system wide +# tor instance +SYSTEM_DROP_PATH = "/var/lib/tor-arm/torrc" +OVERRIDE_SCRIPT = "/usr/share/arm/resources/torrcOverride/override.py" +OVERRIDE_SETUID_SCRIPT = "/usr/bin/torrc-override" + CONFIG = {"wizard.message.role": "", "wizard.message.relay": "", "wizard.message.exit": "", @@ -306,6 +316,13 @@ def showWizard(): if not sysTools.isAvailable("tor-fw-helper"): disabledOpt.append(Options.PORTFORWARD)
+ # If we haven't run 'resources/torrcOverride/override.py --init' or lack + # permissions then we aren't able to deal with the system wide tor instance. + # Also drop the optoin if we aren't installed since override.py won't be at + # the expected path. + if not os.path.exists(SYSTEM_DROP_PATH) or not os.path.exists(OVERRIDE_SCRIPT): + disabledOpt.append(Options.SYSTEM) + while True: if relayType == None: selection = promptRelayType(relaySelection) @@ -331,16 +348,26 @@ def showWizard(): if confirmationSelection == NEXT: log.log(log.INFO, "Writing torrc to '%s':\n%s" % (torrcLocation, generatedTorrc))
+ isSystemReplace = not Options.SYSTEM in disabledOpt and config[Options.SYSTEM].getValue() + if isSystemReplace: torrcLocation = SYSTEM_DROP_PATH + # if the torrc already exists then save it to a _bak file isBackedUp = False if os.path.exists(torrcLocation): - shutil.copy(torrcLocation, torrcLocation + "_bak") - isBackedUp = True + try: + shutil.copy(torrcLocation, torrcLocation + "_bak") + isBackedUp = True + except IOError, exc: + log.log(log.WARN, "Unable to backup the torrc: %s" % exc)
# writes the torrc contents - torrcFile = open(torrcLocation, "w") - torrcFile.write(generatedTorrc) - torrcFile.close() + try: + torrcFile = open(torrcLocation, "w") + torrcFile.write(generatedTorrc) + torrcFile.close() + except IOError, exc: + log.log(log.ERR, "Unable to make torrc: %s" % exc) + break
# logs where we placed the torrc msg = "Tor configuration placed at '%s'" % torrcLocation @@ -367,7 +394,53 @@ def showWizard(): msg = "Exit notice placed at '%s/index.html'. Some of the sections are specific to US relay operators so please change the "FIXME" sections if this is inappropriate." % dst log.log(log.NOTICE, msg)
- if manager.isTorrcAvailable(): + runCommand, exitCode = None, 1 + + if isSystemReplace: + # running override.py needs root so... + # - if running as root (bad user, no biscuit!) then run it directly + # - if the setuid binary is available at '/usr/bin/torrc-override' + # then use that + # - attempt sudo in case passwordless sudo is available + # - if all of the above fail then log instructions + + if os.geteuid() == 0: runCommand = OVERRIDE_SCRIPT + elif os.path.exists(OVERRIDE_SETUID_SCRIPT): runCommand = OVERRIDE_SETUID_SCRIPT + else: + # The -n argument to sudo is *supposed* to be available starting + # with 1.7.0 [1] however this is a dirty lie (Ubuntu 9.10 uses + # 1.7.0 and even has the option in its man page, but it doesn't + # work). Instead checking for version 1.7.1. + # + # [1] http://www.sudo.ws/pipermail/sudo-users/2009-January/003889.html + + sudoVersionResult = sysTools.call("sudo -V") + + # version output looks like "Sudo version 1.7.2p7" + if len(sudoVersionResult) == 1 and sudoVersionResult.count(" ") >= 2: + versionNum = 0 + + for comp in sudoVersionResult[0].split(" ")[2].split("."): + if comp and comp[0].isdigit(): + versionNum = (10 * versionNum) + int(comp) + else: + # invalid format + log.log(log.INFO, "Unrecognized sudo version string: %s" % sudoVersionResult[0]) + versionNum = 0 + break + + if versionNum >= 171: + runCommand = "sudo -n %s" % OVERRIDE_SCRIPT + else: + log.log(log.INFO, "Insufficient sudo version for the -n argument") + + if runCommand: exitCode = os.system("%s > /dev/null 2>&1" % runCommand) + + if exitCode != 0: + msg = "Tor needs root permissions to replace the system wide torrc. To continue...\n- open another terminal\n- run "sudo %s"\n- press 'x' here to tell tor to reload" % OVERRIDE_SCRIPT + log.log(log.NOTICE, msg) + else: torTools.getConn().reload() + elif manager.isTorrcAvailable(): # If we're connected to a managed instance then just need to # issue a sighup to pick up the new settings. Otherwise starts # a new tor instance. @@ -603,9 +676,12 @@ def getTorrc(relayType, config, disabledOpt): dataDir = cli.controller.getController().getDataDirectory() templateOptions["NOTICE_PATH"] = "%sexitNotice/index.html" % dataDir templateOptions["LOG_ENTRY"] = "notice file %stor_log" % dataDir - templateOptions["DATA_DIR"] = "%stor_data" % dataDir templateOptions["USERNAME"] = getpass.getuser()
+ # using custom data directory, unless this is for a system wide instance + if not config[Options.SYSTEM].getValue() or Options.SYSTEM in disabledOpt: + templateOptions["DATA_DIR"] = "%stor_data" % dataDir + policyCategories = [] if not config[Options.POLICY].getValue(): policyCategories = ["web", "mail", "im", "misc"] diff --git a/src/settings.cfg b/src/settings.cfg index 750ae9e..9154ed5 100644 --- a/src/settings.cfg +++ b/src/settings.cfg @@ -354,6 +354,7 @@ wizard.toggle Portforward => Enabled, Disabled wizard.toggle Startup => Yes, No wizard.toggle Rshutdown => Yes, No wizard.toggle Cshutdown => Yes, No +wizard.toggle System => Yes, No wizard.toggle Notice => Yes, No wizard.toggle Policy => Custom, Default wizard.toggle Websites => Allow, Block @@ -383,6 +384,7 @@ wizard.default Bandwidth => 5 MB/s wizard.default Startup => true wizard.default Rshutdown => false wizard.default Cshutdown => true +wizard.default System => true wizard.default Client => false wizard.default Lowports => true wizard.default Portforward => true @@ -421,6 +423,7 @@ wizard.label.opt Portforward => Port Forwarding wizard.label.opt Startup => Run At Startup wizard.label.opt Rshutdown => Shutdown With Arm wizard.label.opt Cshutdown => Shutdown With Arm +wizard.label.opt System => Use System Instance wizard.label.opt Notice => Disclaimer Notice wizard.label.opt Policy => Exit Policy wizard.label.opt Websites => Web Browsing @@ -452,6 +455,7 @@ wizard.description.opt Portforward => If needed, attempts NAT traversal using UP wizard.description.opt Startup => Runs Tor in the background when the system starts. wizard.description.opt Rshutdown => When you quit arm the Tor process is stopped thirty seconds later. This delay is so people using you can gracefully switch their circuits. wizard.description.opt Cshutdown => Stops the Tor process when you quit arm. +wizard.description.opt System => Use the system wide tor instance rather than making one of our own. wizard.description.opt Notice => Provides a disclaimer that this is an exit on port 80 (http://www.atagar.com/exitNotice). wizard.description.opt Policy => Ports allowed to exit from your relay. The default policy allows for common services while limiting the chance of getting a DMCA takedown for torrent traffic (http://www.atagar.com/exitPolicy). wizard.description.opt Websites => General Internet browsing including HTTP (80), HTTPS (443), common alternatives (81, 8008), and proxies (3128, 8080)
tor-commits@lists.torproject.org