/usr/lib/python3/dist-packages/asyncssh/pattern.py is in python3-asyncssh 1.11.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | # Copyright (c) 2015 by Ron Frederick <ronf@timeheart.net>.
# All rights reserved.
#
# This program and the accompanying materials are made available under
# the terms of the Eclipse Public License v1.0 which accompanies this
# distribution and is available at:
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Ron Frederick - initial implementation, API, and documentation
"""Pattern matching for principal and host names"""
from fnmatch import fnmatch
from .misc import ip_network
class WildcardPattern:
"""A pattern matcher for '*' and '?' wildcards"""
def __init__(self, pattern):
# We need to escape square brackets in host patterns if we
# want to use Python's fnmatch.
self._pattern = ''.join('[[]' if ch == '[' else
'[]]' if ch == ']' else
ch for ch in pattern)
def matches(self, value):
"""Return whether a wild card pattern matches a value"""
return fnmatch(value, self._pattern)
class WildcardHostPattern(WildcardPattern):
"""Match a host name or address against a wildcard pattern"""
def matches(self, host, addr, ip):
"""Return whether a host or address matches a wild card host pattern"""
# Arguments vary by class, but inheritance is still needed here
# IP matching is only done for CIDRHostPattern
# pylint: disable=arguments-differ,unused-argument
return (host and super().matches(host)) or \
(addr and super().matches(addr))
class CIDRHostPattern:
"""Match IPv4/v6 address against CIDR-style subnet pattern"""
def __init__(self, pattern):
self._network = ip_network(pattern)
def matches(self, host, addr, ip):
"""Return whether an IP address matches a CIDR address pattern"""
# Host & addr matching is only done for WildcardHostPattern
# pylint: disable=unused-argument
return ip and ip in self._network
class _PatternList:
"""Match against a list of comma-separated positive and negative patterns
This class is a base class for building a pattern matcher that
takes a set of comma-separated positive and negative patterns,
returning ``True`` if one or more positive patterns match and
no negative ones do.
The pattern matching is done by objects returned by the
build_pattern method. The arguments passed in when a match
is performed will vary depending on what class build_pattern
returns.
"""
def __init__(self, patterns):
self._pos_patterns = []
self._neg_patterns = []
for pattern in patterns.split(','):
if pattern.startswith('!'):
negate = True
pattern = pattern[1:]
else:
negate = False
matcher = self.build_pattern(pattern)
if negate:
self._neg_patterns.append(matcher)
else:
self._pos_patterns.append(matcher)
def build_pattern(self, pattern):
"""Abstract method to build a pattern object"""
raise NotImplementedError
def matches(self, *args):
"""Match a set of values against positive & negative pattern lists"""
pos_match = any(p.matches(*args) for p in self._pos_patterns)
neg_match = any(p.matches(*args) for p in self._neg_patterns)
return pos_match and not neg_match
class WildcardPatternList(_PatternList):
"""Match names against wildcard patterns"""
def build_pattern(self, pattern):
"""Build a wild card pattern"""
return WildcardPattern(pattern)
class HostPatternList(_PatternList):
"""Match host names & addresses against wildcard and CIDR patterns"""
def build_pattern(self, pattern):
"""Build a CIDR address or wild card host pattern"""
try:
return CIDRHostPattern(pattern)
except ValueError:
return WildcardHostPattern(pattern)
|