diff options
| author | Christian Breunig <christian@breunig.cc> | 2023-02-24 15:32:52 +0100 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-24 15:32:52 +0100 | 
| commit | eaea1789f88082dae5b6cd12cc98bfc48221f35d (patch) | |
| tree | 9d7a24a1fd8239f42af7d17cecaa33866fe2ac79 /src | |
| parent | b652a66119c73042f5e141e6733605edb66b5eea (diff) | |
| parent | f4ecfaf1cd1ad7b7ea9692df5162c998add1e0c1 (diff) | |
| download | vyos-1x-eaea1789f88082dae5b6cd12cc98bfc48221f35d.tar.gz vyos-1x-eaea1789f88082dae5b6cd12cc98bfc48221f35d.zip | |
Merge pull request #1847 from aapostoliuk/T4985-2-sagitta
ipsec: T4985: Changed 'reset vpn ipsec-peer' to use vici library
Diffstat (limited to 'src')
| -rwxr-xr-x | src/op_mode/ipsec.py | 125 | 
1 files changed, 55 insertions, 70 deletions
| diff --git a/src/op_mode/ipsec.py b/src/op_mode/ipsec.py index 63fa05885..8e76f4cc0 100755 --- a/src/op_mode/ipsec.py +++ b/src/op_mode/ipsec.py @@ -14,25 +14,19 @@  # You should have received a copy of the GNU General Public License  # along with this program.  If not, see <http://www.gnu.org/licenses/>. -import os  import re  import sys  import typing -from collections import OrderedDict  from hurry import filesize  from re import split as re_split  from tabulate import tabulate -from subprocess import TimeoutExpired -from vyos.util import call  from vyos.util import convert_data  from vyos.util import seconds_to_human  import vyos.opmode - - -SWANCTL_CONF = '/etc/swanctl/swanctl.conf' +import vyos.ipsec  def _convert(text): @@ -43,22 +37,13 @@ def _alphanum_key(key):      return [_convert(c) for c in re_split('([0-9]+)', str(key))] -def _get_vici_sas(): -    from vici import Session as vici_session - -    try: -        session = vici_session() -    except Exception: -        raise vyos.opmode.UnconfiguredSubsystem("IPsec not initialized") -    sas = list(session.list_sas()) -    return sas - -  def _get_raw_data_sas(): -    get_sas = _get_vici_sas() -    sas = convert_data(get_sas) -    return sas - +    try: +        get_sas = vyos.ipsec.get_vici_sas() +        sas = convert_data(get_sas) +        return sas +    except (vyos.ipsec.ViciInitiateError) as err: +        raise vyos.opmode.UnconfiguredSubsystem(err)  def _get_formatted_output_sas(sas):      sa_data = [] @@ -139,22 +124,14 @@ def _get_formatted_output_sas(sas):  # Connections block -def _get_vici_connections(): -    from vici import Session as vici_session - -    try: -        session = vici_session() -    except Exception: -        raise vyos.opmode.UnconfiguredSubsystem("IPsec not initialized") -    connections = list(session.list_conns()) -    return connections -  def _get_convert_data_connections(): -    get_connections = _get_vici_connections() -    connections = convert_data(get_connections) -    return connections - +    try: +        get_connections = vyos.ipsec.get_vici_connections() +        connections = convert_data(get_connections) +        return connections +    except (vyos.ipsec.ViciInitiateError) as err: +        raise vyos.opmode.UnconfiguredSubsystem(err)  def _get_parent_sa_proposal(connection_name: str, data: list) -> dict:      """Get parent SA proposals by connection name @@ -239,7 +216,8 @@ def _get_child_sa_state(connection_name: str, tunnel_name: str,          # Get all child SA states          # there can be multiple SAs per tunnel          child_sa_states = [ -            v['state'] for k, v in child_sas.items() if v['name'] == tunnel_name +            v['state'] for k, v in child_sas.items() if +            v['name'] == tunnel_name          ]          return 'up' if 'INSTALLED' in child_sa_states else child_sa @@ -406,39 +384,46 @@ def _get_formatted_output_conections(data):  # Connections block end -def get_peer_connections(peer, tunnel): -    search = rf'^[\s]*({peer}-(tunnel-[\d]+|vti)).*' -    matches = [] -    if not os.path.exists(SWANCTL_CONF): -        raise vyos.opmode.UnconfiguredSubsystem("IPsec not initialized") -    suffix = None if tunnel is None else (f'tunnel-{tunnel}' if -                                          tunnel.isnumeric() else tunnel) -    with open(SWANCTL_CONF, 'r') as f: -        for line in f.readlines(): -            result = re.match(search, line) -            if result: -                if tunnel is None: -                    matches.append(result[1]) -                else: -                    if result[2] == suffix: -                        matches.append(result[1]) -    return matches - - -def reset_peer(peer: str, tunnel:typing.Optional[str] = None): -    conns = get_peer_connections(peer, tunnel) - -    if not conns: -        raise vyos.opmode.IncorrectValue('Peer or tunnel(s) not found, aborting') - -    for conn in conns: -        try: -            call(f'sudo /usr/sbin/ipsec down {conn}{{*}}', timeout = 10) -            call(f'sudo /usr/sbin/ipsec up {conn}', timeout = 10) -        except TimeoutExpired as e: -            raise vyos.opmode.InternalError(f'Timed out while resetting {conn}') - -    print('Peer reset result: success') +def _get_childsa_id_list(ike_sas: list) -> list: +    """ +    Generate list of CHILD SA ids based on list of OrderingDict +    wich is returned by vici +    :param ike_sas: list of IKE SAs generated by vici +    :type ike_sas: list +    :return: list of IKE SAs ids +    :rtype: list +    """ +    list_childsa_id: list = [] +    for ike in ike_sas: +        for ike_sa in ike.values(): +            for child_sa in ike_sa['child-sas'].values(): +                list_childsa_id.append(child_sa['uniqueid'].decode('ascii')) +    return list_childsa_id + + +def reset_peer(peer: str, tunnel: typing.Optional[str] = None): +    # Convert tunnel to Strongwan format of CHILD_SA +    if tunnel: +        if tunnel.isnumeric(): +            tunnel = f'{peer}-tunnel-{tunnel}' +        elif tunnel == 'vti': +            tunnel = f'{peer}-vti' +    try: +        sa_list: list = vyos.ipsec.get_vici_sas_by_name(peer, tunnel) + +        if not sa_list: +            raise vyos.opmode.IncorrectValue('Peer not found, aborting') +        if tunnel and sa_list: +            childsa_id_list: list = _get_childsa_id_list(sa_list) +            if not childsa_id_list: +                raise vyos.opmode.IncorrectValue( +                    'Peer or tunnel(s) not found, aborting') +        vyos.ipsec.terminate_vici_by_name(peer, tunnel) +        print('Peer reset result: success') +    except (vyos.ipsec.ViciInitiateError) as err: +        raise vyos.opmode.UnconfiguredSubsystem(err) +    except (vyos.ipsec.ViciInitiateError) as err: +        raise vyos.opmode.IncorrectValue(err)  def show_sa(raw: bool): | 
