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

networks.remote: add recursion checks to prevent bad queries from crashing the server

For example, 'remote net1 remote net2 echo hi' was problematic if the source network was 'net1'.

It's a good thing this command is restricted by default...
This commit is contained in:
James Lu 2017-03-31 16:40:26 -07:00
parent 9d9b01839c
commit 0749a42ef6

View File

@ -1,11 +1,14 @@
"""Networks plugin - allows you to manipulate connections to various configured networks.""" """Networks plugin - allows you to manipulate connections to various configured networks."""
import importlib import importlib
import types import types
import threading
from pylinkirc import utils, world, conf, classes from pylinkirc import utils, world, conf, classes
from pylinkirc.log import log from pylinkirc.log import log
from pylinkirc.coremods import control, permissions from pylinkirc.coremods import control, permissions
REMOTE_IN_USE = threading.Event()
@utils.add_cmd @utils.add_cmd
def disconnect(irc, source, args): def disconnect(irc, source, args):
"""<network> """<network>
@ -65,20 +68,30 @@ def remote(irc, source, args):
args = remote_parser.parse_args(args) args = remote_parser.parse_args(args)
netname = args.network netname = args.network
# XXX: things like 'remote network1 remote network2 echo hi' will crash PyLink if the source network is network1...
global REMOTE_IN_USE
if REMOTE_IN_USE.is_set():
irc.error("The 'remote' command can not be nested.")
return
REMOTE_IN_USE.set()
if netname == irc.name: if netname == irc.name:
# This would actually throw _remote_reply() into a loop, so check for it here... # This would actually throw _remote_reply() into a loop, so check for it here...
# XXX: properly fix this. # XXX: properly fix this.
irc.error("Cannot remote-send a command to the local network; use a normal command!") irc.error("Cannot remote-send a command to the local network; use a normal command!")
REMOTE_IN_USE.clear()
return return
try: try:
remoteirc = world.networkobjects[netname] remoteirc = world.networkobjects[netname]
except KeyError: # Unknown network. except KeyError: # Unknown network.
irc.error('No such network "%s" (case sensitive).' % netname) irc.error('No such network "%s" (case sensitive).' % netname)
REMOTE_IN_USE.clear()
return return
if args.service not in world.services: if args.service not in world.services:
irc.error('Unknown service %r.' % args.service) irc.error('Unknown service %r.' % args.service)
REMOTE_IN_USE.clear()
return return
# Force remoteirc.called_in to something private in order to prevent # Force remoteirc.called_in to something private in order to prevent
@ -118,6 +131,7 @@ def remote(irc, source, args):
remoteirc._reply = old_reply remoteirc._reply = old_reply
# Remove the identification override after we finish. # Remove the identification override after we finish.
remoteirc.pseudoclient.account = '' remoteirc.pseudoclient.account = ''
REMOTE_IN_USE.clear()
@utils.add_cmd @utils.add_cmd
def reloadproto(irc, source, args): def reloadproto(irc, source, args):