Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reborn #3

Merged
merged 3 commits into from Oct 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions etc/apparmor.d/usr.lib.onion-grater
Expand Up @@ -31,8 +31,16 @@
/etc/nsswitch.conf r,
/etc/gai.conf r,

## Configuration directories
/etc/onion-grater.d/ r,
/etc/onion-grater.d/* r,
/usr/local/etc/onion-grater.d/ r,
/usr/local/etc/onion-grater.d/* r,
## Merger directories for compatibility
/etc/onion-grater-merger.d/ r,
/etc/onion-grater-merger.d/* r,
/usr/local/etc/onion-grater-merger.d/ r,
/usr/local/etc/onion-grater-merger.d/* r,

/run/tor/control.authcookie r,
/run/tor/control rw,
Expand Down
2 changes: 1 addition & 1 deletion lib/systemd/system/onion-grater.service
Expand Up @@ -17,7 +17,7 @@ ConditionPathExists=!/run/qubes/this-is-templatevm

[Service]
## 'ExecStart' gets overwritten in Whonix by file:
## /lib/systemd/system/onion-grater.service.d/30_cpfpy.conf
## /lib/systemd/system/onion-grater.service.d/30_whonix.conf
ExecStart=/usr/lib/onion-grater

User=onion-grater
Expand Down
31 changes: 31 additions & 0 deletions lib/systemd/system/onion-grater.service.d/30_whonix.conf
@@ -0,0 +1,31 @@
## Copyright (C) 2012 - 2022 ENCRYPTED SUPPORT LP <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

#### meta start
#### project Whonix
#### category networking and tor-control
#### gateway_only yes
#### description
## onion-grater systemd unit file extension
## Necessary changes for remote clients
#### meta end

[Service]
## Start onion-grater with listening on interface eth1 explicitly.
## Allow multiple qualifiers to match on different profiles
Environment="MAIN=--listen-interface eth1 --multiple-matches"
## Set profiles directories
Environment="DIRS=--profile-dir /etc/onion-grater-merger.d --profile-dir /usr/local/etc/onion-grater-merger.d"
## Enable debug mode.
#Environment="DEV=--debug"
## Enable complain mode, debug and allows everything (insecure in production).
#Environment="DEV=--complain"
## Override the above variables via custom file, prefix with '-' to avoid
## problems with missing file
EnvironmentFile=-/etc/onion-grater-systemd.conf
EnvironmentFile=-/usr/local/etc/onion-grater-systemd.conf

## Clear previous start line
ExecStart=
## Use variables assigned to arguments
ExecStart=/usr/lib/onion-grater $MAIN $DIRS $DEV
41 changes: 35 additions & 6 deletions usr/lib/onion-grater
Expand Up @@ -141,6 +141,7 @@ import textwrap
import time
import yaml

DEFAULT_PROFILE_DIR = ['/etc/onion-grater.d/']
DEFAULT_LISTEN_ADDRESS = 'localhost'
DEFAULT_LISTEN_PORT = 9051
DEFAULT_COOKIE_PATH = '/run/tor/control.authcookie'
Expand Down Expand Up @@ -549,11 +550,15 @@ class FilteredControlPortProxyHandler(socketserver.StreamRequestHandler):
self.restrict_stream_events = False
self.server_address = self.server.server_address
self.subscribed_event_listeners = []
for filter_file in glob.glob('/etc/onion-grater.d/*.yml'):
profile_dir = []
for directory in global_args.profile_dir:
profile_dir += glob.glob(directory + '*.yml')
profile_dir.sort(reverse = True)
for filter_file in profile_dir:
try:
with open(filter_file, "rb") as fh:
filters = yaml.safe_load(fh.read())
name = re.sub(r'\.yml$', '', os.path.basename(filter_file))
name = re.sub(r'\.yml$', '', os.path.abspath(filter_file))
for filter_ in filters:
if name not in filter_:
filter_['name'] = name
Expand Down Expand Up @@ -619,11 +624,13 @@ class FilteredControlPortProxyHandler(socketserver.StreamRequestHandler):
if all(any(val == expected_val or val == '*'
for val in filter_.get(key, []))
for key, expected_val in matchers)]

if len(matched_filters) == 0:
return
elif len(matched_filters) > 1:
raise RuntimeError('multiple filters matched: ' +
', '.join(matched_filters))
if global_args.multiple_matches == False and \
len(matched_filters) > 1:
raise RuntimeError('multiple filters matched: {}'
.format(matched_filters))
matched_filter = matched_filters[0]
self.filter_name = matched_filter['name']
commands = matched_filter.get('commands', {}) or {}
Expand Down Expand Up @@ -757,6 +764,17 @@ class FilteredControlPortProxy(socketserver.ThreadingTCPServer):

def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"--multiple-matches",
action='store_true', default=False,
help="allow multiple files to match "
)
parser.add_argument(
"--profile-dir",
action='append', metavar='DIR',
help="specifies the directory on which the profiles are " +
"(default: {})".format(DEFAULT_PROFILE_DIR)
)
parser.add_argument(
"--listen-address",
type=str, metavar='ADDR', default=DEFAULT_LISTEN_ADDRESS,
Expand Down Expand Up @@ -805,13 +823,24 @@ def main():
if global_args.listen_interface:
ip_address = get_ip_address(global_args.listen_interface)
if global_args.debug:
log("IP address for interface {} : {}".format(
log("IP address for interface {}: {}".format(
global_args.listen_interface, ip_address))
else:
ip_address = global_args.listen_address
address = (ip_address, global_args.listen_port)
server = FilteredControlPortProxy(address, FilteredControlPortProxyHandler)
log("Tor control port filter started, listening on {}:{}".format(*address))
profile_dir = []
# https://bugs.python.org/issue16399
if global_args.profile_dir == None:
global_args.profile_dir = DEFAULT_PROFILE_DIR
for dir in global_args.profile_dir:
# Don't duplicate directories
if dir not in profile_dir:
# Adds trailing slash at the end of dir if it doesn't exist yet
profile_dir.append(os.path.join(dir, ''))
global_args.profile_dir = profile_dir
log("Profile directory: {}".format(profile_dir))
try:
server.serve_forever()
except KeyboardInterrupt:
Expand Down
2 changes: 1 addition & 1 deletion usr/share/doc/onion-grater-merger/examples/40_bisq.yml
Expand Up @@ -9,7 +9,7 @@
#### meta end

---
- exe-paths:
- apparmor-profiles:
- '*'
users:
- '*'
Expand Down
2 changes: 1 addition & 1 deletion usr/share/doc/onion-grater-merger/examples/40_bitcoind.yml
Expand Up @@ -11,7 +11,7 @@
## Maintained by: https://forums.whonix.org/u/qubenix <qubenix@riseup.net>

---
- exe-paths:
- apparmor-profiles:
- '*'
users:
- '*'
Expand Down
Expand Up @@ -22,7 +22,7 @@
#XAJKD2BRVOI4C4IHK2OWF3EKIJNVIDBVCP2IM2Z2ZHPN456HNRZA

---
- exe-paths:
- apparmor-profiles:
- '*'
users:
- '*'
Expand Down
Expand Up @@ -25,7 +25,7 @@
## HsDir gets redacted.

---
- exe-paths:
- apparmor-profiles:
- '*'
users:
- '*'
Expand Down
2 changes: 1 addition & 1 deletion usr/share/doc/onion-grater-merger/examples/40_ricochet.yml
Expand Up @@ -12,7 +12,7 @@
## https://github.com/ricochet-im/ricochet/issues/30#issuecomment-271646818

---
- exe-paths:
- apparmor-profiles:
- '*'
users:
- '*'
Expand Down
2 changes: 1 addition & 1 deletion usr/share/doc/onion-grater-merger/examples/40_zeronet.yml
Expand Up @@ -9,7 +9,7 @@
#### meta end

---
- exe-paths:
- apparmor-profiles:
- '*'
users:
- '*'
Expand Down