From 50e5608331330b37c0b9cce846e34ccc193d1b0d Mon Sep 17 00:00:00 2001 From: Joseph Nuthalapati Date: Wed, 26 Feb 2020 21:44:42 +0530 Subject: [PATCH] shadowsocks: Move user settings to state directory Fixes #1775 Signed-off-by: Joseph Nuthalapati Reviewed-by: James Valleroy --- actions/shadowsocks | 40 +++++++++++++------ plinth/modules/shadowsocks/__init__.py | 7 +++- .../freedombox.conf | 2 + plinth/modules/shadowsocks/manifest.py | 4 +- 4 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 plinth/modules/shadowsocks/data/lib/systemd/system/shadowsocks-libev-local@.service.d/freedombox.conf diff --git a/actions/shadowsocks b/actions/shadowsocks index 1ade9ec33..21ebc62d1 100755 --- a/actions/shadowsocks +++ b/actions/shadowsocks @@ -7,12 +7,15 @@ Helper script for configuring Shadowsocks. import argparse import json import os +import subprocess import sys from plinth import action_utils from plinth.modules import shadowsocks -SHADOWSOCKS_CONFIG = '/etc/shadowsocks-libev/freedombox.json' +SHADOWSOCKS_CONFIG_SYMLINK = '/etc/shadowsocks-libev/freedombox.json' +SHADOWSOCKS_CONFIG_ACTUAL = \ + '/var/lib/private/shadowsocks-libev/freedombox/freedombox.json' def parse_arguments(): @@ -26,6 +29,11 @@ def parse_arguments(): subparsers.add_parser('merge-config', help='Merge JSON config from stdin with existing') + # Migrations + subparsers.add_parser( + 'migrate-1-2', + help='Move shadowsocks config file to a secure location') + subparsers.required = True return parser.parse_args() @@ -35,23 +43,25 @@ def subcommand_setup(_): # Only client socks5 proxy is supported for now. Disable the # server component. action_utils.service_disable('shadowsocks-libev') + if not os.path.islink(SHADOWSOCKS_CONFIG_SYMLINK): + os.symlink(SHADOWSOCKS_CONFIG_ACTUAL, SHADOWSOCKS_CONFIG_SYMLINK) -def subcommand_get_config(arguments): +def subcommand_get_config(_): """Read and print Shadowsocks configuration.""" try: - print(open(SHADOWSOCKS_CONFIG, 'r').read()) + print(open(SHADOWSOCKS_CONFIG_SYMLINK, 'r').read()) except Exception: sys.exit(1) -def subcommand_merge_config(arguments): +def subcommand_merge_config(_): """Configure Shadowsocks.""" config = sys.stdin.read() config = json.loads(config) try: - current_config = open(SHADOWSOCKS_CONFIG, 'r').read() + current_config = open(SHADOWSOCKS_CONFIG_SYMLINK, 'r').read() current_config = json.loads(current_config) except (OSError, json.JSONDecodeError): current_config = {} @@ -59,16 +69,20 @@ def subcommand_merge_config(arguments): new_config = current_config new_config.update(config) new_config = json.dumps(new_config, indent=4, sort_keys=True) + open(SHADOWSOCKS_CONFIG_SYMLINK, 'w').write(new_config) - # XXX: Config file with password is world-readable. This is the - # same as the default config file, but find a way to avoid this. - # See https://salsa.debian.org/freedombox-team/plinth/-/merge_requests/1724 - old_umask = os.umask(0o022) - try: - open(SHADOWSOCKS_CONFIG, 'w').write(new_config) - finally: - os.umask(old_umask) + action_utils.service_restart(shadowsocks.managed_services[0]) + +def subcommand_migrate_1_2(_): + """Move shadowsocks config file to a secure location.""" + if os.path.isfile(SHADOWSOCKS_CONFIG_SYMLINK): # ignoring symlinks + os.makedirs('/var/lib/private/shadowsocks-libev/freedombox/', + exist_ok=True) + os.replace(SHADOWSOCKS_CONFIG_SYMLINK, SHADOWSOCKS_CONFIG_ACTUAL) + os.symlink(SHADOWSOCKS_CONFIG_ACTUAL, SHADOWSOCKS_CONFIG_SYMLINK) + + subprocess.check_call(['systemctl', 'daemon-reload']) action_utils.service_restart(shadowsocks.managed_services[0]) diff --git a/plinth/modules/shadowsocks/__init__.py b/plinth/modules/shadowsocks/__init__.py index 531394475..773749333 100644 --- a/plinth/modules/shadowsocks/__init__.py +++ b/plinth/modules/shadowsocks/__init__.py @@ -15,7 +15,7 @@ from plinth.utils import format_lazy from .manifest import backup # noqa, pylint: disable=unused-import -version = 1 +version = 2 managed_services = ['shadowsocks-libev-local@freedombox'] @@ -89,6 +89,11 @@ def init(): def setup(helper, old_version=None): """Install and configure the module.""" + + if old_version == 1: + helper.call('migration', actions.superuser_run, 'shadowsocks', + ['migrate-1-2']) + helper.install(managed_packages) helper.call('post', actions.superuser_run, 'shadowsocks', ['setup']) helper.call('post', app.enable) diff --git a/plinth/modules/shadowsocks/data/lib/systemd/system/shadowsocks-libev-local@.service.d/freedombox.conf b/plinth/modules/shadowsocks/data/lib/systemd/system/shadowsocks-libev-local@.service.d/freedombox.conf new file mode 100644 index 000000000..ef74f9383 --- /dev/null +++ b/plinth/modules/shadowsocks/data/lib/systemd/system/shadowsocks-libev-local@.service.d/freedombox.conf @@ -0,0 +1,2 @@ +[Service] +StateDirectory=shadowsocks-libev/%i diff --git a/plinth/modules/shadowsocks/manifest.py b/plinth/modules/shadowsocks/manifest.py index 78a3455c6..38a0412cb 100644 --- a/plinth/modules/shadowsocks/manifest.py +++ b/plinth/modules/shadowsocks/manifest.py @@ -7,7 +7,9 @@ from plinth.modules.backups.api import validate as validate_backup backup = validate_backup({ 'secrets': { - 'files': ['/etc/shadowsocks-libev/freedombox.json'] + 'files': [ + '/var/lib/private/shadowsocks-libev/freedombox/freedombox.json' + ] }, 'services': ['shadowsocks-libev-local@freedombox'] })