diff options
Diffstat (limited to 'src/op_mode')
-rwxr-xr-x | src/op_mode/bridge.py | 43 | ||||
-rwxr-xr-x | src/op_mode/dhcp.py | 96 | ||||
-rwxr-xr-x | src/op_mode/firewall.py | 223 | ||||
-rwxr-xr-x | src/op_mode/pki.py | 20 | ||||
-rwxr-xr-x | src/op_mode/show_openconnect_otp.py | 38 | ||||
-rw-r--r-- | src/op_mode/show_techsupport_report.py | 3 | ||||
-rwxr-xr-x | src/op_mode/webproxy_update_blacklist.sh | 9 |
7 files changed, 283 insertions, 149 deletions
diff --git a/src/op_mode/bridge.py b/src/op_mode/bridge.py index 1834b9cc9..185db4f20 100755 --- a/src/op_mode/bridge.py +++ b/src/op_mode/bridge.py @@ -29,7 +29,6 @@ from vyos.utils.dict import dict_search import vyos.opmode - def _get_json_data(): """ Get bridge data format JSON @@ -46,11 +45,14 @@ def _get_raw_data_summary(): return data_dict -def _get_raw_data_vlan(): +def _get_raw_data_vlan(tunnel:bool=False): """ :returns dict """ - json_data = cmd('bridge --json --compressvlans vlan show') + show = 'show' + if tunnel: + show = 'tunnel' + json_data = cmd(f'bridge --json --compressvlans vlan {show}') data_dict = json.loads(json_data) return data_dict @@ -134,10 +136,34 @@ def _get_formatted_output_vlan(data): flags = ', '.join(flags_raw if isinstance(flags_raw,list) else "").lower() data_entries.append([interface, vlan, flags]) - headers = ["Interface", "Vlan", "Flags"] + headers = ["Interface", "VLAN", "Flags"] output = tabulate(data_entries, headers) return output +def _get_formatted_output_vlan_tunnel(data): + data_entries = [] + for entry in data: + interface = entry.get('ifname') + first = True + for tunnel_entry in entry.get('tunnels'): + vlan = tunnel_entry.get('vlan') + vni = tunnel_entry.get('tunid') + if first: + data_entries.append([interface, vlan, vni]) + first = False + else: + # Group by VXLAN interface only - no need to repeat + # VXLAN interface name for every VLAN <-> VNI mapping + # + # Interface VLAN VNI + # ----------- ------ ----- + # vxlan0 100 100 + # 200 200 + data_entries.append(['', vlan, vni]) + + headers = ["Interface", "VLAN", "VNI"] + output = tabulate(data_entries, headers) + return output def _get_formatted_output_fdb(data): data_entries = [] @@ -192,12 +218,15 @@ def show(raw: bool): return _get_formatted_output_summary(bridge_data) -def show_vlan(raw: bool): - bridge_vlan = _get_raw_data_vlan() +def show_vlan(raw: bool, tunnel: typing.Optional[bool]): + bridge_vlan = _get_raw_data_vlan(tunnel) if raw: return bridge_vlan else: - return _get_formatted_output_vlan(bridge_vlan) + if tunnel: + return _get_formatted_output_vlan_tunnel(bridge_vlan) + else: + return _get_formatted_output_vlan(bridge_vlan) def show_fdb(raw: bool, interface: str): diff --git a/src/op_mode/dhcp.py b/src/op_mode/dhcp.py index 3e51e990b..f558c18b7 100755 --- a/src/op_mode/dhcp.py +++ b/src/op_mode/dhcp.py @@ -14,10 +14,12 @@ # 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 sys import typing from datetime import datetime +from glob import glob from ipaddress import ip_address from isc_dhcp_leases import IscDhcpLeases from tabulate import tabulate @@ -27,10 +29,13 @@ import vyos.opmode from vyos.base import Warning from vyos.configquery import ConfigTreeQuery -from vyos.utils.process import cmd from vyos.utils.dict import dict_search +from vyos.utils.file import read_file +from vyos.utils.process import cmd from vyos.utils.process import is_systemd_service_running +time_string = "%a %b %d %H:%M:%S %Z %Y" + config = ConfigTreeQuery() lease_valid_states = ['all', 'active', 'free', 'expired', 'released', 'abandoned', 'reset', 'backup'] sort_valid_inet = ['end', 'mac', 'hostname', 'ip', 'pool', 'remaining', 'start', 'state'] @@ -287,6 +292,95 @@ def show_server_leases(raw: bool, family: ArgFamily, pool: typing.Optional[str], return _get_formatted_server_leases(lease_data, family=family) +def _get_raw_client_leases(family='inet', interface=None): + from time import mktime + from datetime import datetime + from vyos.defaults import directories + from vyos.utils.network import get_interface_vrf + + lease_dir = directories['isc_dhclient_dir'] + lease_files = [] + lease_data = [] + + if interface: + tmp = f'{lease_dir}/dhclient_{interface}.lease' + if os.path.exists(tmp): + lease_files.append(tmp) + else: + # All DHCP leases + lease_files = glob(f'{lease_dir}/dhclient_*.lease') + + for lease in lease_files: + tmp = {} + with open(lease, 'r') as f: + for line in f.readlines(): + line = line.rstrip() + if 'last_update' not in tmp: + # ISC dhcp client contains least_update timestamp in human readable + # format this makes less sense for an API and also the expiry + # timestamp is provided in UNIX time. Convert string (e.g. Sun Jul + # 30 18:13:44 CEST 2023) to UNIX time (1690733624) + tmp.update({'last_update' : int(mktime(datetime.strptime(line, time_string).timetuple()))}) + continue + + k, v = line.split('=') + tmp.update({k : v.replace("'", "")}) + + if 'interface' in tmp: + vrf = get_interface_vrf(tmp['interface']) + if vrf: tmp.update({'vrf' : vrf}) + + lease_data.append(tmp) + + return lease_data + +def _get_formatted_client_leases(lease_data, family): + from time import localtime + from time import strftime + + from vyos.validate import is_intf_addr_assigned + + data_entries = [] + for lease in lease_data: + data_entries.append(["Interface", lease['interface']]) + if 'new_ip_address' in lease: + tmp = '[Active]' if is_intf_addr_assigned(lease['interface'], lease['new_ip_address']) else '[Inactive]' + data_entries.append(["IP address", lease['new_ip_address'], tmp]) + if 'new_subnet_mask' in lease: + data_entries.append(["Subnet Mask", lease['new_subnet_mask']]) + if 'new_domain_name' in lease: + data_entries.append(["Domain Name", lease['new_domain_name']]) + if 'new_routers' in lease: + data_entries.append(["Router", lease['new_routers']]) + if 'new_domain_name_servers' in lease: + data_entries.append(["Name Server", lease['new_domain_name_servers']]) + if 'new_dhcp_server_identifier' in lease: + data_entries.append(["DHCP Server", lease['new_dhcp_server_identifier']]) + if 'new_dhcp_lease_time' in lease: + data_entries.append(["DHCP Server", lease['new_dhcp_lease_time']]) + if 'vrf' in lease: + data_entries.append(["VRF", lease['vrf']]) + if 'last_update' in lease: + tmp = strftime(time_string, localtime(int(lease['last_update']))) + data_entries.append(["Last Update", tmp]) + if 'new_expiry' in lease: + tmp = strftime(time_string, localtime(int(lease['new_expiry']))) + data_entries.append(["Expiry", tmp]) + + # Add empty marker + data_entries.append(['']) + + output = tabulate(data_entries, tablefmt='plain') + + return output + +def show_client_leases(raw: bool, family: ArgFamily, interface: typing.Optional[str]): + lease_data = _get_raw_client_leases(family=family, interface=interface) + if raw: + return lease_data + else: + return _get_formatted_client_leases(lease_data, family=family) + if __name__ == '__main__': try: res = vyos.opmode.run(sys.modules[__name__]) diff --git a/src/op_mode/firewall.py b/src/op_mode/firewall.py index 8260bbb77..852a7248a 100755 --- a/src/op_mode/firewall.py +++ b/src/op_mode/firewall.py @@ -24,62 +24,27 @@ from vyos.config import Config from vyos.utils.process import cmd from vyos.utils.dict import dict_search_args -def get_firewall_interfaces(firewall, name=None, ipv6=False): - directions = ['in', 'out', 'local'] - - if 'interface' in firewall: - for ifname, if_conf in firewall['interface'].items(): - for direction in directions: - if direction not in if_conf: - continue - - fw_conf = if_conf[direction] - name_str = f'({ifname},{direction})' - - if 'name' in fw_conf: - fw_name = fw_conf['name'] - - if not name: - firewall['name'][fw_name]['interface'].append(name_str) - elif not ipv6 and name == fw_name: - firewall['interface'].append(name_str) - - if 'ipv6_name' in fw_conf: - fw_name = fw_conf['ipv6_name'] - - if not name: - firewall['ipv6_name'][fw_name]['interface'].append(name_str) - elif ipv6 and name == fw_name: - firewall['interface'].append(name_str) - - return firewall - -def get_config_firewall(conf, name=None, ipv6=False, interfaces=True): +def get_config_firewall(conf, hook=None, priority=None, ipv6=False, interfaces=True): config_path = ['firewall'] - if name: - config_path += ['ipv6-name' if ipv6 else 'name', name] + if hook: + config_path += ['ipv6' if ipv6 else 'ipv4', hook] + if priority: + config_path += [priority] firewall = conf.get_config_dict(config_path, key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True) - if firewall and interfaces: - if name: - firewall['interface'] = {} - else: - if 'name' in firewall: - for fw_name, name_conf in firewall['name'].items(): - name_conf['interface'] = [] - if 'ipv6_name' in firewall: - for fw_name, name_conf in firewall['ipv6_name'].items(): - name_conf['interface'] = [] - - get_firewall_interfaces(firewall, name, ipv6) return firewall -def get_nftables_details(name, ipv6=False): +def get_nftables_details(hook, priority, ipv6=False): suffix = '6' if ipv6 else '' name_prefix = 'NAME6_' if ipv6 else 'NAME_' - command = f'sudo nft list chain ip{suffix} vyos_filter {name_prefix}{name}' + if hook == 'name' or hook == 'ipv6-name': + command = f'sudo nft list chain ip{suffix} vyos_filter {name_prefix}{priority}' + else: + up_hook = hook.upper() + command = f'sudo nft list chain ip{suffix} vyos_filter VYOS_{up_hook}_{priority}' + try: results = cmd(command) except: @@ -87,7 +52,7 @@ def get_nftables_details(name, ipv6=False): out = {} for line in results.split('\n'): - comment_search = re.search(rf'{name}[\- ](\d+|default-action)', line) + comment_search = re.search(rf'{priority}[\- ](\d+|default-action)', line) if not comment_search: continue @@ -102,18 +67,15 @@ def get_nftables_details(name, ipv6=False): out[rule_id] = rule return out -def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None): +def output_firewall_name(hook, priority, firewall_conf, ipv6=False, single_rule_id=None): ip_str = 'IPv6' if ipv6 else 'IPv4' - print(f'\n---------------------------------\n{ip_str} Firewall "{name}"\n') - - if name_conf['interface']: - print('Active on: {0}\n'.format(" ".join(name_conf['interface']))) + print(f'\n---------------------------------\n{ip_str} Firewall "{hook} {priority}"\n') - details = get_nftables_details(name, ipv6) + details = get_nftables_details(hook, priority, ipv6) rows = [] - if 'rule' in name_conf: - for rule_id, rule_conf in name_conf['rule'].items(): + if 'rule' in firewall_conf: + for rule_id, rule_conf in firewall_conf['rule'].items(): if single_rule_id and rule_id != single_rule_id: continue @@ -128,8 +90,8 @@ def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None): row.append(rule_details['conditions']) rows.append(row) - if 'default_action' in name_conf and not single_rule_id: - row = ['default', name_conf['default_action'], 'all'] + if 'default_action' in firewall_conf and not single_rule_id: + row = ['default', firewall_conf['default_action'], 'all'] if 'default-action' in details: rule_details = details['default-action'] row.append(rule_details.get('packets', 0)) @@ -140,18 +102,15 @@ def output_firewall_name(name, name_conf, ipv6=False, single_rule_id=None): header = ['Rule', 'Action', 'Protocol', 'Packets', 'Bytes', 'Conditions'] print(tabulate.tabulate(rows, header) + '\n') -def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id=None): +def output_firewall_name_statistics(hook, prior, prior_conf, ipv6=False, single_rule_id=None): ip_str = 'IPv6' if ipv6 else 'IPv4' - print(f'\n---------------------------------\n{ip_str} Firewall "{name}"\n') + print(f'\n---------------------------------\n{ip_str} Firewall "{hook} {prior}"\n') - if name_conf['interface']: - print('Active on: {0}\n'.format(" ".join(name_conf['interface']))) - - details = get_nftables_details(name, ipv6) + details = get_nftables_details(prior, ipv6) rows = [] - if 'rule' in name_conf: - for rule_id, rule_conf in name_conf['rule'].items(): + if 'rule' in prior_conf: + for rule_id, rule_conf in prior_conf['rule'].items(): if single_rule_id and rule_id != single_rule_id: continue @@ -174,7 +133,7 @@ def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id= row.append(dest_addr) rows.append(row) - if 'default_action' in name_conf and not single_rule_id: + if 'default_action' in prior_conf and not single_rule_id: row = ['default'] if 'default-action' in details: rule_details = details['default-action'] @@ -183,7 +142,7 @@ def output_firewall_name_statistics(name, name_conf, ipv6=False, single_rule_id= else: row.append('0') row.append('0') - row.append(name_conf['default_action']) + row.append(prior_conf['default_action']) row.append('0.0.0.0/0') # Source row.append('0.0.0.0/0') # Dest rows.append(row) @@ -201,29 +160,47 @@ def show_firewall(): if not firewall: return - if 'name' in firewall: - for name, name_conf in firewall['name'].items(): - output_firewall_name(name, name_conf, ipv6=False) + if 'ipv4' in firewall: + for hook, hook_conf in firewall['ipv4'].items(): + for prior, prior_conf in firewall['ipv4'][hook].items(): + output_firewall_name(hook, prior, prior_conf, ipv6=False) + + if 'ipv6' in firewall: + for hook, hook_conf in firewall['ipv6'].items(): + for prior, prior_conf in firewall['ipv6'][hook].items(): + output_firewall_name(hook, prior, prior_conf, ipv6=True) - if 'ipv6_name' in firewall: - for name, name_conf in firewall['ipv6_name'].items(): - output_firewall_name(name, name_conf, ipv6=True) +def show_firewall_family(family): + print(f'Rulesets {family} Information') -def show_firewall_name(name, ipv6=False): + conf = Config() + firewall = get_config_firewall(conf) + + if not firewall: + return + + for hook, hook_conf in firewall[family].items(): + for prior, prior_conf in firewall[family][hook].items(): + if family == 'ipv6': + output_firewall_name(hook, prior, prior_conf, ipv6=True) + else: + output_firewall_name(hook, prior, prior_conf, ipv6=False) + +def show_firewall_name(hook, priority, ipv6=False): print('Ruleset Information') conf = Config() - firewall = get_config_firewall(conf, name, ipv6) + firewall = get_config_firewall(conf, hook, priority, ipv6) if firewall: - output_firewall_name(name, firewall, ipv6) + output_firewall_name(hook, priority, firewall, ipv6) -def show_firewall_rule(name, rule_id, ipv6=False): +def show_firewall_rule(hook, priority, rule_id, ipv6=False): print('Rule Information') conf = Config() - firewall = get_config_firewall(conf, name, ipv6) + firewall = get_config_firewall(conf, hook, priority, ipv6) if firewall: - output_firewall_name(name, firewall, ipv6, rule_id) + output_firewall_name(hook, priority, firewall, ipv6, rule_id) def show_firewall_group(name=None): conf = Config() @@ -234,19 +211,32 @@ def show_firewall_group(name=None): def find_references(group_type, group_name): out = [] - for name_type in ['name', 'ipv6_name']: - if name_type not in firewall: - continue - for name, name_conf in firewall[name_type].items(): - if 'rule' not in name_conf: + family = [] + if group_type in ['address_group', 'network_group']: + family = ['ipv4'] + elif group_type == 'ipv6_address_group': + family = ['ipv6'] + group_type = 'address_group' + elif group_type == 'ipv6_network_group': + family = ['ipv6'] + group_type = 'network_group' + else: + family = ['ipv4', 'ipv6'] + + for item in family: + for name_type in ['name', 'ipv6_name', 'forward', 'input', 'output']: + if name_type not in firewall[item]: continue - for rule_id, rule_conf in name_conf['rule'].items(): - source_group = dict_search_args(rule_conf, 'source', 'group', group_type) - dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type) - if source_group and group_name == source_group: - out.append(f'{name}-{rule_id}') - elif dest_group and group_name == dest_group: - out.append(f'{name}-{rule_id}') + for name, name_conf in firewall[item][name_type].items(): + if 'rule' not in name_conf: + continue + for rule_id, rule_conf in name_conf['rule'].items(): + source_group = dict_search_args(rule_conf, 'source', 'group', group_type) + dest_group = dict_search_args(rule_conf, 'destination', 'group', group_type) + if source_group and group_name == source_group: + out.append(f'{name}-{rule_id}') + elif dest_group and group_name == dest_group: + out.append(f'{name}-{rule_id}') return out header = ['Name', 'Type', 'References', 'Members'] @@ -284,28 +274,28 @@ def show_summary(): if not firewall: return - header = ['Ruleset Name', 'Description', 'References'] + header = ['Ruleset Hook', 'Ruleset Priority', 'Description', 'References'] v4_out = [] v6_out = [] - if 'name' in firewall: - for name, name_conf in firewall['name'].items(): - description = name_conf.get('description', '') - interfaces = ", ".join(name_conf['interface']) - v4_out.append([name, description, interfaces]) + if 'ipv4' in firewall: + for hook, hook_conf in firewall['ipv4'].items(): + for prior, prior_conf in firewall['ipv4'][hook].items(): + description = prior_conf.get('description', '') + v4_out.append([hook, prior, description]) - if 'ipv6_name' in firewall: - for name, name_conf in firewall['ipv6_name'].items(): - description = name_conf.get('description', '') - interfaces = ", ".join(name_conf['interface']) - v6_out.append([name, description, interfaces or 'N/A']) + if 'ipv6' in firewall: + for hook, hook_conf in firewall['ipv6'].items(): + for prior, prior_conf in firewall['ipv6'][hook].items(): + description = prior_conf.get('description', '') + v6_out.append([hook, prior, description]) if v6_out: - print('\nIPv6 name:\n') + print('\nIPv6 Ruleset:\n') print(tabulate.tabulate(v6_out, header) + '\n') if v4_out: - print('\nIPv4 name:\n') + print('\nIPv4 Ruleset:\n') print(tabulate.tabulate(v4_out, header) + '\n') show_firewall_group() @@ -319,18 +309,23 @@ def show_statistics(): if not firewall: return - if 'name' in firewall: - for name, name_conf in firewall['name'].items(): - output_firewall_name_statistics(name, name_conf, ipv6=False) + if 'ipv4' in firewall: + for hook, hook_conf in firewall['ipv4'].items(): + for prior, prior_conf in firewall['ipv4'][hook].items(): + output_firewall_name_statistics(hook,prior, prior_conf, ipv6=False) - if 'ipv6_name' in firewall: - for name, name_conf in firewall['ipv6_name'].items(): - output_firewall_name_statistics(name, name_conf, ipv6=True) + if 'ipv6' in firewall: + for hook, hook_conf in firewall['ipv6'].items(): + for prior, prior_conf in firewall['ipv6'][hook].items(): + output_firewall_name_statistics(hook,prior, prior_conf, ipv6=True) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--action', help='Action', required=False) parser.add_argument('--name', help='Firewall name', required=False, action='store', nargs='?', default='') + parser.add_argument('--family', help='IP family', required=False, action='store', nargs='?', default='') + parser.add_argument('--hook', help='Firewall hook', required=False, action='store', nargs='?', default='') + parser.add_argument('--priority', help='Firewall priority', required=False, action='store', nargs='?', default='') parser.add_argument('--rule', help='Firewall Rule ID', required=False) parser.add_argument('--ipv6', help='IPv6 toggle', action='store_true') @@ -338,11 +333,13 @@ if __name__ == '__main__': if args.action == 'show': if not args.rule: - show_firewall_name(args.name, args.ipv6) + show_firewall_name(args.hook, args.priority, args.ipv6) else: - show_firewall_rule(args.name, args.rule, args.ipv6) + show_firewall_rule(args.hook, args.priority, args.rule, args.ipv6) elif args.action == 'show_all': show_firewall() + elif args.action == 'show_family': + show_firewall_family(args.family) elif args.action == 'show_group': show_firewall_group(args.name) elif args.action == 'show_statistics': diff --git a/src/op_mode/pki.py b/src/op_mode/pki.py index 4c31291ad..aff4ad1ae 100755 --- a/src/op_mode/pki.py +++ b/src/op_mode/pki.py @@ -26,8 +26,8 @@ from cryptography.x509.oid import ExtendedKeyUsageOID from vyos.config import Config from vyos.configquery import ConfigTreeQuery -from vyos.configdict import dict_merge from vyos.pki import encode_certificate, encode_public_key, encode_private_key, encode_dh_parameters +from vyos.pki import get_certificate_fingerprint from vyos.pki import create_certificate, create_certificate_request, create_certificate_revocation_list from vyos.pki import create_private_key from vyos.pki import create_dh_parameters @@ -38,7 +38,6 @@ from vyos.utils.io import ask_input from vyos.utils.io import ask_yes_no from vyos.utils.misc import install_into_config from vyos.utils.process import cmd -from vyos.xml import defaults CERT_REQ_END = '-----END CERTIFICATE REQUEST-----' auth_dir = '/config/auth' @@ -49,10 +48,9 @@ def get_default_values(): # Fetch default x509 values base = ['pki', 'x509', 'default'] x509_defaults = conf.get_config_dict(base, key_mangling=('-', '_'), + no_tag_node_value_mangle=True, get_first_key=True, - no_tag_node_value_mangle=True) - default_values = defaults(base) - x509_defaults = dict_merge(default_values, x509_defaults) + with_recursive_defaults=True) return x509_defaults @@ -916,6 +914,12 @@ def show_certificate(name=None, pem=False): print("Certificates:") print(tabulate.tabulate(data, headers)) +def show_certificate_fingerprint(name, hash): + cert = get_config_certificate(name=name) + cert = load_certificate(cert['certificate']) + + print(get_certificate_fingerprint(cert, hash)) + def show_crl(name=None, pem=False): headers = ['CA Name', 'Updated', 'Revokes'] data = [] @@ -961,6 +965,7 @@ if __name__ == '__main__': parser.add_argument('--sign', help='Sign certificate with specified CA', required=False) parser.add_argument('--self-sign', help='Self-sign the certificate', action='store_true') parser.add_argument('--pem', help='Output using PEM encoding', action='store_true') + parser.add_argument('--fingerprint', help='Show fingerprint and exit', action='store') # SSH parser.add_argument('--ssh', help='SSH Key', required=False) @@ -1057,7 +1062,10 @@ if __name__ == '__main__': if not conf.exists(['pki', 'certificate', cert_name]): print(f'Certificate "{cert_name}" does not exist!') exit(1) - show_certificate(None if args.certificate == 'all' else args.certificate, args.pem) + if args.fingerprint is None: + show_certificate(None if args.certificate == 'all' else args.certificate, args.pem) + else: + show_certificate_fingerprint(args.certificate, args.fingerprint) elif args.crl: show_crl(None if args.crl == 'all' else args.crl, args.pem) else: diff --git a/src/op_mode/show_openconnect_otp.py b/src/op_mode/show_openconnect_otp.py index 415a5f72c..3771fb385 100755 --- a/src/op_mode/show_openconnect_otp.py +++ b/src/op_mode/show_openconnect_otp.py @@ -17,12 +17,11 @@ import argparse import os +from base64 import b32encode from vyos.config import Config -from vyos.xml import defaults -from vyos.configdict import dict_merge +from vyos.utils.dict import dict_search_args from vyos.utils.process import popen -from base64 import b32encode otp_file = '/run/ocserv/users.oath' @@ -33,7 +32,7 @@ def check_uname_otp(username): config = Config() base_key = ['vpn', 'openconnect', 'authentication', 'local-users', 'username', username, 'otp', 'key'] if not config.exists(base_key): - return None + return False return True def get_otp_ocserv(username): @@ -41,21 +40,21 @@ def get_otp_ocserv(username): base = ['vpn', 'openconnect'] if not config.exists(base): return None - ocserv = config.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) - # We have gathered the dict representation of the CLI, but there are default - # options which we need to update into the dictionary retrived. - default_values = defaults(base) - ocserv = dict_merge(default_values, ocserv) - # workaround a "know limitation" - https://vyos.dev/T2665 - del ocserv['authentication']['local_users']['username']['otp'] - if not ocserv["authentication"]["local_users"]["username"]: + + ocserv = config.get_config_dict(base, key_mangling=('-', '_'), + get_first_key=True, + with_recursive_defaults=True) + + user_path = ['authentication', 'local_users', 'username'] + users = dict_search_args(ocserv, *user_path) + + if users is None: return None - default_ocserv_usr_values = default_values['authentication']['local_users']['username']['otp'] - for user, params in ocserv['authentication']['local_users']['username'].items(): - # Not every configuration requires OTP settings - if ocserv['authentication']['local_users']['username'][user].get('otp'): - ocserv['authentication']['local_users']['username'][user]['otp'] = dict_merge(default_ocserv_usr_values, ocserv['authentication']['local_users']['username'][user]['otp']) - result = ocserv['authentication']['local_users']['username'][username] + + # function is called conditionally, if check_uname_otp true, so username + # exists + result = users[username] + return result def display_otp_ocserv(username, params, info): @@ -101,8 +100,7 @@ if __name__ == '__main__': parser.add_argument('--info', action="store", type=str, default='full', help='Wich information to display') args = parser.parse_args() - check_otp = check_uname_otp(args.user) - if check_otp: + if check_uname_otp(args.user): user_otp_params = get_otp_ocserv(args.user) display_otp_ocserv(args.user, user_otp_params, args.info) else: diff --git a/src/op_mode/show_techsupport_report.py b/src/op_mode/show_techsupport_report.py index d27221e54..53144fd52 100644 --- a/src/op_mode/show_techsupport_report.py +++ b/src/op_mode/show_techsupport_report.py @@ -91,7 +91,8 @@ def show_package_repository_config() -> None: def show_user_startup_scripts() -> None: """Prints the user startup scripts.""" - execute_command('cat /config/scripts/vyos-postconfig-bootup.script', 'User Startup Scripts') + execute_command('cat /config/scripts/vyos-preconfig-bootup.script', 'User Startup Scripts (Preconfig)') + execute_command('cat /config/scripts/vyos-postconfig-bootup.script', 'User Startup Scripts (Postconfig)') def show_frr_config() -> None: diff --git a/src/op_mode/webproxy_update_blacklist.sh b/src/op_mode/webproxy_update_blacklist.sh index 4fb9a54c6..05ea86f9e 100755 --- a/src/op_mode/webproxy_update_blacklist.sh +++ b/src/op_mode/webproxy_update_blacklist.sh @@ -45,6 +45,9 @@ do --auto-update-blacklist) auto="yes" ;; + --vrf) + vrf="yes" + ;; (-*) echo "$0: error - unrecognized option $1" 1>&2; exit 1;; (*) break;; esac @@ -76,7 +79,11 @@ fi if [[ -n $update ]] && [[ $update -eq "yes" ]]; then tmp_blacklists='/tmp/blacklists.gz' - curl -o $tmp_blacklists $blacklist_url + if [[ -n $vrf ]] && [[ $vrf -eq "yes" ]]; then + sudo ip vrf exec $1 curl -o $tmp_blacklists $blacklist_url + else + curl -o $tmp_blacklists $blacklist_url + fi if [ $? -ne 0 ]; then echo "Unable to download [$blacklist_url]!" exit 1 |