3
0
mirror of https://github.com/jlu5/PyLink.git synced 2025-04-25 17:27:55 +02:00

protocols: split things common between nefarious and ts6_common into a new ircs2s_common module

This commit is contained in:
James Lu 2016-07-05 00:24:23 -07:00
parent 26f4a9c276
commit bfa69815b4
3 changed files with 89 additions and 115 deletions

View File

@ -0,0 +1,82 @@
"""
ircs2s_common.py: Common base protocol class with functions shared by TS6 and P10-based protocols.
"""
from pylinkirc.classes import Protocol
from pylinkirc.log import log
class IRCS2SProtocol(Protocol):
def handle_kill(self, source, command, args):
"""Handles incoming KILLs."""
killed = args[0]
# Depending on whether the IRCd sends explicit QUIT messages for
# killed clients, the user may or may not have automatically been
# removed from our user list.
# If not, we have to assume that KILL = QUIT and remove them
# ourselves.
data = self.irc.users.get(killed)
if data:
self.removeClient(killed)
# TS6-style kills look something like this:
# <- :GL KILL 38QAAAAAA :hidden-1C620195!GL (test)
# What we actually want is to format a pretty kill message, in the form
# "Killed (killername (reason))".
if source in self.irc.users:
# Killer was a user (they're SO fired)
killer = self.irc.users[source].nick
elif source in self.irc.servers:
# Killer was a server (impossible, the machine is always right)
killer = self.irc.servers[source].name
else:
# Killer was... neither? We must have aliens or something. Fallback
# to the given "UID".
killer = source
# Get the reason, which is enclosed in brackets.
reason = ' '.join(args[1].split(" ")[1:])
killmsg = "Killed (%s %s)" % (killer, reason)
return {'target': killed, 'text': killmsg, 'userdata': data}
def handle_squit(self, numeric, command, args):
"""Handles incoming SQUITs."""
# <- ABAAE SQ nefarious.midnight.vpn 0 :test
split_server = self._getSid(args[0])
affected_users = []
log.debug('(%s) Splitting server %s (reason: %s)', self.irc.name, split_server, args[-1])
if split_server not in self.irc.servers:
log.warning("(%s) Tried to split a server (%s) that didn't exist!", self.irc.name, split_server)
return
# Prevent RuntimeError: dictionary changed size during iteration
old_servers = self.irc.servers.copy()
# Cycle through our list of servers. If any server's uplink is the one that is being SQUIT,
# remove them and all their users too.
for sid, data in old_servers.items():
if data.uplink == split_server:
log.debug('Server %s also hosts server %s, removing those users too...', split_server, sid)
# Recursively run SQUIT on any other hubs this server may have been connected to.
args = self.handle_squit(sid, 'SQUIT', [sid, "0",
"PyLink: Automatically splitting leaf servers of %s" % sid])
affected_users += args['users']
for user in self.irc.servers[split_server].users.copy():
affected_users.append(user)
log.debug('Removing client %s (%s)', user, self.irc.users[user].nick)
self.removeClient(user)
sname = self.irc.servers[split_server].name
uplink = self.irc.servers[split_server].uplink
del self.irc.servers[split_server]
log.debug('(%s) Netsplit affected users: %s', self.irc.name, affected_users)
return {'target': split_server, 'users': affected_users, 'name': sname,
'uplink': uplink}

View File

@ -2,15 +2,14 @@
nefarious.py: Nefarious IRCu protocol module for PyLink. nefarious.py: Nefarious IRCu protocol module for PyLink.
""" """
import sys
import os
import base64 import base64
import struct import struct
from ipaddress import ip_address from ipaddress import ip_address
from pylinkirc import utils from pylinkirc import utils, structures
from pylinkirc.classes import * from pylinkirc.classes import *
from pylinkirc.log import log from pylinkirc.log import log
from pylinkirc.protocols.ircs2s_common import *
class P10UIDGenerator(utils.IncrementalUIDGenerator): class P10UIDGenerator(utils.IncrementalUIDGenerator):
"""Implements an incremental P10 UID Generator.""" """Implements an incremental P10 UID Generator."""
@ -59,7 +58,7 @@ class P10SIDGenerator():
self.currentnum += 1 self.currentnum += 1
return sid return sid
class P10Protocol(Protocol): class P10Protocol(IRCS2SProtocol):
def __init__(self, irc): def __init__(self, irc):
super().__init__(irc) super().__init__(irc)
@ -504,8 +503,8 @@ class P10Protocol(Protocol):
# XXX: there HAS to be a better way of doing this # XXX: there HAS to be a better way of doing this
def access_sort(key): def access_sort(key):
prefixes, user = key prefixes, user = key
# This is some hocus pocus. Add the prefixes given for each userpair, # Add the prefixes given for each userpair, giving each one a set value. This ensures
# giving each one a set value. This ensures that 'ohv' > 'oh' > 'ov' > 'o' > 'hv' > 'h' > 'v' > '' # that 'ohv' > 'oh' > 'ov' > 'o' > 'hv' > 'h' > 'v' > ''
accesses = {'o': 100, 'h': 10, 'v': 1} accesses = {'o': 100, 'h': 10, 'v': 1}
num = 0 num = 0
@ -1181,44 +1180,6 @@ class P10Protocol(Protocol):
self.removeClient(killed) self.removeClient(killed)
return {'target': killed, 'text': args[1], 'userdata': data} return {'target': killed, 'text': args[1], 'userdata': data}
def handle_squit(self, numeric, command, args):
"""Handles incoming SQUITs."""
# <- ABAAE SQ nefarious.midnight.vpn 0 :test
split_server = self._getSid(args[0])
affected_users = []
log.debug('(%s) Splitting server %s (reason: %s)', self.irc.name, split_server, args[-1])
if split_server not in self.irc.servers:
log.warning("(%s) Tried to split a server (%s) that didn't exist!", self.irc.name, split_server)
return
# Prevent RuntimeError: dictionary changed size during iteration
old_servers = self.irc.servers.copy()
# Cycle through our list of servers. If any server's uplink is the one that is being SQUIT,
# remove them and all their users too.
for sid, data in old_servers.items():
if data.uplink == split_server:
log.debug('Server %s also hosts server %s, removing those users too...', split_server, sid)
# Recursively run SQUIT on any other hubs this server may have been connected to.
args = self.handle_squit(sid, 'SQUIT', [sid, "0",
"PyLink: Automatically splitting leaf servers of %s" % sid])
affected_users += args['users']
for user in self.irc.servers[split_server].users.copy():
affected_users.append(user)
log.debug('Removing client %s (%s)', user, self.irc.users[user].nick)
self.removeClient(user)
sname = self.irc.servers[split_server].name
uplink = self.irc.servers[split_server].uplink
del self.irc.servers[split_server]
log.debug('(%s) Netsplit affected users: %s', self.irc.name, affected_users)
return {'target': split_server, 'users': affected_users, 'name': sname,
'uplink': uplink}
def handle_topic(self, source, command, args): def handle_topic(self, source, command, args):
"""Handles TOPIC changes.""" """Handles TOPIC changes."""
# <- ABAAA T #test GL!~gl@nefarious.midnight.vpn 1460852591 1460855795 :blah # <- ABAAA T #test GL!~gl@nefarious.midnight.vpn 1460852591 1460855795 :blah

View File

@ -2,13 +2,12 @@
ts6_common.py: Common base protocol class with functions shared by the UnrealIRCd, InspIRCd, and TS6 protocol modules. ts6_common.py: Common base protocol class with functions shared by the UnrealIRCd, InspIRCd, and TS6 protocol modules.
""" """
import sys
import os
import string import string
from pylinkirc import utils, structures from pylinkirc import utils, structures
from pylinkirc.classes import * from pylinkirc.classes import *
from pylinkirc.log import log from pylinkirc.log import log
from pylinkirc.protocols.ircs2s_common import *
class TS6SIDGenerator(): class TS6SIDGenerator():
""" """
@ -98,7 +97,7 @@ class TS6UIDGenerator(utils.IncrementalUIDGenerator):
self.length = 6 self.length = 6
super().__init__(sid) super().__init__(sid)
class TS6BaseProtocol(Protocol): class TS6BaseProtocol(IRCS2SProtocol):
def __init__(self, irc): def __init__(self, irc):
super().__init__(irc) super().__init__(irc)
@ -352,41 +351,6 @@ class TS6BaseProtocol(Protocol):
handle_notice = handle_privmsg handle_notice = handle_privmsg
def handle_kill(self, source, command, args):
"""Handles incoming KILLs."""
killed = args[0]
# Depending on whether the IRCd sends explicit QUIT messages for
# killed clients, the user may or may not have automatically been
# removed from our user list.
# If not, we have to assume that KILL = QUIT and remove them
# ourselves.
data = self.irc.users.get(killed)
if data:
self.removeClient(killed)
# TS6-style kills look something like this:
# <- :GL KILL 38QAAAAAA :hidden-1C620195!GL (test)
# What we actually want is to format a pretty kill message, in the form
# "Killed (killername (reason))".
if source in self.irc.users:
# Killer was a user (they're SO fired)
killer = self.irc.users[source].nick
elif source in self.irc.servers:
# Killer was a server (impossible, the machine is always right)
killer = self.irc.servers[source].name
else:
# Killer was... neither? We must have aliens or something. Fallback
# to the given "UID".
killer = source
# Get the reason, which is enclosed in brackets.
reason = ' '.join(args[1].split(" ")[1:])
killmsg = "Killed (%s %s)" % (killer, reason)
return {'target': killed, 'text': killmsg, 'userdata': data}
def handle_kick(self, source, command, args): def handle_kick(self, source, command, args):
"""Handles incoming KICKs.""" """Handles incoming KICKs."""
# :70MAAAAAA KICK #test 70MAAAAAA :some reason # :70MAAAAAA KICK #test 70MAAAAAA :some reason
@ -428,39 +392,6 @@ class TS6BaseProtocol(Protocol):
self.irc.users[user].nick = user self.irc.users[user].nick = user
return {'target': user, 'ts': int(args[1]), 'oldnick': oldnick} return {'target': user, 'ts': int(args[1]), 'oldnick': oldnick}
def handle_squit(self, numeric, command, args):
"""Handles incoming SQUITs (netsplits)."""
# :70M SQUIT 1ML :Server quit by GL!gl@0::1
log.debug('handle_squit args: %s', args)
split_server = args[0]
affected_users = []
log.debug('(%s) Splitting server %s (reason: %s)', self.irc.name, split_server, args[-1])
if split_server not in self.irc.servers:
log.warning("(%s) Tried to split a server (%s) that didn't exist!", self.irc.name, split_server)
return
uplink = self.irc.servers[split_server].uplink
# Prevent RuntimeError: dictionary changed size during iteration
old_servers = self.irc.servers.copy()
for sid, data in old_servers.items():
if data.uplink == split_server:
log.debug('Server %s also hosts server %s, removing those users too...', split_server, sid)
args = self.handle_squit(sid, 'SQUIT', [sid, "PyLink: Automatically splitting leaf servers of %s" % sid])
affected_users += args['users']
for user in self.irc.servers[split_server].users.copy():
affected_users.append(user)
log.debug('Removing client %s (%s)', user, self.irc.users[user].nick)
self.removeClient(user)
sname = self.irc.servers[split_server].name
del self.irc.servers[split_server]
log.debug('(%s) Netsplit affected users: %s', self.irc.name, affected_users)
return {'target': split_server, 'users': affected_users, 'name': sname,
'uplink': uplink}
def handle_topic(self, numeric, command, args): def handle_topic(self, numeric, command, args):
"""Handles incoming TOPIC changes from clients. For topic bursts, """Handles incoming TOPIC changes from clients. For topic bursts,
TB (TS6/charybdis) and FTOPIC (InspIRCd) are used instead.""" TB (TS6/charybdis) and FTOPIC (InspIRCd) are used instead."""