From 9242a9404febd02902209d282aa5afa1940fb430 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Wed, 30 Oct 2019 14:45:24 -0700 Subject: [PATCH] wireguard: Add ability to set private key in client addition Signed-off-by: Sunil Mohan Adapa Reviewed-by: James Valleroy --- actions/wireguard | 31 ++++++++++++---------- plinth/modules/wireguard/forms.py | 5 ++++ plinth/modules/wireguard/views.py | 43 ++++++++++++++++++------------- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/actions/wireguard b/actions/wireguard index 19085de33..7221ae907 100755 --- a/actions/wireguard +++ b/actions/wireguard @@ -24,6 +24,7 @@ import json import os import pathlib import subprocess +import sys from plinth import network @@ -63,7 +64,6 @@ def parse_arguments(): help='Client IP address provided by server') add_server.add_argument('--public-key', required=True, help='Public key of the server') - add_server.add_argument('--pre-shared-key', help='Pre-shared key') add_server.add_argument( '--all-outgoing', action='store_true', help='Use this connection to send all outgoing traffic') @@ -200,10 +200,11 @@ def _find_next_interface(): def _get_connection_settings(name, interface, endpoint, client_ip, public_key, - pre_shared_key): + client_private_key, pre_shared_key): """Return settings for Network Manager connection.""" - with PRIVATE_KEY_PATH.open() as private_key_file: - private_key = private_key_file.read().strip() + if not client_private_key: + with PRIVATE_KEY_PATH.open() as private_key_file: + client_private_key = private_key_file.read().strip() return { 'common': { @@ -221,7 +222,7 @@ def _get_connection_settings(name, interface, endpoint, client_ip, public_key, 'second_dns': '', }, 'wireguard': { - 'private_key': private_key, + 'private_key': client_private_key, 'peer_endpoint': endpoint, 'peer_public_key': public_key, 'preshared_key': pre_shared_key, @@ -231,6 +232,7 @@ def _get_connection_settings(name, interface, endpoint, client_ip, public_key, def subcommand_add_server(arguments): """Add a server.""" + secret_args = json.loads(sys.stdin.read() or '{}') new_interface_name = _find_next_interface() subprocess.run( @@ -238,17 +240,19 @@ def subcommand_add_server(arguments): check=True) connection_name = 'WireGuard-' + new_interface_name - settings = _get_connection_settings(connection_name, - new_interface_name, + settings = _get_connection_settings(connection_name, new_interface_name, arguments.endpoint, arguments.client_ip, arguments.public_key, - arguments.pre_shared_key) + secret_args.get('client_private_key'), + secret_args.get('pre_shared_key')) network.add_connection(settings) def subcommand_modify_server(arguments): """Modify a server.""" + secret_args = json.loads(sys.stdin.read() or '{}') + interfaces = _get_info() interfaces.pop(SERVER_INTERFACE, None) interface_to_modify = None @@ -261,12 +265,11 @@ def subcommand_modify_server(arguments): if interface_to_modify: connection = network.get_connection_by_interface_name( interface_to_modify) - settings = _get_connection_settings('WireGuard-' + interface_to_modify, - interface_to_modify, - arguments.endpoint, - arguments.client_ip, - arguments.public_key, - arguments.pre_shared_key) + settings = _get_connection_settings( + 'WireGuard-' + interface_to_modify, interface_to_modify, + arguments.endpoint, arguments.client_ip, arguments.public_key, + secret_args.get('client_private_key'), + secret_args.get('pre_shared_key')) if connection: network.edit_connection(connection, settings) diff --git a/plinth/modules/wireguard/forms.py b/plinth/modules/wireguard/forms.py index 2fe72d2d4..bb4cc0978 100644 --- a/plinth/modules/wireguard/forms.py +++ b/plinth/modules/wireguard/forms.py @@ -43,6 +43,11 @@ class AddServerForm(forms.Form): label=_('Public key of the server'), strip=True, help_text=_('Public key of the server.')) + client_private_key = forms.CharField( + label=_('Private key of the client'), strip=True, + help_text=_('Optional. A new key is generated if left blank.'), + required=False) + pre_shared_key = forms.CharField( label=_('Pre-shared key'), strip=True, required=False, help_text=_('Optional: a shared secret key provided by the server to ' diff --git a/plinth/modules/wireguard/views.py b/plinth/modules/wireguard/views.py index 299c6025e..824b27a93 100644 --- a/plinth/modules/wireguard/views.py +++ b/plinth/modules/wireguard/views.py @@ -18,6 +18,7 @@ Views for WireGuard application. """ +import json import tempfile import urllib.parse @@ -161,22 +162,25 @@ class AddServerView(SuccessMessageMixin, FormView): endpoint = form.cleaned_data.get('endpoint') client_ip_address = form.cleaned_data.get('client_ip_address') public_key = form.cleaned_data.get('public_key') + client_private_key = form.cleaned_data.get('client_private_key') pre_shared_key = form.cleaned_data.get('pre_shared_key') all_outgoing_traffic = form.cleaned_data.get('all_outgoing_traffic') - args = ['add-server', '--endpoint', endpoint, '--client-ip', - client_ip_address, '--public-key', public_key] - optional_psk_file = None + args = [ + 'add-server', '--endpoint', endpoint, '--client-ip', + client_ip_address, '--public-key', public_key + ] + secret_args = {} + if client_private_key: + secret_args['client_private_key'] = client_private_key + if pre_shared_key: - optional_psk_file = tempfile.NamedTemporaryFile() - optional_psk_file.write(pre_shared_key.encode()) - args += ['--pre-shared-key', optional_psk_file.name] + secret_args['pre_shared_key'] = pre_shared_key if all_outgoing_traffic: args.append('--all-outgoing') - actions.superuser_run('wireguard', args) - if optional_psk_file: - optional_psk_file.close() + actions.superuser_run('wireguard', args, + input=json.dumps(secret_args).encode()) return super().form_valid(form) @@ -238,22 +242,25 @@ class EditServerView(SuccessMessageMixin, FormView): endpoint = form.cleaned_data.get('endpoint') client_ip_address = form.cleaned_data.get('client_ip_address') public_key = form.cleaned_data.get('public_key') + client_private_key = form.client_data.get('client_private_key') pre_shared_key = form.cleaned_data.get('pre_shared_key') all_outgoing_traffic = form.cleaned_data.get('all_outgoing_traffic') - args = ['modify-server', '--endpoint', endpoint, '--client-ip', - client_ip_address, '--public-key', public_key] - optional_psk_file = None + args = [ + 'modify-server', '--endpoint', endpoint, '--client-ip', + client_ip_address, '--public-key', public_key + ] + secret_args = {} + if client_private_key: + secret_args['client_private_key'] = client_private_key + if pre_shared_key: - optional_psk_file = tempfile.NamedTemporaryFile() - optional_psk_file.write(pre_shared_key.encode()) - args += ['--pre-shared-key', optional_psk_file.name] + secret_args['pre_shared_key'] = pre_shared_key if all_outgoing_traffic: args.append('--all-outgoing') - actions.superuser_run('wireguard', args) - if optional_psk_file: - optional_psk_file.close() + actions.superuser_run('wireguard', args, + input=json.dumps(secret_args).encode()) return super().form_valid(form)