def _validateNick(self, nick): """ Checks to make sure a nick doesn't clash with a PUID. """ if nick in self.irc.users or nick in self.irc.servers: raise ProtocolError( "Got bad nick %s from IRC which clashes with a PUID. Is someone trying to spoof users?" % nick)
def handle_quit(self, source, command, args): """Handles incoming QUITs.""" if self.irc.pseudoclient and source == self.irc.pseudoclient.uid: # Someone faked a quit from us? We should abort. raise ProtocolError("Received QUIT from uplink (%s)" % args[0]) self.quit(source, args[0]) return {'text': args[0]}
def handle_error(self, numeric, command, args): """Handles ERROR messages - these mean that our uplink has disconnected us!""" raise ProtocolError('Received an ERROR, disconnecting!')
def _squit(self, numeric, command, args): """Handles incoming SQUITs.""" split_server = self._get_SID(args[0]) # Normally we'd only need to check for our SID as the SQUIT target, but Nefarious # actually uses the uplink server as the SQUIT target. # <- ABAAE SQ nefarious.midnight.vpn 0 :test if split_server in (self.sid, self.uplink): raise ProtocolError('SQUIT received: (reason: %s)' % args[-1]) affected_users = [] affected_nicks = defaultdict(list) log.debug('(%s) Splitting server %s (reason: %s)', self.name, split_server, args[-1]) if split_server not in self.servers: log.warning("(%s) Tried to split a server (%s) that didn't exist!", self.name, split_server) return # Prevent RuntimeError: dictionary changed size during iteration old_servers = self.servers.copy() old_channels = self._channels.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._squit(sid, 'SQUIT', [ sid, "0", "PyLink: Automatically splitting leaf servers of %s" % sid ]) affected_users += args['users'] for user in self.servers[split_server].users.copy(): affected_users.append(user) nick = self.users[user].nick # Nicks affected is channel specific for SQUIT:. This makes Clientbot's SQUIT relaying # much easier to implement. for name, cdata in old_channels.items(): if user in cdata.users: affected_nicks[name].append(nick) log.debug('Removing client %s (%s)', user, nick) self._remove_client(user) serverdata = self.servers[split_server] sname = serverdata.name uplink = serverdata.uplink del self.servers[split_server] log.debug('(%s) Netsplit affected users: %s', self.name, affected_users) return { 'target': split_server, 'users': affected_users, 'name': sname, 'uplink': uplink, 'nicks': affected_nicks, 'serverdata': serverdata, 'channeldata': old_channels }