mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-24 03:29:28 +01:00
bots: more validation in "MODE" to prevent bad things from happening
This adds a new "allow_forceset_usermodes" attribute to protocol modules, which determines whether the IRCd allows us to force usermode changes on other servers' clients. Also, make sure our target is a valid nick/UID/channel, and that the parsed modes are not empty!
This commit is contained in:
parent
78080bde6b
commit
c5b6658200
@ -396,6 +396,9 @@ class Protocol():
|
|||||||
self.casemapping = 'rfc1459'
|
self.casemapping = 'rfc1459'
|
||||||
self.hook_map = {}
|
self.hook_map = {}
|
||||||
|
|
||||||
|
# Whether the IRCd allows forcing user mode changes on other servers' clients.
|
||||||
|
self.allow_forceset_usermodes = False
|
||||||
|
|
||||||
class FakeProto(Protocol):
|
class FakeProto(Protocol):
|
||||||
"""Dummy protocol module for testing purposes."""
|
"""Dummy protocol module for testing purposes."""
|
||||||
def handle_events(self, data):
|
def handle_events(self, data):
|
||||||
|
@ -138,30 +138,34 @@ def kick(irc, source, args):
|
|||||||
def mode(irc, source, args):
|
def mode(irc, source, args):
|
||||||
"""<source> <target> <modes>
|
"""<source> <target> <modes>
|
||||||
|
|
||||||
Admin-only. Sets modes <modes> on <target> from <source>, where <source> is either the nick of a PyLink client, or the SID of a PyLink server."""
|
Admin-only. Sets modes <modes> on <target> from <source>, where <source> is either the nick of a PyLink client, or the SID of a PyLink server. <target> can be either a nick or a channel."""
|
||||||
utils.checkAuthenticated(irc, source, allowOper=False)
|
utils.checkAuthenticated(irc, source, allowOper=False)
|
||||||
try:
|
try:
|
||||||
modesource, target, modes = args[0], args[1], args[2:]
|
modesource, target, modes = args[0], args[1], args[2:]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
irc.msg(source, 'Error: Not enough arguments. Needs 3: source nick, target, modes to set.')
|
irc.msg(source, 'Error: Not enough arguments. Needs 3: source nick, target, modes to set.')
|
||||||
return
|
return
|
||||||
if not modes:
|
target = utils.nickToUid(irc, target) or target
|
||||||
irc.msg(source, "Error: No modes given to set!")
|
if not (target in irc.users or target in irc.channels):
|
||||||
return
|
|
||||||
parsedmodes = utils.parseModes(irc, target, modes)
|
|
||||||
targetuid = utils.nickToUid(irc, target)
|
|
||||||
if targetuid:
|
|
||||||
target = targetuid
|
|
||||||
elif not utils.isChannel(target):
|
|
||||||
irc.msg(source, "Error: Invalid channel or nick %r." % target)
|
irc.msg(source, "Error: Invalid channel or nick %r." % target)
|
||||||
return
|
return
|
||||||
|
elif target in irc.users and not irc.proto.allow_forceset_usermodes:
|
||||||
|
irc.msg(source, "Error: this IRCd does not allow forcing user mode "
|
||||||
|
"changes on other servers' users!")
|
||||||
|
return
|
||||||
|
parsedmodes = utils.parseModes(irc, target, modes)
|
||||||
|
if not parsedmodes:
|
||||||
|
irc.msg(source, "Error: No valid modes were given.")
|
||||||
|
return
|
||||||
if utils.isInternalServer(irc, modesource):
|
if utils.isInternalServer(irc, modesource):
|
||||||
|
# Setting modes from a server.
|
||||||
irc.proto.modeServer(modesource, target, parsedmodes)
|
irc.proto.modeServer(modesource, target, parsedmodes)
|
||||||
irc.callHooks([modesource, 'PYLINK_BOTSPLUGIN_MODE', {'target': target, 'modes': parsedmodes, 'parse_as': 'MODE'}])
|
|
||||||
else:
|
else:
|
||||||
sourceuid = utils.nickToUid(irc, modesource)
|
# Setting modes from a client.
|
||||||
irc.proto.modeClient(sourceuid, target, parsedmodes)
|
modesource = utils.nickToUid(irc, modesource)
|
||||||
irc.callHooks([sourceuid, 'PYLINK_BOTSPLUGIN_MODE', {'target': target, 'modes': parsedmodes, 'parse_as': 'MODE'}])
|
irc.proto.modeClient(modesource, target, parsedmodes)
|
||||||
|
irc.callHooks([modesource, 'PYLINK_BOTSPLUGIN_MODE',
|
||||||
|
{'target': target, 'modes': parsedmodes, 'parse_as': 'MODE'}])
|
||||||
|
|
||||||
@utils.add_cmd
|
@utils.add_cmd
|
||||||
def msg(irc, source, args):
|
def msg(irc, source, args):
|
||||||
|
@ -27,6 +27,9 @@ class InspIRCdProtocol(TS6BaseProtocol):
|
|||||||
self.sidgen = utils.TS6SIDGenerator(self.irc.serverdata["sidrange"])
|
self.sidgen = utils.TS6SIDGenerator(self.irc.serverdata["sidrange"])
|
||||||
self.uidgen = {}
|
self.uidgen = {}
|
||||||
|
|
||||||
|
# Whether the IRCd allows forcing user mode changes on other servers' clients.
|
||||||
|
self.allow_forceset_usermodes = True
|
||||||
|
|
||||||
def spawnClient(self, nick, ident='null', host='null', realhost=None, modes=set(),
|
def spawnClient(self, nick, ident='null', host='null', realhost=None, modes=set(),
|
||||||
server=None, ip='0.0.0.0', realname=None, ts=None, opertype=None):
|
server=None, ip='0.0.0.0', realname=None, ts=None, opertype=None):
|
||||||
"""Spawns a client with nick <nick> on the given IRC connection.
|
"""Spawns a client with nick <nick> on the given IRC connection.
|
||||||
|
Loading…
Reference in New Issue
Block a user