Skip to content

PAN-OS login-banner parsing issue #750

@michalis1

Description

@michalis1

Environment

  • Python version: 3.11.11
  • netutils version: 1.15.1

Expected Behavior

section_config() may normalize the PAN-OS login banner terminator (for example, replacing the closing quote " with ^C). However, the resulting section must remain parseable by PaloAltoNetworksConfigParser.
Specifically, the parser should recognize ^C as a valid banner terminator and should not include subsequent set commands as part of the banner content. Normalization should not lead to banner parsing errors or unintended expansion of the banner section.

Observed Behavior

When extracting a PAN-OS login banner using section_config(), the returned configuration:

  • Removes the closing double quote (")
  • Appends ^C to the banner content (banner end normalization)

This transformation causes the returned section to be syntactically different from the original configuration and not parseable by PaloAltoNetworksConfigParser.
As a result, downstream calls (e.g. via diff_network_config() / feature_compliance()) raise: ValueError: Unable to parse banner end..

Example outputs from section_config():

Example 1:

config:

set deviceconfig system login-banner  "####################################################
WARNING TO UNAUTHORIZED USERS:
...
####################################################
"

section_config() returns:

set deviceconfig system login-banner "####################################################
WARNING TO UNAUTHORIZED USERS:
...
####################################################
^C

Result: The closing '"' is removed and a '^C' is added.

In this case if we run feature_compliace() for this configuration we get the following exception:

>>> compliance = feature_compliance(feature, backup_cfg, intended_cfg_2, network_os)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/opt/nautobot/lib/python3.10/site-packages/netutils/config/compliance.py", line 355, in feature_compliance
    feature_data.update(_check_configs_differences(intended_cfg, backup_cfg, network_os))
  File "/opt/nautobot/lib/python3.10/site-packages/netutils/config/compliance.py", line 81, in _check_configs_differences
    missing = diff_network_config(intended_cfg, actual_cfg, network_os)
  File "/opt/nautobot/lib/python3.10/site-packages/netutils/config/compliance.py", line 284, in diff_network_config
    compare_parser = os_parser(compare_config)
  File "/opt/nautobot/lib/python3.10/site-packages/netutils/config/parser.py", line 65, in __init__
    super(BaseSpaceConfigParser, self).__init__(config)
  File "/opt/nautobot/lib/python3.10/site-packages/netutils/config/parser.py", line 32, in __init__
    self.build_config_relationship()
  File "/opt/nautobot/lib/python3.10/site-packages/netutils/config/parser.py", line 1579, in build_config_relationship
    line = self._build_banner(line)  # type: ignore
  File "/opt/nautobot/lib/python3.10/site-packages/netutils/config/parser.py", line 1538, in _build_banner
    raise ValueError("Unable to parse banner end.")
ValueError: Unable to parse banner end.

Example 2:

config:

set deviceconfig system login-banner  "####################################################
WARNING TO UNAUTHORIZED USERS:
...
####################################################
"
set deviceconfig system ntp-servers primary-ntp-server ntp-server-address ntp.chevron.net
set deviceconfig system ntp-servers primary-ntp-server authnetication-type none

section_config() returns:

set deviceconfig system login-banner "####################################################
WARNING TO UNAUTHORIZED USERS:
...
####################################################
^C
set deviceconfig system ntp-servers primary-ntp-server ntp-server-address ntp.chevron.net
set deviceconfig system ntp-servers primary-ntp-server authnetication-type none

Result: The closing '"' is removed and the set commands that follow the banner are included in the section.

Based on the above section_config() normalizes the PAN-OS login banner by replacing the closing quote (") with a ^C terminator. As a result, the section passed to diff_network_config() is no longer the original PAN-OS quoted banner but an IOS-style banner. However, PaloAltoNetworksConfigParser does not recognize ^C as a valid banner terminator, which leads to parsing errors.
Also, because line.startswith("set") is included in PaloAltoNetworksConfigParser.is_banner_end() checks, in Example 2 the subsequent set commands are incorrectly included in the banner section.

Steps to Reproduce

Example script to reproduce the issue:

from netutils.config.parser import PaloAltoNetworksConfigParser
from netutils.config.compliance import section_config, feature_compliance, diff_network_config, _check_configs_differences
import json

intended_1 = """\
set deviceconfig system login-banner "##
xxxxx
##
"
set deviceconfig system ntp-servers primary-ntp-server ntp-server-address ntp.chevron.net
set deviceconfig system ntp-servers primary-ntp-server authentication-type none
"""

intended_2 = """\
set deviceconfig system login-banner "##
xxxxx
##
"
"""

backup = """\
"""

network_os = "paloalto_panos"
feature = {"section":['set deviceconfig system login-banner'],"ordered":False}
backup_cfg = section_config(feature, backup, network_os)

intended_cfg_1 = section_config(feature, intended_1, network_os)
print(intended_cfg_1)
compliance = feature_compliance(feature, backup_cfg, intended_cfg_1, network_os)
print(json.dumps(compliance, indent=4))

intended_cfg_2 = section_config(feature, intended_2, network_os)
print(intended_cfg_2)
compliance = feature_compliance(feature, backup_cfg, intended_cfg_2, network_os)
print(json.dumps(compliance, indent=4))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions