mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-28 08:03:36 +00:00
- Allow users to run regular relays. In addition to that users will be able to turn them into bridge relays. Like before, by default, relaying is enabled and the relay type bridge relay. - Show obfs3/4 transport ports as needing firewall port forwarding only if bridge relay is enabled. - Remove pluggable transports configuration from configuration when bridge rely is disabled. - Improve description message for relays and bridge relays.
151 lines
4.8 KiB
Python
151 lines
4.8 KiB
Python
#
|
|
# This file is part of Plinth.
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero General Public License as
|
|
# published by the Free Software Foundation, either version 3 of the
|
|
# License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
"""
|
|
Tor utility functions
|
|
"""
|
|
|
|
import augeas
|
|
import glob
|
|
import itertools
|
|
import json
|
|
|
|
from plinth import actions
|
|
from plinth import action_utils
|
|
from plinth.modules.names import SERVICES
|
|
|
|
|
|
APT_SOURCES_URI_PATHS = ('/files/etc/apt/sources.list/*/uri',
|
|
'/files/etc/apt/sources.list.d/*/*/uri')
|
|
APT_TOR_PREFIX = 'tor+'
|
|
|
|
|
|
def is_enabled():
|
|
"""Return whether the module is enabled."""
|
|
return action_utils.service_is_enabled('tor')
|
|
|
|
|
|
def is_running():
|
|
"""Return whether the service is running."""
|
|
return action_utils.service_is_running('tor')
|
|
|
|
|
|
def get_status():
|
|
"""Return current Tor status."""
|
|
output = actions.superuser_run('tor', ['get-status'])
|
|
status = json.loads(output)
|
|
|
|
hs_info = status['hidden_service']
|
|
hs_services = []
|
|
hs_virtports = [port['virtport'] for port in hs_info['ports']]
|
|
for service_type in SERVICES:
|
|
if str(service_type[2]) in hs_virtports:
|
|
hs_services.append(service_type[0])
|
|
|
|
# Filter out obfs3/4 ports when bridge relay is disabled
|
|
ports = {service_type: port
|
|
for service_type, port in status['ports'].items()
|
|
if service_type not in ['obfs4', 'obfs3'] or
|
|
status['bridge_relay_enabled']}
|
|
|
|
return {'enabled': is_enabled(),
|
|
'is_running': is_running(),
|
|
'relay_enabled': status['relay_enabled'],
|
|
'bridge_relay_enabled': status['bridge_relay_enabled'],
|
|
'ports': ports,
|
|
'hs_enabled': hs_info['enabled'],
|
|
'hs_status': hs_info['status'],
|
|
'hs_hostname': hs_info['hostname'],
|
|
'hs_ports': hs_info['ports'],
|
|
'hs_services': hs_services,
|
|
'apt_transport_tor_enabled':
|
|
_is_apt_transport_tor_enabled()
|
|
}
|
|
|
|
|
|
def iter_apt_uris(aug):
|
|
"""Iterate over all the APT source URIs."""
|
|
return itertools.chain.from_iterable([aug.match(path)
|
|
for path in APT_SOURCES_URI_PATHS])
|
|
|
|
|
|
def get_real_apt_uri_path(aug, path):
|
|
"""Return the actual path which contains APT URL.
|
|
|
|
XXX: This is a workaround for Augeas bug parsing Apt source files
|
|
with '[options]'. Remove this workaround after Augeas lens is
|
|
fixed.
|
|
"""
|
|
uri = aug.get(path)
|
|
if uri[0] == '[':
|
|
parent_path = path.rsplit('/', maxsplit=1)[0]
|
|
skipped = False
|
|
for child_path in aug.match(parent_path + '/*')[1:]:
|
|
if skipped:
|
|
return child_path
|
|
|
|
value = aug.get(child_path)
|
|
if value[-1] == ']':
|
|
skipped = True
|
|
|
|
return path
|
|
|
|
|
|
def get_augeas():
|
|
"""Return an instance of Augeaus for processing APT configuration."""
|
|
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
|
|
augeas.Augeas.NO_MODL_AUTOLOAD)
|
|
aug.set('/augeas/load/Aptsources/lens', 'Aptsources.lns')
|
|
aug.set('/augeas/load/Aptsources/incl[last() + 1]',
|
|
'/etc/apt/sources.list')
|
|
aug.set('/augeas/load/Aptsources/incl[last() + 1]',
|
|
'/etc/apt/sources.list.d/*.list')
|
|
aug.load()
|
|
|
|
# Currently, augeas does not handle Deb822 format, it error out.
|
|
if aug.match('/augeas/files/etc/apt/sources.list/error') or \
|
|
aug.match('/augeas/files/etc/apt/sources.list.d//error'):
|
|
raise Exception('Error parsing sources list')
|
|
|
|
# Starting with Apt 1.1, /etc/apt/sources.list.d/*.sources will
|
|
# contain files with Deb822 format. If they are found, error out
|
|
# for now. XXX: Provide proper support Deb822 format with a new
|
|
# Augeas lens.
|
|
if glob.glob('/etc/apt/sources.list.d/*.sources'):
|
|
raise Exception('Can not handle Deb822 source files')
|
|
|
|
return aug
|
|
|
|
|
|
def _is_apt_transport_tor_enabled():
|
|
"""Return whether APT is set to download packages over Tor."""
|
|
try:
|
|
aug = get_augeas()
|
|
except Exception:
|
|
# If there was an error with parsing or there are Deb822
|
|
# files.
|
|
return False
|
|
|
|
for uri_path in iter_apt_uris(aug):
|
|
uri_path = get_real_apt_uri_path(aug, uri_path)
|
|
uri = aug.get(uri_path)
|
|
if not uri.startswith(APT_TOR_PREFIX) and \
|
|
(uri.startswith('http://') or uri.startswith('https://')):
|
|
return False
|
|
|
|
return True
|