tor: Add option to use upstream bridges

This commit is contained in:
James Valleroy 2016-09-11 17:20:01 -04:00 committed by Sunil Mohan Adapa
parent 413256569d
commit 09b58a8b99
No known key found for this signature in database
GPG Key ID: 36C361440C9BC971
5 changed files with 124 additions and 2 deletions

View File

@ -63,6 +63,16 @@ def parse_arguments():
configure.add_argument('--apt-transport-tor',
choices=['enable', 'disable'],
help='Configure package download over Tor')
configure.add_argument('--use-upstream-bridges',
choices=['enable', 'disable'],
help='Configure use of upstream bridges')
upstream = subparsers.add_parser(
'set-upstream-bridges', help='Set list of upstream bridges')
upstream.add_argument('--bridges',
help='List of upstream bridges to use')
subparsers.add_parser('restart', help='Restart Tor')
return parser.parse_args()
@ -137,6 +147,11 @@ def subcommand_configure(arguments):
if arguments.service == 'disable':
_disable()
restart = arguments.service is None and \
arguments.hidden_service is None and \
arguments.relay is None and arguments.bridge_relay is None
_use_upstream_bridges(arguments.use_upstream_bridges, restart=restart)
restart = arguments.service is None and arguments.hidden_service is None
_enable_relay(arguments.relay, arguments.bridge_relay, restart=restart)
@ -155,15 +170,50 @@ def subcommand_configure(arguments):
_disable_apt_transport_tor()
def subcommand_set_upstream_bridges(arguments):
"""Set list of upstream bridges."""
aug = augeas_load()
aug.remove(TOR_CONFIG + '/Bridge')
if arguments.bridges:
bridges = arguments.bridges.split('\n')
for bridge in bridges:
if bridge.strip():
aug.set(TOR_CONFIG + '/Bridge[last() + 1]', bridge.strip())
aug.save()
def subcommand_restart(_):
"""Restart Tor."""
if is_enabled() and is_running():
action_utils.service_restart('tor')
def get_status():
"""Return dict with Tor status."""
aug = augeas_load()
return {'relay_enabled': _is_relay_enabled(aug),
return {'use_upstream_bridges': _are_upstream_bridges_enabled(aug),
'upstream_bridges': _get_upstream_bridges(aug),
'relay_enabled': _is_relay_enabled(aug),
'bridge_relay_enabled': _is_bridge_relay_enabled(aug),
'ports': _get_ports(),
'hidden_service': _get_hidden_service(aug)}
def _are_upstream_bridges_enabled(aug):
"""Return whether upstream bridges are being used."""
use_bridges = aug.get(TOR_CONFIG + '/UseBridges')
return use_bridges == '1'
def _get_upstream_bridges(aug):
"""Return upstream bridges separated by newlines."""
matches = aug.match(TOR_CONFIG + '/Bridge')
bridges = [aug.get(match) for match in matches]
return '\n'.join(bridges)
def _is_relay_enabled(aug):
"""Return whether a relay is enabled."""
orport = aug.get(TOR_CONFIG + '/ORPort')
@ -262,6 +312,26 @@ def _disable():
action_utils.service_disable('tor@plinth')
def _use_upstream_bridges(use_upstream_bridges=None, restart=True, aug=None):
"""Enable use of upstream bridges."""
if use_upstream_bridges is None:
return
if not aug:
aug = augeas_load()
if use_upstream_bridges == 'enable':
aug.set(TOR_CONFIG + '/UseBridges', '1')
elif use_upstream_bridges == 'disable':
aug.set(TOR_CONFIG + '/UseBridges', '0')
aug.save()
if restart:
if is_enabled() and is_running():
action_utils.service_restart('tor')
def _enable_relay(relay=None, bridge=None, restart=True, aug=None):
"""Enable Tor bridge relay."""
if relay is None and bridge is None:

View File

@ -20,6 +20,7 @@ Forms for configuring Tor.
"""
from django import forms
from django.forms import widgets
from django.utils.translation import ugettext_lazy as _
from plinth import cfg
@ -62,3 +63,18 @@ class TorForm(forms.Form): # pylint: disable=W0232
'network for installations and upgrades. This adds a '
'degree of privacy and security during software '
'downloads.'))
use_upstream_bridges = forms.BooleanField(
label=_('Use upstream bridges to connect to Tor network'),
required=False,
help_text=_('When enabled, the bridges configured below will be used '
'to connect to the Tor network. This will disable relay '
'modes. Use this option only if you cannot connect to '
'the Tor network directly.'))
upstream_bridges = forms.CharField(
widget=widgets.Textarea,
label=_('Upstream bridges'),
required=False,
help_text=_('If you need to use a bridge to connect to Tor network, '
'you can get some bridges from '
'https://bridges.torproject.org/ and paste the bridge '
'information here.'))

View File

@ -151,6 +151,20 @@
$('#id_tor-bridge_relay_enabled').prop('checked', false);
}
}).change();
$('#id_tor-use_upstream_bridges').change(function() {
if ($('#id_tor-use_upstream_bridges').prop('checked')) {
$('#id_tor-upstream_bridges').show('slow');
$('label[for="id_tor-upstream_bridges"]').show('slow');
$('label[for="id_tor-upstream_bridges"]').parent().show('slow');
$('#id_tor-relay_enabled').prop('checked', false);
$('#id_tor-bridge_relay_enabled').prop('checked', false);
} else {
$('#id_tor-upstream_bridges').hide('slow');
$('label[for="id_tor-upstream_bridges"]').hide('slow');
$('label[for="id_tor-upstream_bridges"]').parent().hide('slow');
}
}).change();
})(jQuery);
// @license-end
</script>

View File

@ -64,6 +64,8 @@ def get_status():
return {'enabled': is_enabled(),
'is_running': is_running(),
'use_upstream_bridges': status['use_upstream_bridges'],
'upstream_bridges': status['upstream_bridges'],
'relay_enabled': status['relay_enabled'],
'bridge_relay_enabled': status['bridge_relay_enabled'],
'ports': ports,

View File

@ -74,6 +74,15 @@ def __apply_changes(request, old_status, new_status):
# Already running a configuration task
return
needs_restart = False
if old_status['upstream_bridges'] != new_status['upstream_bridges']:
if new_status['enabled'] and new_status['use_upstream_bridges']:
actions.superuser_run(
'tor', ['set-upstream-bridges', '--bridges',
new_status['upstream_bridges']])
needs_restart = True
arguments = []
if old_status['enabled'] != new_status['enabled']:
@ -102,11 +111,22 @@ def __apply_changes(request, old_status, new_status):
arg_value = 'enable'
arguments.extend(['--apt-transport-tor', arg_value])
if old_status['use_upstream_bridges'] != \
new_status['use_upstream_bridges']:
arg_value = 'disable'
if new_status['enabled'] and new_status['use_upstream_bridges']:
arg_value = 'enable'
arguments.extend(['--use-upstream-bridges', arg_value])
if arguments:
config_process = actions.superuser_run(
'tor', ['configure'] + arguments, async=True)
else:
messages.info(request, _('Setting unchanged'))
if needs_restart:
config_process = actions.superuser_run(
'tor', ['restart'], async=True)
else:
messages.info(request, _('Setting unchanged'))
def _collect_config_result(request):