From 5c7647bcc242d4b26cd9afdde1f084ef93916727 Mon Sep 17 00:00:00 2001 From: Viacheslav Hletenko Date: Tue, 19 Nov 2024 17:44:58 +0000 Subject: [PATCH] T264: IPsec add base64 encoded secret-type feature Add the ability to configure base64 encoded passwords for VPN IPSec site-to-site peers authentication psk PSK secret 'xxxxx==' authentication psk PSK secret-type --- data/templates/ipsec/swanctl.conf.j2 | 4 ++++ interface-definitions/vpn_ipsec.xml.in | 12 ++++++++++++ python/vyos/utils/convert.py | 26 +++++++++++++++++++++++++ smoketest/scripts/cli/test_vpn_ipsec.py | 7 +++++-- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/data/templates/ipsec/swanctl.conf.j2 b/data/templates/ipsec/swanctl.conf.j2 index 698a9135ef..64e7ea860c 100644 --- a/data/templates/ipsec/swanctl.conf.j2 +++ b/data/templates/ipsec/swanctl.conf.j2 @@ -87,7 +87,11 @@ secrets { id-{{ gen_uuid }} = "{{ id }}" {% endfor %} {% endif %} +{% if psk_config.secret_type is vyos_defined('base64') %} + secret = 0s{{ psk_config.secret }} +{% elif psk_config.secret_type is vyos_defined('plaintext') %} secret = "{{ psk_config.secret }}" +{% endif %} } {% endfor %} {% endif %} diff --git a/interface-definitions/vpn_ipsec.xml.in b/interface-definitions/vpn_ipsec.xml.in index d9d6fd93bb..5540021e23 100644 --- a/interface-definitions/vpn_ipsec.xml.in +++ b/interface-definitions/vpn_ipsec.xml.in @@ -41,6 +41,18 @@ + + + Secret type + + base64 plaintext + + + (base64|plaintext) + + + plaintext + diff --git a/python/vyos/utils/convert.py b/python/vyos/utils/convert.py index dd4266f57c..2f587405d4 100644 --- a/python/vyos/utils/convert.py +++ b/python/vyos/utils/convert.py @@ -235,3 +235,29 @@ def convert_data(data) -> dict | list | tuple | str | int | float | bool | None: # which cannot be converted to JSON # for example: complex | range | memoryview return + + +def encode_to_base64(input_string): + """ + Encodes a given string to its base64 representation. + + Args: + input_string (str): The string to be encoded. + + Returns: + str: The base64-encoded version of the input string. + + Example: + input_string = "Hello, World!" + encoded_string = encode_to_base64(input_string) + print(encoded_string) # Output: SGVsbG8sIFdvcmxkIQ== + """ + import base64 + # Convert the string to bytes + byte_string = input_string.encode('utf-8') + + # Encode the byte string to base64 + encoded_string = base64.b64encode(byte_string) + + # Decode the base64 bytes back to a string + return encoded_string.decode('utf-8') diff --git a/smoketest/scripts/cli/test_vpn_ipsec.py b/smoketest/scripts/cli/test_vpn_ipsec.py index de18d04274..f2bea58d1c 100755 --- a/smoketest/scripts/cli/test_vpn_ipsec.py +++ b/smoketest/scripts/cli/test_vpn_ipsec.py @@ -21,6 +21,7 @@ from vyos.configsession import ConfigSessionError from vyos.ifconfig import Interface +from vyos.utils.convert import encode_to_base64 from vyos.utils.process import process_named_running from vyos.utils.file import read_file @@ -495,6 +496,7 @@ def test_flex_vpn_vips(self): local_id = 'vyos-r1' remote_id = 'vyos-r2' peer_base_path = base_path + ['site-to-site', 'peer', connection_name] + secret_base64 = encode_to_base64(secret) self.cli_set(tunnel_path + ['tun1', 'encapsulation', 'gre']) self.cli_set(tunnel_path + ['tun1', 'source-address', local_address]) @@ -509,7 +511,8 @@ def test_flex_vpn_vips(self): self.cli_set(base_path + ['authentication', 'psk', connection_name, 'id', remote_id]) self.cli_set(base_path + ['authentication', 'psk', connection_name, 'id', local_address]) self.cli_set(base_path + ['authentication', 'psk', connection_name, 'id', peer_ip]) - self.cli_set(base_path + ['authentication', 'psk', connection_name, 'secret', secret]) + self.cli_set(base_path + ['authentication', 'psk', connection_name, 'secret', secret_base64]) + self.cli_set(base_path + ['authentication', 'psk', connection_name, 'secret-type', 'base64']) self.cli_set(peer_base_path + ['authentication', 'local-id', local_id]) self.cli_set(peer_base_path + ['authentication', 'mode', 'pre-shared-secret']) @@ -546,7 +549,7 @@ def test_flex_vpn_vips(self): f'id-{regex_uuid4} = "{remote_id}"', f'id-{regex_uuid4} = "{peer_ip}"', f'id-{regex_uuid4} = "{local_address}"', - f'secret = "{secret}"', + f'secret = 0s{secret_base64}', ] for line in swanctl_secrets_lines: