From f25ce0216f5bb0649580d98a59e0b1af24f95725 Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Tue, 1 Sep 2015 21:42:33 -0400 Subject: [PATCH] tor: Add control to enable/disable apt-transport-tor (Closes: #78). --- actions/tor | 27 +++++++++++++++++++++++++++ plinth/modules/tor/tor.py | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/actions/tor b/actions/tor index e08781811..4178a5904 100755 --- a/actions/tor +++ b/actions/tor @@ -22,6 +22,7 @@ Configuration helper for the Tor service """ import argparse +import augeas import codecs import os import re @@ -29,6 +30,8 @@ import socket from plinth import action_utils +APT_SOURCES_URI_PATH = '/files/etc/apt/sources.list/*/uri' +APT_TOR_PREFIX = 'tor+' TOR_CONFIG = '/etc/tor/torrc' TOR_STATE_FILE = '/var/lib/tor/state' TOR_AUTH_COOKIE = '/var/run/tor/control.authcookie' @@ -46,6 +49,10 @@ def parse_arguments(): subparsers.add_parser('enable-hs', help='Enable hidden service') subparsers.add_parser('disable-hs', help='Disable hidden service') subparsers.add_parser('get-ports', help='Get list of Tor ports') + subparsers.add_parser('enable-apt-transport-tor', + help='Enable package download over Tor') + subparsers.add_parser('disable-apt-transport-tor', + help='Disable package download over Tor') return parser.parse_args() @@ -194,6 +201,26 @@ def subcommand_get_ports(_): print('{0} {1}'.format(matches.group(1), matches.group(2))) +def subcommand_enable_apt_transport_tor(_): + """Enable package download over Tor.""" + aug = augeas.Augeas() + for uri_path in aug.match(APT_SOURCES_URI_PATH): + uri = aug.get(uri_path) + if not uri.startswith(APT_TOR_PREFIX): + aug.set(uri_path, APT_TOR_PREFIX + uri) + aug.save() + + +def subcommand_disable_apt_transport_tor(_): + """Disable package download over Tor.""" + aug = augeas.Augeas() + for uri_path in aug.match(APT_SOURCES_URI_PATH): + uri = aug.get(uri_path) + if uri.startswith(APT_TOR_PREFIX): + aug.set(uri_path, uri[len(APT_TOR_PREFIX):]) + aug.save() + + def _get_orport(): """Return the ORPort by querying running instance.""" cookie = open(TOR_AUTH_COOKIE, 'rb').read() diff --git a/plinth/modules/tor/tor.py b/plinth/modules/tor/tor.py index 628f437dd..f92ab67e3 100644 --- a/plinth/modules/tor/tor.py +++ b/plinth/modules/tor/tor.py @@ -19,6 +19,7 @@ Plinth module for configuring Tor """ +import augeas from django import forms from django.contrib import messages from django.template.response import TemplateResponse @@ -29,6 +30,9 @@ from plinth import action_utils from plinth import cfg from plinth import package +APT_SOURCES_URI_PATH = '/files/etc/apt/sources.list/*/uri' +APT_TOR_PREFIX = 'tor+' + class TorForm(forms.Form): # pylint: disable=W0232 """Tor configuration form""" @@ -41,6 +45,12 @@ class TorForm(forms.Form): # pylint: disable=W0232 help_text=_('A hidden service will allow FreedomBox to provide ' 'selected services (such as ownCloud or Chat) without ' 'revealing its location.')) + apt_transport_tor_enabled = forms.BooleanField( + label=_('Download software packages over Tor'), + required=False, + help_text=_('When enabled, Debian packages will be downloaded over ' + 'the Tor network for software installs and upgrades. This ' + 'adds a degree of privacy to your software downloads.')) def init(): @@ -55,7 +65,8 @@ def on_install(): actions.superuser_run('tor', ['setup']) -@package.required(['tor', 'obfsproxy', 'torsocks'], on_install=on_install) +@package.required(['tor', 'obfsproxy', 'torsocks', 'apt-transport-tor'], + on_install=on_install) def index(request): """Service the index page""" status = get_status() @@ -106,18 +117,28 @@ def get_status(): hs_hostname = hs_info[0] hs_ports = hs_info[1] + apt_transport_tor_enabled = False + aug = augeas.Augeas() + for uri_path in aug.match(APT_SOURCES_URI_PATH): + if aug.get(uri_path).startswith(APT_TOR_PREFIX): + apt_transport_tor_enabled = True + break + return {'enabled': action_utils.service_is_enabled('tor'), 'is_running': action_utils.service_is_running('tor'), 'ports': ports, 'hs_enabled': hs_enabled, 'hs_hostname': hs_hostname, - 'hs_ports': hs_ports} + 'hs_ports': hs_ports, + 'apt_transport_tor_enabled': apt_transport_tor_enabled} def _apply_changes(request, old_status, new_status): """Apply the changes.""" if old_status['enabled'] == new_status['enabled'] and \ - old_status['hs_enabled'] == new_status['hs_enabled']: + old_status['hs_enabled'] == new_status['hs_enabled'] and \ + old_status['apt_transport_tor_enabled'] == \ + new_status['apt_transport_tor_enabled']: messages.info(request, _('Setting unchanged')) return @@ -136,3 +157,12 @@ def _apply_changes(request, old_status, new_status): else: messages.success(request, _('Tor hidden service disabled')) actions.superuser_run('tor', ['disable-hs']) + + if old_status['apt_transport_tor_enabled'] != \ + new_status['apt_transport_tor_enabled']: + if new_status['apt_transport_tor_enabled']: + messages.success(request, _('Enabled package download over Tor')) + actions.superuser_run('tor', ['enable-apt-transport-tor']) + else: + messages.success(request, _('Disabled package download over Tor')) + actions.superuser_run('tor', ['disable-apt-transport-tor'])