3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-01 01:09:22 +01:00

matchHost: extend negation via "!" to regular hostmasks as well as exttargets

This commit is contained in:
James Lu 2017-05-04 19:04:03 -07:00
parent d51c399351
commit 5d629f7331

View File

@ -1162,65 +1162,78 @@ class Irc(utils.DeprecatedAttributesObject):
# Try to convert target into a UID. If this fails, it's probably a hostname. # Try to convert target into a UID. If this fails, it's probably a hostname.
target = self.nickToUid(target) or target target = self.nickToUid(target) or target
# Prepare a list of hosts to check against. # Allow queries like !$exttarget to invert the given match.
if target in self.users: invert = glob.startswith('!')
if glob.startswith(('$', '!$')): if invert:
# !$exttarget inverts the given match. glob = glob.lstrip('!')
invert = glob.startswith('!$')
# Exttargets start with $. Skip regular ban matching and find the matching ban handler. def match_host_core():
glob = glob.lstrip('$!') """
exttargetname = glob.split(':', 1)[0] Core processor for matchHost(), minus the inversion check.
handler = world.exttarget_handlers.get(exttargetname) """
# Work with variables in the matchHost() scope, from
# http://stackoverflow.com/a/8178808
nonlocal glob
if handler: # Prepare a list of hosts to check against.
# Handler exists. Return what it finds. if target in self.users:
result = handler(self, glob, target) if glob.startswith('$'):
log.debug('(%s) Got %s from exttarget %s in matchHost() glob $%s for target %s', # Exttargets start with $. Skip regular ban matching and find the matching ban handler.
self.name, result, exttargetname, glob, target) glob = glob.lstrip('$')
if invert: # Anti-exttarget was specified. exttargetname = glob.split(':', 1)[0]
result = not result handler = world.exttarget_handlers.get(exttargetname)
return result
else:
log.debug('(%s) Unknown exttarget %s in matchHost() glob $%s', self.name,
exttargetname, glob)
return False
hosts = {self.getHostmask(target)} if handler:
# Handler exists. Return what it finds.
result = handler(self, glob, target)
log.debug('(%s) Got %s from exttarget %s in matchHost() glob $%s for target %s',
self.name, result, exttargetname, glob, target)
return result
else:
log.debug('(%s) Unknown exttarget %s in matchHost() glob $%s', self.name,
exttargetname, glob)
return False
if ip: hosts = {self.getHostmask(target)}
hosts.add(self.getHostmask(target, ip=True))
# HACK: support CIDR hosts in the hosts portion if ip:
try: hosts.add(self.getHostmask(target, ip=True))
header, cidrtarget = glob.split('@', 1)
log.debug('(%s) Processing CIDRs for %s (full host: %s)', self.name,
cidrtarget, glob)
# Try to parse the host portion as a CIDR range
network = ipaddress.ip_network(cidrtarget)
log.debug('(%s) Found CIDR for %s, replacing target host with IP %s', self.name, # HACK: support CIDR hosts in the hosts portion
realhost, target) try:
real_ip = self.users[target].ip header, cidrtarget = glob.split('@', 1)
if ipaddress.ip_address(real_ip) in network: log.debug('(%s) Processing CIDRs for %s (full host: %s)', self.name,
# If the CIDR matches, hack around the host matcher by pretending that cidrtarget, glob)
# the lookup target was the IP and not the CIDR range! # Try to parse the host portion as a CIDR range
glob = '@'.join((header, real_ip)) network = ipaddress.ip_network(cidrtarget)
except ValueError:
pass
if realhost: log.debug('(%s) Found CIDR for %s, replacing target host with IP %s', self.name,
hosts.add(self.getHostmask(target, realhost=True)) realhost, target)
real_ip = self.users[target].ip
if ipaddress.ip_address(real_ip) in network:
# If the CIDR matches, hack around the host matcher by pretending that
# the lookup target was the IP and not the CIDR range!
glob = '@'.join((header, real_ip))
except ValueError:
pass
else: # We were given a host, use that. if realhost:
hosts = [target] hosts.add(self.getHostmask(target, realhost=True))
# Iterate over the hosts to match using ircmatch. else: # We were given a host, use that.
for host in hosts: hosts = [target]
if ircmatch.match(casemapping, glob, host):
return True
return False # Iterate over the hosts to match using ircmatch.
for host in hosts:
if ircmatch.match(casemapping, glob, host):
return True
return False
result = match_host_core()
if invert:
result = not result
return result
class IrcUser(): class IrcUser():
"""PyLink IRC user class.""" """PyLink IRC user class."""