You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.7 KiB

10 months ago
import re
def _build_regex(pattern):
regex = '^'
part_beginning = 0
while part_beginning < len(pattern):
ix1 = pattern.find('*', part_beginning)
ix2 = pattern.find('?', part_beginning)
ix1 = len(pattern) if ix1 < 0 else ix1
ix2 = len(pattern) if ix2 < 0 else ix2
part_end = min(ix1, ix2)
regex += re.escape(pattern[part_beginning:part_end])
if part_end < len(pattern):
if pattern[part_end] == '*':
regex += '.*'
else:
regex += '.'
part_beginning = part_end + 1
regex += '$'
return regex
def _pattern_matches(pattern, string):
if pattern.lower() == 'all':
return True
regex = _build_regex(pattern)
return re.match(regex, string, re.IGNORECASE) is not None
def _daemon_list_matches_daemon(daemon_list, daemon, recursion_depth):
try:
cur_list_end = daemon_list.index('except')
except ValueError:
cur_list_end = len(daemon_list)
cur_list = daemon_list[:cur_list_end]
matches_cur_list = False
for item in cur_list:
try:
ix = item.index('@')
# For simplicity, we ignore the host part. So we must make sure
# that a daemon list containing a host-based pattern will always match
# the daemon part of that host-based pattern (e.g. 'all except vsftpd@localhost
# matches 'vsftpd'). See test_config_applies_to_daemon_with_host_except().
if recursion_depth % 2 == 1:
continue
pattern = item[:ix]
except ValueError:
pattern = item
if _pattern_matches(pattern, daemon):
matches_cur_list = True
break
next_list = daemon_list[cur_list_end + 1:]
if not next_list:
matches_next_list = False
else:
matches_next_list = _daemon_list_matches_daemon(next_list, daemon, recursion_depth + 1)
return matches_cur_list and not matches_next_list
def config_applies_to_daemon(facts, daemon):
"""
Returns True if the specified tcp_wrappers configuration applies to the specified daemon.
Otherwise returns False.
This information is intended to be used in the Checks phase to check whether there is
any tcp_wrappers configuration that the user needs to migrate manually and whether we
should inhibit the upgrade, so that the upgraded system is not insecure.
:param facts: A TcpWrappersFacts representation of the tcp_wrappers configuration
:param daemon: The daemon name
"""
for daemon_list in facts.daemon_lists:
value = [item.lower() for item in daemon_list.value]
if _daemon_list_matches_daemon(value, daemon, 0):
return True
return False