[tor-commits] [arm/master] Using Stem's connect() method
atagar at torproject.org
atagar at torproject.org
Thu Apr 10 16:13:28 UTC 2014
commit 3aa83a9de0056425c47d3f3695ec6a299218c4f0
Author: Damian Johnson <atagar at torproject.org>
Date: Thu Apr 10 09:13:47 2014 -0700
Using Stem's connect() method
Replacing our connection and authentication code in favor of stem's shiny new
method for this.
---
arm/__init__.py | 2 +-
arm/arguments.py | 2 +-
arm/config/strings.cfg | 38 ---------------------
arm/starter.py | 21 ++++++++----
arm/util/__init__.py | 77 +++---------------------------------------
test/util/authenticate.py | 73 ---------------------------------------
test/util/init_controller.py | 67 ------------------------------------
7 files changed, 21 insertions(+), 259 deletions(-)
diff --git a/arm/__init__.py b/arm/__init__.py
index c203b5f..25e322f 100644
--- a/arm/__init__.py
+++ b/arm/__init__.py
@@ -2,7 +2,7 @@
Scripts involved in validating user input, system state, and initializing arm.
"""
-__all__ = ["starter", "prereq", "version", "config_panel", "controller", "header_panel", "log_panel", "popups", "torrc_panel"]
+__all__ = ["starter", "arguments", "prereq", "version", "config_panel", "controller", "header_panel", "log_panel", "popups", "torrc_panel"]
__version__ = '1.4.6_dev'
__release_date__ = 'April 28, 2011'
diff --git a/arm/arguments.py b/arm/arguments.py
index 3d4a656..b527564 100644
--- a/arm/arguments.py
+++ b/arm/arguments.py
@@ -25,7 +25,7 @@ DEFAULT_ARGS = {
'print_help': False,
}
-OPT = 'i:s:c:d:bl:vh'
+OPT = 'i:s:c:d:l:vh'
OPT_EXPANDED = [
'interface=',
diff --git a/arm/config/strings.cfg b/arm/config/strings.cfg
index 17a9cd7..3ac3b3c 100644
--- a/arm/config/strings.cfg
+++ b/arm/config/strings.cfg
@@ -3,7 +3,6 @@
# User facing strings. These are sorted into the following namespaces...
#
# * config parsing or handling configuration options
-# * connect connection and authentication to tor
# * debug concerns the --debug argument
# * misc anything that doesn't fit into a present namespace
# * setup notificaitons or issues arising while starting arm
@@ -18,15 +17,6 @@ msg.config.unable_to_load_settings Unable to load arm's internal configurations:
msg.config.unable_to_read_file Failed to load configuration (using defaults): "{error}"
msg.config.nothing_loaded No armrc loaded, using defaults. You can customize arm by placing a configuration file at {path} (see the armrc.sample for its options).
-msg.connect.general_auth_failure Unable to authenticate: {error}
-msg.connect.incorrect_password Incorrect password
-msg.connect.no_control_port Unable to connect to tor. Maybe it's running without a ControlPort?
-msg.connect.password_prompt Tor controller password:
-msg.connect.socket_doesnt_exist The socket file you specified ({path}) doesn't exist
-msg.connect.tor_isnt_running Unable to connect to tor. Are you sure it's running?
-msg.connect.unable_to_use_port Unable to connect to {address}:{port}: {error}
-msg.connect.unable_to_use_socket Unable to connect to '{path}': {error}
-
msg.debug.saving_to_path Saving a debug log to {path}, please check it for sensitive information before sharing it.
msg.debug.unable_to_write_file Unable to write to our debug log file ({path}): {error}
@@ -53,26 +43,6 @@ msg.usage.not_a_valid_port '{port_input}' isn't a valid port number
msg.usage.unrecognized_log_flags Unrecognized event flags: {flags}
msg.usage.unable_to_set_color_override "{color}" isn't a valid color
-msg.connect.missing_password_bug
-|BUG: You provided a password but despite this stem reported that it was
-|missing. This shouldn't happen - please let us know about it!
-|
-| http://bugs.torproject.org
-
-msg.connect.unreadable_cookie_file
-|We were unable to read tor's authentication cookie...
-|
-| Path: {path}
-| Issue: {issue}
-
-msg.connect.wrong_port_type
-|Please check in your torrc that {port} is the ControlPort. Maybe you
-|configured it to be the ORPort or SocksPort instead?
-
-msg.connect.wrong_socket_type
-|Unable to connect to tor. Are you sure the interface you specified belongs to
-|tor?
-
msg.debug.header
|Arm {arm_version} Debug Dump
|Stem Version: {stem_version}
@@ -99,14 +69,6 @@ msg.setup.unknown_term
|Either update your terminfo database or run arm using "TERM=xterm arm".
|
-msg.uncrcognized_auth_type
-|Tor is using a type of authentication we do not recognize...
-|
-| {auth_methods}
-|
-|Please check that arm is up to date and if there is an existing issue on
-|'http://bugs.torproject.org'. If there isn't one then let us know!
-
msg.usage.help_output
|Usage arm [OPTION]
|Terminal status monitor for Tor relays.
diff --git a/arm/starter.py b/arm/starter.py
index 9493415..ba7c9af 100644
--- a/arm/starter.py
+++ b/arm/starter.py
@@ -22,11 +22,12 @@ import arm.util.tracker
import arm.util.ui_tools
import stem
+import stem.connection
import stem.util.conf
import stem.util.log
import stem.util.system
-from arm.util import BASE_DIR, init_controller, authenticate, msg, trace, info, notice, warn, load_settings
+from arm.util import BASE_DIR, init_controller, msg, trace, info, notice, warn, load_settings
CONFIG = stem.util.conf.get_config('arm')
@@ -64,13 +65,21 @@ def main():
_load_user_armrc(args.config)
- try:
- controller = init_controller(args)
- authenticate(controller, CONFIG.get('tor.password', None), CONFIG.get('tor.chroot', ''))
- except ValueError as exc:
- print exc
+ control_port = None if args.user_provided_socket else (args.control_address, args.control_port)
+ control_socket = None if args.user_provided_port else args.control_socket
+
+ controller = stem.connection.connect(
+ control_port = control_port,
+ control_socket = control_socket,
+ password = CONFIG.get('tor.password', None),
+ password_prompt = True,
+ chroot_path = CONFIG.get('tor.chroot', ''),
+ )
+
+ if controller is None:
exit(1)
+ init_controller(controller)
_warn_if_root(controller)
_warn_if_unable_to_get_pid(controller)
_setup_freebsd_chroot(controller)
diff --git a/arm/util/__init__.py b/arm/util/__init__.py
index d94173b..d606a43 100644
--- a/arm/util/__init__.py
+++ b/arm/util/__init__.py
@@ -6,7 +6,6 @@ and safely working with curses (hiding some of the gory details).
__all__ = ["connections", "panel", "sysTools", "text_input", "tor_config", "tor_tools", "tracker", "ui_tools"]
-import getpass
import os
import stem
@@ -29,57 +28,15 @@ def tor_controller():
return TOR_CONTROLLER
-def init_controller(args):
+def init_controller(controller):
"""
- Provides a Controller for the endpoint specified in the given arguments.
+ Sets the Controller used by arm.
- :param namedtuple args: arguments that arm was started with
-
- :returns: :class:`~stem.control.Controller` for the given arguments
-
- :raises: **ValueError** if unable to acquire a controller connection
+ :param Controller controller: control connection to be used by arm
"""
global TOR_CONTROLLER
- TOR_CONTROLLER = _get_controller(args)
- return TOR_CONTROLLER
-
-
-def authenticate(controller, password, chroot_path = ''):
- """
- Authenticates to the given Controller.
-
- :param stem.control.Controller controller: controller to be authenticated
- :param str password: password to authenticate with, **None** if nothing was
- provided
- :param str chroot_path: chroot tor resides within
-
- :raises: **ValueError** if unable to authenticate
- """
-
- try:
- controller.authenticate(password = password, chroot_path = chroot_path)
- except stem.connection.IncorrectSocketType:
- control_socket = controller.get_socket()
-
- if isinstance(control_socket, stem.socket.ControlPort):
- raise ValueError(msg('connect.wrong_port_type', port = control_socket.get_port()))
- else:
- raise ValueError(msg('connect.wrong_socket_type'))
- except stem.connection.UnrecognizedAuthMethods as exc:
- raise ValueError(msg('uncrcognized_auth_type', auth_methods = ', '.join(exc.unknown_auth_methods)))
- except stem.connection.IncorrectPassword:
- raise ValueError(msg('connect.incorrect_password'))
- except stem.connection.MissingPassword:
- if password:
- raise ValueError(msg('connect.missing_password_bug'))
-
- password = getpass.getpass(msg('connect.password_prompt') + ' ')
- return authenticate(controller, password)
- except stem.connection.UnreadableCookieFile as exc:
- raise ValueError(msg('connect.unreadable_cookie_file', path = exc.cookie_path, issue = str(exc)))
- except stem.connection.AuthenticationFailure as exc:
- raise ValueError(msg('connect.general_auth_failure', error = exc))
+ TOR_CONTROLLER = controller
def msg(message, **attr):
@@ -155,29 +112,3 @@ def _log(runlevel, message, **attr):
"""
stem.util.log.log(runlevel, msg(message, **attr))
-
-
-def _get_controller(args):
- """
- Provides a Controller for the endpoint specified in the given arguments.
- """
-
- if os.path.exists(args.control_socket):
- try:
- return stem.control.Controller.from_socket_file(args.control_socket)
- except stem.SocketError as exc:
- if args.user_provided_socket:
- raise ValueError(msg('connect.unable_to_use_socket', path = args.control_socket, error = exc))
- elif args.user_provided_socket:
- raise ValueError(msg('connect.socket_doesnt_exist', path = args.control_socket))
-
- try:
- return stem.control.Controller.from_port(args.control_address, args.control_port)
- except stem.SocketError as exc:
- if args.user_provided_port:
- raise ValueError(msg('connect.unable_to_use_port', address = args.control_address, port = args.control_port, error = exc))
-
- if not stem.util.system.is_running('tor'):
- raise ValueError(msg('connect.tor_isnt_running'))
- else:
- raise ValueError(msg('connect.no_control_port'))
diff --git a/test/util/authenticate.py b/test/util/authenticate.py
deleted file mode 100644
index 9dae10b..0000000
--- a/test/util/authenticate.py
+++ /dev/null
@@ -1,73 +0,0 @@
-import unittest
-
-from mock import Mock, patch
-
-from arm.util import (
- init_controller,
- authenticate,
-)
-
-import stem
-import stem.connection
-import stem.socket
-
-
-class TestAuthenticate(unittest.TestCase):
- def test_success(self):
- controller = Mock()
-
- authenticate(controller, None)
- controller.authenticate.assert_called_with(password = None, chroot_path = '')
- controller.authenticate.reset_mock()
-
- authenticate(controller, 's3krit!!!', '/my/chroot')
- controller.authenticate.assert_called_with(password = 's3krit!!!', chroot_path = '/my/chroot')
-
- @patch('getpass.getpass')
- def test_success_with_password_prompt(self, getpass_mock):
- controller = Mock()
-
- def authenticate_mock(password, **kwargs):
- if password is None:
- raise stem.connection.MissingPassword('no password')
- elif password == 'my_password':
- return None # success
- else:
- raise ValueError("Unexpected authenticate_mock input: %s" % password)
-
- controller.authenticate.side_effect = authenticate_mock
- getpass_mock.return_value = 'my_password'
-
- authenticate(controller, None)
- controller.authenticate.assert_any_call(password = None, chroot_path = '')
- controller.authenticate.assert_any_call(password = 'my_password', chroot_path = '')
-
- def test_failure(self):
- controller = Mock()
-
- controller.authenticate.side_effect = stem.connection.IncorrectSocketType('unable to connect to socket')
- controller.get_socket.return_value = stem.socket.ControlPort(connect = False)
- self._assert_authenticate_fails_with(controller, 'Please check in your torrc that 9051 is the ControlPort.')
-
- controller.get_socket.return_value = stem.socket.ControlSocketFile(connect = False)
- self._assert_authenticate_fails_with(controller, 'Are you sure the interface you specified belongs to')
-
- controller.authenticate.side_effect = stem.connection.UnrecognizedAuthMethods('unable to connect', ['telepathy'])
- self._assert_authenticate_fails_with(controller, 'Tor is using a type of authentication we do not recognize...\n\n telepathy')
-
- controller.authenticate.side_effect = stem.connection.IncorrectPassword('password rejected')
- self._assert_authenticate_fails_with(controller, 'Incorrect password')
-
- controller.authenticate.side_effect = stem.connection.UnreadableCookieFile('permission denied', '/tmp/my_cookie', False)
- self._assert_authenticate_fails_with(controller, "We were unable to read tor's authentication cookie...\n\n Path: /tmp/my_cookie\n Issue: permission denied")
-
- controller.authenticate.side_effect = stem.connection.OpenAuthRejected('crazy failure')
- self._assert_authenticate_fails_with(controller, 'Unable to authenticate: crazy failure')
-
- def _assert_authenticate_fails_with(self, controller, msg):
- try:
- init_controller(authenticate(controller, None))
- self.fail()
- except ValueError as exc:
- if not msg in str(exc):
- self.fail("Expected...\n\n%s\n\n... which couldn't be found in...\n\n%s" % (msg, exc))
diff --git a/test/util/init_controller.py b/test/util/init_controller.py
deleted file mode 100644
index cbbeffa..0000000
--- a/test/util/init_controller.py
+++ /dev/null
@@ -1,67 +0,0 @@
-import unittest
-
-from mock import Mock, patch
-
-from arm.arguments import parse
-from arm.util import init_controller
-
-import stem
-import stem.connection
-import stem.socket
-
-
-class TestGetController(unittest.TestCase):
- @patch('os.path.exists', Mock(return_value = True))
- @patch('stem.util.system.is_running')
- @patch('stem.control.Controller.from_socket_file', Mock(side_effect = stem.SocketError('failed')))
- @patch('stem.control.Controller.from_port', Mock(side_effect = stem.SocketError('failed')))
- def test_failue_with_the_default_endpoint(self, is_running_mock):
- is_running_mock.return_value = False
- self._assert_init_controller_fails_with([], "Unable to connect to tor. Are you sure it's running?")
-
- is_running_mock.return_value = True
- self._assert_init_controller_fails_with([], "Unable to connect to tor. Maybe it's running without a ControlPort?")
-
- @patch('os.path.exists')
- @patch('stem.util.system.is_running', Mock(return_value = True))
- @patch('stem.control.Controller.from_socket_file', Mock(side_effect = stem.SocketError('failed')))
- @patch('stem.control.Controller.from_port', Mock(side_effect = stem.SocketError('failed')))
- def test_failure_with_a_custom_endpoint(self, path_exists_mock):
- path_exists_mock.return_value = True
- self._assert_init_controller_fails_with(['--interface', '80'], "Unable to connect to 127.0.0.1:80: failed")
- self._assert_init_controller_fails_with(['--socket', '/tmp/my_socket'], "Unable to connect to '/tmp/my_socket': failed")
-
- path_exists_mock.return_value = False
- self._assert_init_controller_fails_with(['--interface', '80'], "Unable to connect to 127.0.0.1:80: failed")
- self._assert_init_controller_fails_with(['--socket', '/tmp/my_socket'], "The socket file you specified (/tmp/my_socket) doesn't exist")
-
- @patch('os.path.exists', Mock(return_value = False))
- @patch('stem.control.Controller.from_port')
- def test_getting_a_control_port(self, from_port_mock):
- from_port_mock.return_value = 'success'
-
- self.assertEqual('success', init_controller(parse([])))
- from_port_mock.assert_called_once_with('127.0.0.1', 9051)
- from_port_mock.reset_mock()
-
- self.assertEqual('success', init_controller(parse(['--interface', '255.0.0.10:80'])))
- from_port_mock.assert_called_once_with('255.0.0.10', 80)
-
- @patch('os.path.exists', Mock(return_value = True))
- @patch('stem.control.Controller.from_socket_file')
- def test_getting_a_control_socket(self, from_socket_file_mock):
- from_socket_file_mock.return_value = 'success'
-
- self.assertEqual('success', init_controller(parse([])))
- from_socket_file_mock.assert_called_once_with('/var/run/tor/control')
- from_socket_file_mock.reset_mock()
-
- self.assertEqual('success', init_controller(parse(['--socket', '/tmp/my_socket'])))
- from_socket_file_mock.assert_called_once_with('/tmp/my_socket')
-
- def _assert_init_controller_fails_with(self, args, msg):
- try:
- init_controller(parse(args))
- self.fail()
- except ValueError as exc:
- self.assertEqual(msg, str(exc))
More information about the tor-commits
mailing list