From e41ae4d952e276d8497d38f5761806c14ea542d2 Mon Sep 17 00:00:00 2001 From: DmitriyEshenko Date: Wed, 9 Sep 2020 06:45:40 +0000 Subject: openconnect: T2036: Move CLI commands under vpn openconnect --- smoketest/scripts/cli/test_vpn_anyconnect.py | 58 --------------------------- smoketest/scripts/cli/test_vpn_openconnect.py | 58 +++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 58 deletions(-) delete mode 100755 smoketest/scripts/cli/test_vpn_anyconnect.py create mode 100755 smoketest/scripts/cli/test_vpn_openconnect.py (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_vpn_anyconnect.py b/smoketest/scripts/cli/test_vpn_anyconnect.py deleted file mode 100755 index dd8ab1609..000000000 --- a/smoketest/scripts/cli/test_vpn_anyconnect.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2020 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import re -import os -import unittest - -from psutil import process_iter -from vyos.configsession import ConfigSession, ConfigSessionError -from vyos.util import read_file - -OCSERV_CONF = '/run/ocserv/ocserv.conf' -base_path = ['vpn', 'anyconnect'] -cert = '/etc/ssl/certs/ssl-cert-snakeoil.pem' -cert_key = '/etc/ssl/private/ssl-cert-snakeoil.key' - -class TestVpnAnyconnect(unittest.TestCase): - def setUp(self): - self.session = ConfigSession(os.getpid()) - - def tearDown(self): - # Delete vpn anyconnect configuration - self.session.delete(base_path) - self.session.commit() - - del self.session - - def test_vpn(self): - user = 'vyos_user' - password = 'vyos_pass' - self.session.delete(base_path) - self.session.set(base_path + ["authentication", "local-users", "username", user, "password", password]) - self.session.set(base_path + ["authentication", "mode", "local"]) - self.session.set(base_path + ["network-settings", "client-ip-settings", "subnet", "192.0.2.0/24"]) - self.session.set(base_path + ["ssl", "ca-cert-file", cert]) - self.session.set(base_path + ["ssl", "cert-file", cert]) - self.session.set(base_path + ["ssl", "key-file", cert_key]) - - self.session.commit() - - # Check for running process - self.assertTrue("ocserv-main" in (p.name() for p in process_iter())) - -if __name__ == '__main__': - unittest.main() diff --git a/smoketest/scripts/cli/test_vpn_openconnect.py b/smoketest/scripts/cli/test_vpn_openconnect.py new file mode 100755 index 000000000..d2b82d686 --- /dev/null +++ b/smoketest/scripts/cli/test_vpn_openconnect.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2020 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import re +import os +import unittest + +from psutil import process_iter +from vyos.configsession import ConfigSession, ConfigSessionError +from vyos.util import read_file + +OCSERV_CONF = '/run/ocserv/ocserv.conf' +base_path = ['vpn', 'openconnect'] +cert = '/etc/ssl/certs/ssl-cert-snakeoil.pem' +cert_key = '/etc/ssl/private/ssl-cert-snakeoil.key' + +class TestVpnOpenconnect(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + + def tearDown(self): + # Delete vpn openconnect configuration + self.session.delete(base_path) + self.session.commit() + + del self.session + + def test_vpn(self): + user = 'vyos_user' + password = 'vyos_pass' + self.session.delete(base_path) + self.session.set(base_path + ["authentication", "local-users", "username", user, "password", password]) + self.session.set(base_path + ["authentication", "mode", "local"]) + self.session.set(base_path + ["network-settings", "client-ip-settings", "subnet", "192.0.2.0/24"]) + self.session.set(base_path + ["ssl", "ca-cert-file", cert]) + self.session.set(base_path + ["ssl", "cert-file", cert]) + self.session.set(base_path + ["ssl", "key-file", cert_key]) + + self.session.commit() + + # Check for running process + self.assertTrue("ocserv-main" in (p.name() for p in process_iter())) + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.3 From 5136870ca682b2f32e5ccfc68251cba5664623f3 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 13 Sep 2020 10:32:56 +0200 Subject: qat: T2857: add very limited smoketest --- .../scripts/cli/test_system_acceleration_qat.py | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100755 smoketest/scripts/cli/test_system_acceleration_qat.py (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_system_acceleration_qat.py b/smoketest/scripts/cli/test_system_acceleration_qat.py new file mode 100755 index 000000000..c937c810e --- /dev/null +++ b/smoketest/scripts/cli/test_system_acceleration_qat.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2020 Francois Mertz fireboxled@gmail.com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import os +import unittest + +from vyos.configsession import ConfigSession +from vyos.configsession import ConfigSessionError + +base_path = ['system', 'acceleration', 'qat'] + +class TestSystemLCD(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + + def tearDown(self): + self.session.delete(base_path) + self.session.commit() + del self.session + + def test_basic(self): + """ Check if configuration script is in place and that the config + script throws an error as QAT device is not present in Qemu. This *must* + be extended with QAT autodetection once run on a QAT enabled device """ + + # configure some system display + self.session.set(base_path) + + # An error must be thrown if QAT device could not be found + with self.assertRaises(ConfigSessionError): + self.session.commit() + +if __name__ == '__main__': + unittest.main() -- cgit v1.2.3 From 98d95b677867c27064d84033dc451ba04c9a2b7b Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 15 Sep 2020 18:54:09 +0200 Subject: bonding: T2515: preserve interface admin state when removing from bond Removing a member from a bond/LACP will turn the physical interface always in admin-down state. This is invalid, the interface should be placed into the state configured on the VyOS CLI. Smoketest on bond interfaces is extended to check this behavior. --- python/vyos/ifconfig/bond.py | 22 ++++++++----- smoketest/scripts/cli/test_interfaces_bonding.py | 24 ++++++++++++++ src/conf_mode/interfaces-bonding.py | 42 +++++++++++++----------- 3 files changed, 59 insertions(+), 29 deletions(-) (limited to 'smoketest/scripts/cli') diff --git a/python/vyos/ifconfig/bond.py b/python/vyos/ifconfig/bond.py index 67dcd2b69..c33cf30bf 100644 --- a/python/vyos/ifconfig/bond.py +++ b/python/vyos/ifconfig/bond.py @@ -1,4 +1,4 @@ -# Copyright 2019 VyOS maintainers and contributors +# Copyright 2019-2020 VyOS maintainers and contributors # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -381,9 +381,14 @@ class BondIf(Interface): # Some interface options can only be changed if the interface is # administratively down if self.get_admin_state() == 'down': - # Delete bond member port(s) + # Remove ALL bond member interfaces for interface in self.get_slaves(): self.del_port(interface) + # Removing an interface from a bond will always place the underlaying + # physical interface in admin-down state! If physical interface is + # not disabled, re-enable it. + if not vyos_dict_search(f'member.interface_remove.{interface}.disable', config): + Interface(interface).set_admin_state('up') # Bonding policy/mode value = config.get('mode') @@ -391,13 +396,12 @@ class BondIf(Interface): # Add (enslave) interfaces to bond value = vyos_dict_search('member.interface', config) - if value: - for interface in value: - # if we've come here we already verified the interface - # does not have an addresses configured so just flush - # any remaining ones - Interface(interface).flush_addrs() - self.add_port(interface) + for interface in (value or []): + # if we've come here we already verified the interface + # does not have an addresses configured so just flush + # any remaining ones + Interface(interface).flush_addrs() + self.add_port(interface) # Primary device interface - must be set after 'mode' value = config.get('primary') diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index e3d3b25ee..b165883b9 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -20,6 +20,7 @@ import unittest from base_interfaces_test import BasicInterfaceTest from vyos.ifconfig import Section +from vyos.ifconfig.interface import Interface from vyos.configsession import ConfigSessionError from vyos.util import read_file @@ -57,5 +58,28 @@ class BondingInterfaceTest(BasicInterfaceTest.BaseTest): slaves = read_file(f'/sys/class/net/{interface}/bonding/slaves').split() self.assertListEqual(slaves, self._members) + def test_remove_member(self): + """ T2515: when removing a bond member the interface must be admin-up again """ + + # configure member interfaces + for interface in self._interfaces: + for option in self._options.get(interface, []): + self.session.set(self._base_path + [interface] + option.split()) + + self.session.commit() + + # remove single bond member port + for interface in self._interfaces: + remove_member = self._members[0] + self.session.delete(self._base_path + [interface, 'member', 'interface', remove_member]) + + self.session.commit() + + # removed member port must be admin-up + for interface in self._interfaces: + remove_member = self._members[0] + state = Interface(remove_member).get_admin_state() + self.assertEqual('up', state) + if __name__ == '__main__': unittest.main() diff --git a/src/conf_mode/interfaces-bonding.py b/src/conf_mode/interfaces-bonding.py index 16e6e4f6e..a9679b47c 100755 --- a/src/conf_mode/interfaces-bonding.py +++ b/src/conf_mode/interfaces-bonding.py @@ -29,6 +29,7 @@ from vyos.configverify import verify_source_interface from vyos.configverify import verify_vlan_config from vyos.configverify import verify_vrf from vyos.ifconfig import BondIf +from vyos.ifconfig import Section from vyos.validate import is_member from vyos.validate import has_address_configured from vyos import ConfigError @@ -69,31 +70,33 @@ def get_config(config=None): # into a dictionary - we will use this to add additional information # later on for wach member if 'member' in bond and 'interface' in bond['member']: - # first convert it to a list if only one member is given - if isinstance(bond['member']['interface'], str): - bond['member']['interface'] = [bond['member']['interface']] - - tmp={} - for interface in bond['member']['interface']: - tmp.update({interface: {}}) - - bond['member']['interface'] = tmp + # convert list if member interfaces to a dictionary + bond['member']['interface'] = dict.fromkeys( + bond['member']['interface'], {}) if 'mode' in bond: bond['mode'] = get_bond_mode(bond['mode']) tmp = leaf_node_changed(conf, ['mode']) - if tmp: - bond.update({'shutdown_required': ''}) + if tmp: bond.update({'shutdown_required': {}}) # determine which members have been removed - tmp = leaf_node_changed(conf, ['member', 'interface']) - if tmp: - bond.update({'shutdown_required': ''}) - if 'member' in bond: - bond['member'].update({'interface_remove': tmp }) - else: - bond.update({'member': {'interface_remove': tmp }}) + interfaces_removed = leaf_node_changed(conf, ['member', 'interface']) + if interfaces_removed: + bond.update({'shutdown_required': {}}) + if 'member' not in bond: + bond.update({'member': {}}) + + tmp = {} + for interface in interfaces_removed: + section = Section.section(interface) # this will be 'ethernet' for 'eth0' + if conf.exists(['insterfaces', section, interface, 'disable']): + tmp.update({interface : {'disable': ''}}) + else: + tmp.update({interface : {}}) + + # also present the interfaces to be removed from the bond as dictionary + bond['member'].update({'interface_remove': tmp}) if 'member' in bond and 'interface' in bond['member']: for interface, interface_config in bond['member']['interface'].items(): @@ -109,8 +112,7 @@ def get_config(config=None): # bond members must not have an assigned address tmp = has_address_configured(conf, interface) - if tmp: - interface_config.update({'has_address' : ''}) + if tmp: interface_config.update({'has_address' : ''}) return bond -- cgit v1.2.3 From de5cfd35ba14b75b58da653643472de93577b434 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 16 Sep 2020 21:54:50 +0200 Subject: wireless: T2887: add smoketest for hostapd --- data/templates/wifi/hostapd.conf.tmpl | 4 -- smoketest/scripts/cli/test_interfaces_wireless.py | 87 +++++++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) (limited to 'smoketest/scripts/cli') diff --git a/data/templates/wifi/hostapd.conf.tmpl b/data/templates/wifi/hostapd.conf.tmpl index 136942ca8..132c4ce40 100644 --- a/data/templates/wifi/hostapd.conf.tmpl +++ b/data/templates/wifi/hostapd.conf.tmpl @@ -51,10 +51,6 @@ ssid={{ ssid }} # (default: 0, i.e., not set) # Please note that some drivers do not use this value from hostapd and the # channel will need to be configured separately with iwconfig. -# -# If CONFIG_ACS build option is enabled, the channel can be selected -# automatically at run time by setting channel=acs_survey or channel=0, both of -# which will enable the ACS survey based algorithm. channel={{ channel }} {% endif %} diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py index fae233244..691f633b7 100755 --- a/smoketest/scripts/cli/test_interfaces_wireless.py +++ b/smoketest/scripts/cli/test_interfaces_wireless.py @@ -15,11 +15,19 @@ # along with this program. If not, see . import os +import re import unittest from base_interfaces_test import BasicInterfaceTest from psutil import process_iter + from vyos.util import check_kmod +from vyos.util import read_file + +def get_config_value(interface, key): + tmp = read_file(f'/run/hostapd/{interface}.conf') + tmp = re.findall(r'\n?{}=+(.*)'.format(key), tmp) + return tmp[0] class WirelessInterfaceTest(BasicInterfaceTest.BaseTest): def setUp(self): @@ -53,6 +61,85 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest): else: self.assertTrue(False) + def test_hostapd_config(self): + """ Check if hostapd config is properly generated """ + + # Only set the hostapd (access-point) options + interface = 'wlan0' + phy = 'phy0' + ssid = 'ssid' + channel = '1' + + self.session.set(self._base_path + [interface, 'physical-device', phy]) + self.session.set(self._base_path + [interface, 'ssid', ssid]) + self.session.set(self._base_path + [interface, 'type', 'access-point']) + self.session.set(self._base_path + [interface, 'channel', channel]) + # auto-powersave is special + self.session.set(self._base_path + [interface, 'capabilities', 'ht', 'auto-powersave']) + + ht_opt = { + # VyOS CLI option hostapd - ht_capab setting + '40mhz-incapable' : '[40-INTOLERANT]', + 'delayed-block-ack' : '[DELAYED-BA]', + 'greenfield' : '[GF]', + 'ldpc' : '[LDPC]', + 'lsig-protection' : '[LSIG-TXOP-PROT]', + 'channel-set-width ht40+' : '[HT40+]', + 'stbc tx' : '[TX-STBC]', + 'stbc rx 123' : '[RX-STBC-123]', + 'max-amsdu 7935' : '[MAX-AMSDU-7935]', + 'smps static' : '[SMPS-STATIC]', + } + for key in ht_opt: + self.session.set(self._base_path + [interface, 'capabilities', 'ht'] + key.split()) + + vht_opt = { + # VyOS CLI option hostapd - ht_capab setting + 'stbc tx' : '[TX-STBC-2BY1]', + 'stbc rx 12' : '[RX-STBC-12]', + 'ldpc' : '[RXLDPC]', + 'tx-powersave' : '[VHT-TXOP-PS]', + 'vht-cf' : '[HTC-VHT]', + 'antenna-pattern-fixed' : '[RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]', + 'max-mpdu 11454' : '[MAX-MPDU-11454]', + 'max-mpdu-exp 2' : '[MAX-A-MPDU-LEN-EXP-2][VHT160]', + 'link-adaptation both' : '[VHT-LINK-ADAPT3]', + 'short-gi 80' : '[SHORT-GI-80]', + 'short-gi 160' : '[SHORT-GI-160]', + } + for key in vht_opt: + self.session.set(self._base_path + [interface, 'capabilities', 'vht'] + key.split()) + + self.session.commit() + + # + # Validate Config + # + + # ssid + tmp = get_config_value(interface, 'ssid') + self.assertEqual(ssid, tmp) + + # channel + tmp = get_config_value(interface, 'channel') + self.assertEqual(channel, tmp) + + # auto-powersave is special + tmp = get_config_value(interface, 'uapsd_advertisement_enabled') + self.assertEqual('1', tmp) + + tmp = get_config_value(interface, 'ht_capab') + for key, value in ht_opt.items(): + self.assertIn(value, tmp) + + tmp = get_config_value(interface, 'vht_capab') + for key, value in vht_opt.items(): + self.assertIn(value, tmp) + + # Check for running process + self.assertIn('hostapd', (p.name() for p in process_iter())) + + if __name__ == '__main__': check_kmod('mac80211_hwsim') unittest.main() -- cgit v1.2.3 From de6dd336243b90a79023d7c84645cd75b5798f41 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 17 Sep 2020 21:29:52 +0200 Subject: smoketest: bond: T2894: vlan interfaces must not remove bond members A regression showed that when adding a vif to a bond the bond interface will loose all its member interfaces. This is - of course - super bad! --- smoketest/scripts/cli/test_interfaces_bonding.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index b165883b9..9ad8568ee 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -58,6 +58,14 @@ class BondingInterfaceTest(BasicInterfaceTest.BaseTest): slaves = read_file(f'/sys/class/net/{interface}/bonding/slaves').split() self.assertListEqual(slaves, self._members) + def test_8021q_vlan(self): + """ Testcase for 802.1q VLAN interfaces """ + super().test_8021q_vlan() + + for interface in self._interfaces: + slaves = read_file(f'/sys/class/net/{interface}/bonding/slaves').split() + self.assertListEqual(slaves, self._members) + def test_remove_member(self): """ T2515: when removing a bond member the interface must be admin-up again """ -- cgit v1.2.3 From 14c754f8bd6c96165d8ad3745c19c80a562910e1 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Thu, 17 Sep 2020 21:34:56 +0200 Subject: smoketest: bond: T2894: extend comments --- smoketest/scripts/cli/test_interfaces_bonding.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py index 9ad8568ee..ac5e01e50 100755 --- a/smoketest/scripts/cli/test_interfaces_bonding.py +++ b/smoketest/scripts/cli/test_interfaces_bonding.py @@ -59,7 +59,8 @@ class BondingInterfaceTest(BasicInterfaceTest.BaseTest): self.assertListEqual(slaves, self._members) def test_8021q_vlan(self): - """ Testcase for 802.1q VLAN interfaces """ + """ Testcase for 802.1q VLAN interfaces created on top of a lacp / bond + interface. This is the testcase for T2894 """ super().test_8021q_vlan() for interface in self._interfaces: @@ -67,7 +68,9 @@ class BondingInterfaceTest(BasicInterfaceTest.BaseTest): self.assertListEqual(slaves, self._members) def test_remove_member(self): - """ T2515: when removing a bond member the interface must be admin-up again """ + """ T2515: when removing a bond member the previously enslaved/member + interface must be in its former admin-up/down state. Here we ensure that + it is admin-up as it was admin-up before. """ # configure member interfaces for interface in self._interfaces: -- cgit v1.2.3 From 41a8c45c6b188646d6c6ac97bfaa2dffaffe1653 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sat, 19 Sep 2020 21:57:08 +0200 Subject: smoketest: T2886: validate RADIUS configuration --- smoketest/scripts/cli/test_service_ssh.py | 2 +- smoketest/scripts/cli/test_system_login.py | 70 +++++++++++++++++++++++-- smoketest/scripts/system/test_kernel_options.py | 36 ------------- 3 files changed, 68 insertions(+), 40 deletions(-) delete mode 100755 smoketest/scripts/system/test_kernel_options.py (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_service_ssh.py b/smoketest/scripts/cli/test_service_ssh.py index 1038b8775..79850fe44 100755 --- a/smoketest/scripts/cli/test_service_ssh.py +++ b/smoketest/scripts/cli/test_service_ssh.py @@ -27,7 +27,7 @@ base_path = ['service', 'ssh'] def get_config_value(key): tmp = read_file(SSHD_CONF) - tmp = re.findall(r'\n?{}\s+(.*)'.format(key), tmp) + tmp = re.findall(f'\n?{key}\s+(.*)', tmp) return tmp def is_service_running(): diff --git a/smoketest/scripts/cli/test_system_login.py b/smoketest/scripts/cli/test_system_login.py index 3c4b1fa28..48ae78ccf 100755 --- a/smoketest/scripts/cli/test_system_login.py +++ b/smoketest/scripts/cli/test_system_login.py @@ -16,11 +16,15 @@ import os import re +import platform import unittest +from platform import release as kernel_version from subprocess import Popen, PIPE -from vyos.configsession import ConfigSession, ConfigSessionError -import vyos.util as util + +from vyos.configsession import ConfigSession +from vyos.util import cmd +from vyos.util import read_file base_path = ['system', 'login'] users = ['vyos1', 'vyos2'] @@ -37,7 +41,7 @@ class TestSystemLogin(unittest.TestCase): self.session.commit() del self.session - def test_user(self): + def test_local_user(self): """ Check if user can be created and we can SSH to localhost """ self.session.set(['service', 'ssh', 'port', '22']) @@ -63,5 +67,65 @@ class TestSystemLogin(unittest.TestCase): # b'Linux vyos 4.19.101-amd64-vyos #1 SMP Sun Feb 2 10:18:07 UTC 2020 x86_64 GNU/Linux\n' self.assertTrue(len(stdout) > 40) + def test_radius_kernel_features(self): + """ T2886: RADIUS requires some Kernel options to be present """ + kernel = platform.release() + kernel_config = read_file(f'/boot/config-{kernel}') + + # T2886 - RADIUS authentication - check for statically compiled + # options (=y) + for option in ['CONFIG_AUDIT', 'CONFIG_HAVE_ARCH_AUDITSYSCALL', + 'CONFIG_AUDITSYSCALL', 'CONFIG_AUDIT_WATCH', + 'CONFIG_AUDIT_TREE', 'CONFIG_AUDIT_ARCH']: + self.assertIn(f'{option}=y', kernel_config) + + def test_radius_config(self): + """ Verify generated RADIUS configuration files """ + + radius_key = 'VyOSsecretVyOS' + radius_server = '172.16.100.10' + radius_source = '127.0.0.1' + radius_port = '2000' + radius_timeout = '1' + + self.session.set(base_path + ['radius', 'server', radius_server, 'key', radius_key]) + self.session.set(base_path + ['radius', 'server', radius_server, 'port', radius_port]) + self.session.set(base_path + ['radius', 'server', radius_server, 'timeout', radius_timeout]) + self.session.set(base_path + ['radius', 'source-address', radius_source]) + + self.session.commit() + + # this file must be read with higher permissions + pam_radius_auth_conf = cmd('sudo cat /etc/pam_radius_auth.conf') + tmp = re.findall(r'\n?{}:{}\s+{}\s+{}\s+{}'.format(radius_server, + radius_port, radius_key, radius_timeout, + radius_source), pam_radius_auth_conf) + self.assertTrue(tmp) + + # required, static options + self.assertIn('priv-lvl 15', pam_radius_auth_conf) + self.assertIn('mapped_priv_user radius_priv_user', pam_radius_auth_conf) + + # PAM + pam_common_account = read_file('/etc/pam.d/common-account') + self.assertIn('pam_radius_auth.so', pam_common_account) + + pam_common_auth = read_file('/etc/pam.d/common-auth') + self.assertIn('pam_radius_auth.so', pam_common_auth) + + pam_common_session = read_file('/etc/pam.d/common-session') + self.assertIn('pam_radius_auth.so', pam_common_session) + + pam_common_session_noninteractive = read_file('/etc/pam.d/common-session-noninteractive') + self.assertIn('pam_radius_auth.so', pam_common_session_noninteractive) + + # NSS + nsswitch_conf = read_file('/etc/nsswitch.conf') + tmp = re.findall(r'passwd:\s+mapuid\s+files\s+mapname', nsswitch_conf) + self.assertTrue(tmp) + + tmp = re.findall(r'group:\s+mapname\s+files', nsswitch_conf) + self.assertTrue(tmp) + if __name__ == '__main__': unittest.main() diff --git a/smoketest/scripts/system/test_kernel_options.py b/smoketest/scripts/system/test_kernel_options.py deleted file mode 100755 index 8c96d96fb..000000000 --- a/smoketest/scripts/system/test_kernel_options.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2020 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -import os -import platform -import unittest - -kernel = platform.release() -with open(f'/boot/config-{kernel}') as f: - config = f.read() - -class TestKernelModules(unittest.TestCase): - - def test_radius_auth_t2886(self): - # T2886 - RADIUS authentication - check for statically compiled - # options (=y) - for option in ['CONFIG_AUDIT', 'CONFIG_HAVE_ARCH_AUDITSYSCALL', - 'CONFIG_AUDITSYSCALL', 'CONFIG_AUDIT_WATCH', - 'CONFIG_AUDIT_TREE', 'CONFIG_AUDIT_ARCH']: - self.assertIn(f'{option}=y', config) - -if __name__ == '__main__': - unittest.main() -- cgit v1.2.3