[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r24019: {arm} Hack to fix relative COOKIEFILE paths This is to improve usa (in arm/trunk/src: . util)



Author: atagar
Date: 2011-01-02 03:38:32 +0000 (Sun, 02 Jan 2011)
New Revision: 24019

Modified:
   arm/trunk/src/starter.py
   arm/trunk/src/util/procTools.py
   arm/trunk/src/util/sysTools.py
   arm/trunk/src/util/torConfig.py
Log:
Hack to fix relative COOKIEFILE paths
This is to improve usability with tbb instances, and will be removed when https://trac.torproject.org/projects/tor/ticket/1101 is resolved.



Modified: arm/trunk/src/starter.py
===================================================================
--- arm/trunk/src/starter.py	2011-01-02 02:34:20 UTC (rev 24018)
+++ arm/trunk/src/starter.py	2011-01-02 03:38:32 UTC (rev 24019)
@@ -10,6 +10,7 @@
 import sys
 import time
 import getopt
+import socket
 
 import version
 import interface.controller
@@ -280,7 +281,36 @@
   TorCtl.INCORRECT_PASSWORD_MSG = "Controller password found in '%s' was incorrect" % configPath
   authPassword = config.get("startup.controlPassword", CONFIG["startup.controlPassword"])
   conn = TorCtl.TorCtl.connect(controlAddr, controlPort, authPassword)
-  if conn == None: sys.exit(1)
+  if conn == None:
+    # Connecting to the control port will probably fail if it's using cookie
+    # authentication and the cookie path is relative (unfortunately this is
+    # the case for TBB). This is discussed in:
+    # https://trac.torproject.org/projects/tor/ticket/1101
+    #
+    # Until this is fixed including a hack to expand the relative path in
+    # these cases, setting conn to the established connection if successful
+    # and leaving it undefined otherwise. Even if successful this prints the
+    # error message saying that the auth cookie couldn't be found
+    # (unfortunately this is unavoidable without either changing TorCtl or
+    # making this a much bigger hack).
+    
+    try:
+      s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+      s.connect((controlAddr, controlPort))
+      tmpConn = TorCtl.TorCtl.Connection(s)
+      
+      if tmpConn.get_auth_type() == TorCtl.TorCtl.AUTH_TYPE.COOKIE:
+        cookiePath = tmpConn.get_auth_cookie_path()
+        torPid = util.torTools.getPid(controlPort)
+        
+        if torPid and cookiePath[0] != "/":
+          # previous attempt to connect failed due to having a relative path - fix it
+          tmpConn._cookiePath = util.sysTools.expandRelativePath(cookiePath, torPid)
+          tmpConn.authenticate(cookiePath)
+          conn = tmpConn # success!
+    except: pass
+    
+    if conn == None: sys.exit(1)
   
   # removing references to the controller password so the memory can be freed
   # (unfortunately python does allow for direct access to the memory so this

Modified: arm/trunk/src/util/procTools.py
===================================================================
--- arm/trunk/src/util/procTools.py	2011-01-02 02:34:20 UTC (rev 24018)
+++ arm/trunk/src/util/procTools.py	2011-01-02 03:38:32 UTC (rev 24019)
@@ -82,7 +82,7 @@
   
   return SYS_PHYSICAL_MEMORY
 
-def getCwd(pid):
+def getPwd(pid):
   """
   Provides the current working directory for the given process.
   

Modified: arm/trunk/src/util/sysTools.py
===================================================================
--- arm/trunk/src/util/sysTools.py	2011-01-02 02:34:20 UTC (rev 24018)
+++ arm/trunk/src/util/sysTools.py	2011-01-02 03:38:32 UTC (rev 24019)
@@ -17,6 +17,7 @@
 CALL_CACHE_LOCK = threading.RLock() # governs concurrent modifications of CALL_CACHE
 
 PROCESS_NAME_CACHE = {} # mapping of pids to their process names
+PWD_CACHE = {}          # mapping of pids to their present working directory
 RESOURCE_TRACKERS = {}  # mapping of pids to their resource tracker instances
 
 # Runtimes for system calls, used to estimate cpu usage. Entries are tuples of
@@ -138,6 +139,61 @@
     PROCESS_NAME_CACHE[pid] = processName
     return processName
 
+def getPwd(pid):
+  """
+  Provices the working directory of the given process. This raises an IOError
+  if it can't be determined.
+  
+  Arguments:
+    pid - pid of the process
+  """
+  
+  if not pid: raise IOError("we couldn't get the pid")
+  elif pid in PWD_CACHE: return PWD_CACHE[pid]
+  
+  # try fetching via the proc contents if available
+  if procTools.isProcAvailable():
+    try:
+      pwd = procTools.getPwd(pid)
+      PWD_CACHE[pid] = pwd
+      return pwd
+    except IOError: pass # fall back to pwdx
+  
+  try:
+    # pwdx results are of the form:
+    # 3799: /home/atagar
+    # 5839: No such process
+    results = sysTools.call("pwdx %s" % pid)
+    if not results:
+      raise IOError("pwdx didn't return any results")
+    elif results[0].endswith("No such process"):
+      raise IOError("pwdx reported no process for pid " + pid)
+    elif len(results) != 1 or results.count(" ") != 1:
+      raise IOError("we got unexpected output from pwdx")
+    else:
+      pwd = results[0][results[0].find(" ") + 1:]
+      PWD_CACHE[pid] = pwd
+      return pwd
+  except IOError, exc:
+    raise IOError("the pwdx call failed: " + str(exc))
+
+def expandRelativePath(path, ownerPid):
+  """
+  Expands relative paths to be an absolute path with reference to a given
+  process. This raises an IOError if the process pwd is required and can't be
+  resolved.
+  
+  Arguments:
+    path     - path to be expanded
+    ownerPid - pid of the process to which the path belongs
+  """
+  
+  if not path or path[0] == "/": return path
+  else:
+    if path.startswith("./"): path = path[2:]
+    processPwd = getPwd(ownerPid)
+    return "%s/%s" % (processPwd, path)
+
 def call(command, cacheAge=0, suppressExc=False, quiet=True):
   """
   Convenience function for performing system calls, providing:

Modified: arm/trunk/src/util/torConfig.py
===================================================================
--- arm/trunk/src/util/torConfig.py	2011-01-02 02:34:20 UTC (rev 24018)
+++ arm/trunk/src/util/torConfig.py	2011-01-02 03:38:32 UTC (rev 24019)
@@ -288,32 +288,13 @@
   
   conn = torTools.getConn()
   configLocation = conn.getInfo("config-file")
+  torPid, torPrefix = conn.getMyPid(), conn.getPathPrefix()
   if not configLocation: raise IOError("unable to query the torrc location")
   
-  # checks if this is a relative path, needing the tor pwd to be appended
-  if configLocation[0] != "/":
-    torPid = conn.getMyPid()
-    failureMsg = "querying tor's pwd failed because %s"
-    if not torPid: raise IOError(failureMsg % "we couldn't get the pid")
-    
-    try:
-      # pwdx results are of the form:
-      # 3799: /home/atagar
-      # 5839: No such process
-      results = sysTools.call("pwdx %s" % torPid)
-      if not results:
-        raise IOError(failureMsg % "pwdx didn't return any results")
-      elif results[0].endswith("No such process"):
-        raise IOError(failureMsg % ("pwdx reported no process for pid " + torPid))
-      elif len(results) != 1 or results.count(" ") != 1:
-        raise IOError(failureMsg % "we got unexpected output from pwdx")
-      else:
-        pwdPath = results[0][results[0].find(" ") + 1:]
-        configLocation = "%s/%s" % (pwdPath, configLocation)
-    except IOError, exc:
-      raise IOError(failureMsg % ("the pwdx call failed: " + str(exc)))
-  
-  return conn.getPathPrefix() + configLocation
+  try:
+    return torPrefix + sysTools.expandRelativePath(configLocation, torPid)
+  except IOError, exc:
+    raise IOError("querying tor's pwd failed because %s" % exc)
 
 def getMultilineParameters():
   """