wireguard: Add ability to set private key in client addition

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2019-10-30 14:45:24 -07:00 committed by James Valleroy
parent ad53848983
commit 9242a9404f
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
3 changed files with 47 additions and 32 deletions

View File

@ -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)

View File

@ -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 '

View File

@ -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)