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

[tor-commits] [stem/master] Having create_hidden_service() return the *.onion address



commit 260a73ca78a6ffbd6e8b781c3c4558df0f40204e
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date:   Sat Dec 13 16:11:41 2014 -0800

    Having create_hidden_service() return the *.onion address
    
    This isn't reliable since tor restricts the hidden service directory to only be
    readable by the tor user. This sucks, since it's handy to have the hidden
    service address and this is the only way to get it. But oh well, more useful
    than returning a boolean as we did before.
---
 stem/control.py                  |   35 +++++++++++++++++++++++++++++++----
 test/integ/control/controller.py |   18 +++++++++++-------
 2 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index a90dfcb..77a5e3b 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -2237,6 +2237,10 @@ class Controller(BaseController):
     Create a new hidden service. If the directory is already present, a
     new port is added.
 
+    This method returns our *.onion address by reading the hidden service
+    directory. However, this directory is only readable by the tor user, so if
+    unavailable this method returns None.
+
     .. versionadded:: 1.3.0
 
     :param str path: path for the hidden service's data directory
@@ -2245,8 +2249,8 @@ class Controller(BaseController):
     :param int target_port: port of the service, by default this is the same as
       **port**
 
-    :returns: **True** if the hidden service is created, **False** if the
-      hidden service port is already in use
+    :returns: **str** of the onion address for the hidden service if it can be
+      retrieved, **None** otherwise
 
     :raises: :class:`stem.ControllerError` if the call fails
     """
@@ -2268,14 +2272,37 @@ class Controller(BaseController):
       ports = conf[path]['HiddenServicePort']
 
       if (port, target_address, target_port) in ports:
-        return False
+        return
     else:
       conf[path] = {'HiddenServicePort': []}
 
     conf[path]['HiddenServicePort'].append((port, target_address, target_port))
     self.set_hidden_service_conf(conf)
 
-    return True
+    if self.is_localhost():
+      if not os.path.isabs(path):
+        cwd = stem.util.system.cwd(self.get_pid(None))
+
+        if cwd:
+          path = stem.util.system.expand_path(path, cwd)
+
+      if os.path.isabs(path):
+        start_time = time.time()
+        hostname_path = os.path.join(path, 'hostname')
+
+        while not os.path.exists(hostname_path):
+          wait_time = time.time() - start_time
+
+          if wait_time >= 3:
+            return
+          else:
+            time.sleep(0.05)
+
+        try:
+          with open(hostname_path) as hostname_file:
+            return hostname_file.read().strip()
+        except:
+          pass
 
   def remove_hidden_service(self, path, port = None):
     """
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 386eb8e..8b9759c 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -505,27 +505,31 @@ class TestController(unittest.TestCase):
 
         # add already existing services, with/without explicit target
 
-        self.assertFalse(controller.create_hidden_service('test_hidden_service1/', 8020))
-        self.assertFalse(controller.create_hidden_service('test_hidden_service1/', 8021, target_port = 8021))
+        self.assertEqual(None, controller.create_hidden_service('test_hidden_service1/', 8020))
+        self.assertEqual(None, controller.create_hidden_service('test_hidden_service1/', 8021, target_port = 8021))
         self.assertDictEqual(initialconf, controller.get_hidden_service_conf())
 
         # add a new service, with/without explicit target
 
-        self.assertTrue(controller.create_hidden_service('test_hidden_serviceX/', 8888))
-        self.assertTrue(controller.create_hidden_service('test_hidden_serviceX/', 8989, target_port = 8021))
+        hs_path = os.path.join(os.getcwd(), 'test_hidden_serviceX')
+        hs_address1 = controller.create_hidden_service(hs_path, 8888)
+        hs_address2 = controller.create_hidden_service(hs_path, 8989, target_port = 8021)
+
+        self.assertEqual(hs_address1, hs_address2)
+        self.assertTrue(hs_address1.endswith('.onion'))
 
         conf = controller.get_hidden_service_conf()
         self.assertEqual(4, len(conf))
-        self.assertEqual(2, len(conf['test_hidden_serviceX/']['HiddenServicePort']))
+        self.assertEqual(2, len(conf[hs_path]['HiddenServicePort']))
 
         # remove a hidden service, the service dir should still be there
 
-        controller.remove_hidden_service('test_hidden_serviceX/', 8888)
+        controller.remove_hidden_service(hs_path, 8888)
         self.assertEqual(4, len(controller.get_hidden_service_conf()))
 
         # remove a service completely, it should now be gone
 
-        controller.remove_hidden_service('test_hidden_serviceX/', 8989)
+        controller.remove_hidden_service(hs_path, 8989)
         self.assertEqual(3, len(controller.get_hidden_service_conf()))
       finally:
         controller.set_hidden_service_conf({})  # drop hidden services created during the test



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits