From a3845e2b284c7c4962437af3d21b7fbeb5e6c439 Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Tue, 15 Dec 2015 21:12:02 -0500 Subject: [PATCH] tor: Add service for bridge relay ports --- actions/tor | 75 +++++++++++++++++++++++++++------- plinth/modules/tor/__init__.py | 13 ++++-- plinth/modules/tor/views.py | 6 ++- 3 files changed, 74 insertions(+), 20 deletions(-) diff --git a/actions/tor b/actions/tor index 0dcd0c423..450eb7ec3 100755 --- a/actions/tor +++ b/actions/tor @@ -26,11 +26,13 @@ import codecs import os import re import socket +import time from plinth import action_utils from plinth.modules.tor.tor import get_augeas, get_real_apt_uri_path, \ iter_apt_uris, APT_TOR_PREFIX +SERVICE_FILE = '/etc/firewalld/services/tor-{0}.xml' TOR_CONFIG = '/etc/tor/torrc' TOR_STATE_FILE = '/var/lib/tor/state' TOR_AUTH_COOKIE = '/var/run/tor/control.authcookie' @@ -89,11 +91,13 @@ DNSPort [::1]:9053 conffile.writelines(lines) action_utils.service_restart('tor') + _update_ports() def subcommand_enable(_): """Enable and start the service.""" action_utils.service_enable('tor') + _update_ports() def subcommand_disable(_): @@ -190,21 +194,10 @@ def get_hidden_service(): def subcommand_get_ports(_): - """Return a list of running Tor ports.""" - try: - print('orport', _get_orport()) - except Exception: - pass - - try: - with open(TOR_STATE_FILE, 'r') as state_file: - for line in state_file: - matches = re.match( - r'^\s*TransportProxy\s+(\S*)\s+\S+:(\d+)\s*$', line) - if matches: - print('{0} {1}'.format(matches.group(1), matches.group(2))) - except FileNotFoundError: - pass + """Get list of Tor ports.""" + ports = get_ports() + for name, number in ports.items(): + print(name, number) def subcommand_enable_apt_transport_tor(_): @@ -242,6 +235,27 @@ def subcommand_disable_apt_transport_tor(_): aug.save() +def get_ports(): + """Return dict mapping port names to numbers.""" + ports = {} + try: + ports['orport'] = _get_orport() + except Exception: + pass + + try: + with open(TOR_STATE_FILE, 'r') as state_file: + for line in state_file: + matches = re.match( + r'^\s*TransportProxy\s+(\S*)\s+\S+:(\d+)\s*$', line) + if matches: + ports[matches.group(1)] = matches.group(2) + except FileNotFoundError: + pass + + return ports + + def _get_orport(): """Return the ORPort by querying running instance.""" cookie = open(TOR_AUTH_COOKIE, 'rb').read() @@ -263,6 +277,37 @@ QUIT return matches.group(1) +def _update_ports(): + """Update firewall service information.""" + ready = False + tries = 0 + + # port information may not be available immediately after Tor started + while not ready: + time.sleep(5) + + ports = get_ports() + ready = 'orport' in ports and 'obfs3' in ports and 'obfs4' in ports + if ready: + break + + tries += 1 + if tries >= 12: + return + + lines = """ + + Tor - {0} + + +""" + for name, number in ports.items(): + with open(SERVICE_FILE.format(name), 'w') as service_file: + service_file.writelines(lines.format(name, number)) + + action_utils.service_restart('firewalld') + + def main(): """Parse arguments and perform all duties""" arguments = parse_arguments() diff --git a/plinth/modules/tor/__init__.py b/plinth/modules/tor/__init__.py index 42d47a6ac..bd7ef694e 100644 --- a/plinth/modules/tor/__init__.py +++ b/plinth/modules/tor/__init__.py @@ -34,7 +34,8 @@ from plinth.signals import domain_added depends = ['plinth.modules.apps', 'plinth.modules.names'] -service = None +socks_service = None +bridge_service = None APT_SOURCES_URI_PATHS = ('/files/etc/apt/sources.list/*/uri', '/files/etc/apt/sources.list.d/*/*/uri') @@ -47,11 +48,17 @@ def init(): menu.add_urlname(_('Anonymity Network (Tor)'), 'glyphicon-eye-close', 'tor:index', 100) - global service - service = service_module.Service( + global socks_service + socks_service = service_module.Service( 'tor-socks', _('Tor Anonymity Network'), is_external=False, enabled=is_enabled()) + global bridge_service + bridge_service = service_module.Service( + 'tor-bridge', _('Tor Bridge Relay'), + ports=['tor-orport', 'tor-obfs3', 'tor-obfs4'], + is_external=True, enabled=is_enabled()) + # Register hidden service name with Name Services module. (hs_enabled, hs_hostname, hs_ports) = get_hs() diff --git a/plinth/modules/tor/views.py b/plinth/modules/tor/views.py index 394c82314..2bd055eb0 100644 --- a/plinth/modules/tor/views.py +++ b/plinth/modules/tor/views.py @@ -36,7 +36,8 @@ def on_install(): """Setup Tor configuration as soon as it is installed.""" actions.superuser_run('tor', ['setup']) actions.superuser_run('tor', ['enable-apt-transport-tor']) - tor.service.notify_enabled(None, True) + tor.socks_service.notify_enabled(None, True) + tor.bridge_service.notify_enabled(None, True) @package.required(['tor', 'tor-geoipdb', 'torsocks', 'obfs4proxy', @@ -80,7 +81,8 @@ def __apply_changes(request, old_status, new_status): if old_status['enabled'] != new_status['enabled']: sub_command = 'enable' if new_status['enabled'] else 'disable' actions.superuser_run('tor', [sub_command]) - tor.service.notify_enabled(None, new_status['enabled']) + tor.socks_service.notify_enabled(None, new_status['enabled']) + tor.bridge_service.notify_enabled(None, new_status['enabled']) modified = True if old_status['hs_enabled'] != new_status['hs_enabled']: