[tor-commits] [stem/master] Controller method for getting custom config options
atagar at torproject.org
atagar at torproject.org
Tue Dec 22 17:40:07 UTC 2015
commit e1124d2d29f8cd92d88d46f1024c81eafd5595f1
Author: Damian Johnson <atagar at torproject.org>
Date: Tue Dec 22 09:28:12 2015 -0800
Controller method for getting custom config options
Tor doesn't provide a reliable method of checking 'which config options have I
set?'. As such, adding one.
---
docs/change_log.rst | 1 +
stem/control.py | 48 ++++++++++++++++++++++++++++++++++++++
test/integ/control/controller.py | 20 ++++++++++++++++
3 files changed, 69 insertions(+)
diff --git a/docs/change_log.rst b/docs/change_log.rst
index 87ea053..39d109c 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -48,6 +48,7 @@ The following are only available within Stem's `git repository
* Added `stem.manual <api/manual.html>`_, which provides information available about Tor from `its manual <https://www.torproject.org/docs/tor-manual.html.en>`_ (:trac:`8251`)
* :func:`~stem.connection.connect` and :func:`~stem.control.Controller.from_port` now connect to both port 9051 (relay's default) and 9151 (Tor Browser's default) (:trac:`16075`)
* Added `support for NETWORK_LIVENESS events <api/response.html#stem.response.events.NetworkLivenessEvent>`_ (:spec:`44aac63`)
+ * Added :func:`~stem.control.Controller.get_custom_conf` to the :class:`~stem.control.Controller`
* Added :func:`~stem.control.Controller.is_user_traffic_allowed` to the :class:`~stem.control.Controller`
* Added the replica attribute to the :class:`~stem.response.events.HSDescEvent` (:spec:`4989e73`)
* IPv6 addresses could trigger errors in :func:`~stem.control.Controller.get_listeners`, :class:`~stem.response.events.ORConnEvent`, and quite a few other things (:trac:`16174`)
diff --git a/stem/control.py b/stem/control.py
index 3b1edfa..91c607e 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -93,6 +93,7 @@ If you're fine with allowing your script to raise exceptions then this can be mo
|
|- get_conf - gets the value of a configuration option
|- get_conf_map - gets the values of multiple configuration options
+ |- get_custom_conf - provides configuration options that differ from their defaults
|- set_conf - sets the value of a configuration option
|- reset_conf - reverts configuration options to their default values
|- set_options - sets or resets the values of multiple configuration options
@@ -1986,6 +1987,8 @@ class Controller(BaseController):
def get_conf(self, param, default = UNDEFINED, multiple = False):
"""
+ get_conf(param, default = UNDEFINED, multiple = False)
+
Queries the current value for a configuration option. Some configuration
options (like the ExitPolicy) can have multiple values. This provides a
**list** with all of the values if **multiple** is **True**. Otherwise this
@@ -2033,6 +2036,8 @@ class Controller(BaseController):
def get_conf_map(self, params, default = UNDEFINED, multiple = True):
"""
+ get_conf_map(params, default = UNDEFINED, multiple = True)
+
Similar to :func:`~stem.control.Controller.get_conf` but queries multiple
configuration options, providing back a mapping of those options to their
values.
@@ -2170,6 +2175,49 @@ class Controller(BaseController):
return return_dict
+ @with_default()
+ def get_custom_conf(self, default = UNDEFINED, include_values = False):
+ """
+ get_custom_conf(params, default = UNDEFINED, multiple = True)
+
+ Provides tor configuration options that differ from their defaults.
+
+ .. versionadded:: 1.5.0
+
+ :param object default: response if the query fails
+ :param bool include_values: provides full configuration lines that can be
+ saved, similar to 'GETINFO config-text'
+
+ :returns: **list** of configuration options that have been set, or config
+ lines if **include_values** is **True**
+
+ :raises: :class:`stem.ControllerError` if the call fails and we weren't
+ provided a default response
+ """
+
+ config_lines = self.get_info('config-text').splitlines()
+
+ # Tor provides some config options even if they haven't been set...
+ #
+ # https://trac.torproject.org/projects/tor/ticket/2362
+ # https://trac.torproject.org/projects/tor/ticket/17909
+
+ default_lines = (
+ 'Log notice stdout',
+ 'Log notice file /var/log/tor/log',
+ 'DataDirectory /home/%s/.tor' % self.get_user('undefined'),
+ 'HiddenServiceStatistics 0',
+ )
+
+ for line in default_lines:
+ if line in config_lines:
+ config_lines.remove(line)
+
+ if include_values:
+ return config_lines
+ else:
+ return list(set([line.split(' ')[0] for line in config_lines]))
+
def set_conf(self, param, value):
"""
Changes the value of a tor configuration option. Our value can be any of
diff --git a/test/integ/control/controller.py b/test/integ/control/controller.py
index 84bf58a..cf604c6 100644
--- a/test/integ/control/controller.py
+++ b/test/integ/control/controller.py
@@ -189,6 +189,8 @@ class TestController(unittest.TestCase):
self.assertTrue(isinstance(event, stem.response.events.ConfChangedEvent))
+ controller.reset_conf('NodeFamily')
+
@require_controller
def test_reattaching_listeners(self):
"""
@@ -468,6 +470,24 @@ class TestController(unittest.TestCase):
self.assertEqual({}, controller.get_conf_map([], 'la-di-dah'))
@require_controller
+ def test_get_custom_conf(self):
+ """
+ Exercises our get_custom_conf() method.
+ """
+
+ runner = test.runner.get_runner()
+
+ with runner.get_tor_controller() as controller:
+ custom_options = controller.get_custom_conf()
+ self.assertTrue('ControlPort' in custom_options or 'ControlSocket' in custom_options)
+ self.assertTrue('DownloadExtraInfo' in custom_options)
+ self.assertTrue('SocksListenAddress' in custom_options)
+
+ custom_options = controller.get_custom_conf(include_values = True)
+ self.assertTrue('DownloadExtraInfo 1' in custom_options)
+ self.assertTrue('SocksListenAddress 127.0.0.1:1112' in custom_options)
+
+ @require_controller
def test_hidden_services_conf(self):
"""
Exercises the hidden service family of methods (get_hidden_service_conf,
More information about the tor-commits
mailing list