[tor-commits] [arm/release] Starting Tor instance at wizard completion

atagar at torproject.org atagar at torproject.org
Sun Jul 17 06:08:31 UTC 2011


commit 95cd487cc30c86d62f6ae44cc41cf44129d917ad
Author: Damian Johnson <atagar at torproject.org>
Date:   Fri Jul 8 16:30:17 2011 -0700

    Starting Tor instance at wizard completion
    
    This starts (or attempts to start) a Tor instance when the wizard finishes.
    Currently this just works for the basic use case where we have the permissions
    necessary to start Tor.
---
 src/cli/controller.py           |   13 ++++++++++
 src/cli/wizard.py               |   51 +++++++++++++++++++++++++++-----------
 src/resources/torrcTemplate.txt |    1 +
 src/util/torConfig.py           |    2 +-
 4 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/src/cli/controller.py b/src/cli/controller.py
index c9ab6e7..633296e 100644
--- a/src/cli/controller.py
+++ b/src/cli/controller.py
@@ -3,6 +3,7 @@ Main interface loop for arm, periodically redrawing the screen and issuing
 user input to the proper panels.
 """
 
+import os
 import time
 import curses
 import threading
@@ -25,6 +26,7 @@ from util import connections, conf, enum, log, panel, sysTools, torConfig, torTo
 ARM_CONTROLLER = None
 
 CONFIG = {"startup.events": "N3",
+          "startup.dataDirectory": "~/.arm",
           "startup.blindModeEnabled": False,
           "features.panels.show.graph": True,
           "features.panels.show.log": True,
@@ -366,6 +368,17 @@ class Controller:
     if redraw: controlPanel.redraw(True)
     else: self._forceRedraw = True
   
+  def getDataDirectory(self):
+    """
+    Provides the path where arm's resources are being placed. The path ends
+    with a slash and is created if it doesn't already exist.
+    """
+    
+    dataDir = CONFIG["startup.dataDirectory"]
+    if not dataDir.endswith("/"): dataDir += "/"
+    if not os.path.exists(dataDir): os.makedirs(dataDir)
+    return os.path.expanduser(dataDir)
+  
   def isDone(self):
     """
     True if arm should be terminated, false otherwise.
diff --git a/src/cli/wizard.py b/src/cli/wizard.py
index 946ecd1..3ab3b9d 100644
--- a/src/cli/wizard.py
+++ b/src/cli/wizard.py
@@ -5,13 +5,16 @@ that's used by arm to run its own tor instance.
 
 import os
 import sys
+import shutil
 import functools
 import curses
 
 import cli.popups
 import cli.controller
 
-from util import connections, enum, log, torConfig, uiTools
+from TorCtl import TorCtl
+
+from util import connections, enum, log, torConfig, torTools, uiTools
 
 # template used to generate the torrc
 TORRC_TEMPLATE = "resources/torrcTemplate.txt"
@@ -72,8 +75,7 @@ MSG_COLOR = "green"
 OPTION_COLOR = "yellow"
 DISABLED_COLOR = "cyan"
 
-CONFIG = {"startup.dataDirectory": "~/.arm",
-          "wizard.message.role": "",
+CONFIG = {"wizard.message.role": "",
           "wizard.message.relay": "",
           "wizard.message.exit": "",
           "wizard.message.bridge": "",
@@ -251,6 +253,7 @@ def showWizard():
   
   # remembers the last selection made on the type prompt page
   relaySelection = RelayType.RELAY
+  controller = cli.controller.getController()
   
   while True:
     if relayType == None:
@@ -265,18 +268,36 @@ def showWizard():
       elif selection == NEXT:
         generatedTorrc = getTorrc(relayType, config)
         
-        dataDir = CONFIG["startup.dataDirectory"]
-        if not dataDir.endswith("/"): dataDir += "/"
-        torrcLocation = os.path.expanduser(dataDir) + "torrc"
-        
-        cli.controller.getController().requestRedraw(True)
+        torrcLocation = controller.getDataDirectory() + "torrc"
+        controller.requestRedraw(True)
         confirmationSelection = showConfirmationDialog(generatedTorrc, torrcLocation)
         
         if confirmationSelection == NEXT:
-          log.log(log.NOTICE, "Resulting torrc:\n%s" % generatedTorrc)
-          break # TODO: implement next screen
-        elif confirmationSelection == CANCEL:
+          log.log(log.INFO, "Writing torrc to '%s':\n%s" % (torrcLocation, generatedTorrc))
+          
+          # if the torrc already exists then save it to a _bak file
+          if os.path.exists(torrcLocation):
+            shutil.copy(torrcLocation, torrcLocation + "_bak")
+          
+          # writes the torrc contents
+          torrcFile = open(torrcLocation, "w")
+          torrcFile.write(generatedTorrc)
+          torrcFile.close()
+          
+          try:
+            os.system("tor --quiet -f %s&" % torrcLocation)
+            torctlConn, authType, authValue = TorCtl.preauth_connect(controlPort = 9052)
+            
+            if authType == TorCtl.AUTH_TYPE.COOKIE:
+              torctlConn.authenticate(authValue)
+              torTools.getConn().init(torctlConn)
+            else:
+              raise IOError("unexpected authentication type '%s'" % authType)
+          except IOError, exc:
+            log.log(log.WARN, "Unable to start tor: %s" % exc)
+          
           break
+        elif confirmationSelection == CANCEL: break
     
     # redraws screen to clear away the dialog we just showed
     cli.controller.getController().requestRedraw(True)
@@ -464,9 +485,9 @@ def getTorrc(relayType, config):
   templateOptions["BURST"] = "%i %s" % (int(relayRateComp[0]) * 2, " ".join(relayRateComp[1:]))
   
   # exit notice will be in our data directory
-  dataDir = CONFIG["startup.dataDirectory"]
-  if not dataDir.endswith("/"): dataDir += "/"
-  templateOptions["NOTICE_PATH"] = os.path.expanduser(dataDir) + "exit-notice.html"
+  dataDir = cli.controller.getController().getDataDirectory()
+  templateOptions["NOTICE_PATH"] = dataDir + "exit-notice.html"
+  templateOptions["LOG_ENTRY"] = "notice file %stor-log" % dataDir
   
   policyCategories = []
   if not config[Options.POLICY].getValue():
@@ -564,7 +585,7 @@ def showConfirmationDialog(torrcContents, torrcLocation):
         div = option.find("#")
         if div != -1: option, comment = option[:div], option[div:]
         
-        div = option.find(" ")
+        div = option.strip().find(" ")
         if div != -1: option, arg = option[:div], option[div:]
         
         drawX = 2 + xOffset
diff --git a/src/resources/torrcTemplate.txt b/src/resources/torrcTemplate.txt
index abedd7f..072f847 100644
--- a/src/resources/torrcTemplate.txt
+++ b/src/resources/torrcTemplate.txt
@@ -9,6 +9,7 @@
 [NEWLINE]
 ControlPort 9052              # port controllers can connect to
 CookieAuthentication 1        # method for controller authentication
+Log [LOG_ENTRY]               # location to log notices, warnings, and errors
 
 [IF RELAY | EXIT | BRIDGE]
   RunAsDaemon 1               # runs as a background process
diff --git a/src/util/torConfig.py b/src/util/torConfig.py
index e5f1cb2..8510c7a 100644
--- a/src/util/torConfig.py
+++ b/src/util/torConfig.py
@@ -930,7 +930,7 @@ def renderTorrc(template, options, commentIndent = 30):
           comment = "# %s" % comment.strip()
         
         # parses the argument from the option
-        if " " in parsedLine:
+        if " " in parsedLine.strip():
           option, arg = parsedLine.split(" ", 1)
           option = option.strip()
         else:





More information about the tor-commits mailing list