|
|
@ -1,45 +1,38 @@
|
|
|
|
from twisted.internet.protocol import ReconnectingClientFactory
|
|
|
|
|
|
|
|
from twisted.words.protocols.irc import IRCClient
|
|
|
|
|
|
|
|
from twisted.internet.defer import Deferred
|
|
|
|
|
|
|
|
from twisted.internet.task import LoopingCall
|
|
|
|
|
|
|
|
from twisted.internet import reactor, task
|
|
|
|
|
|
|
|
from twisted.words.protocols.irc import (
|
|
|
|
|
|
|
|
symbolic_to_numeric,
|
|
|
|
|
|
|
|
numeric_to_symbolic,
|
|
|
|
|
|
|
|
lowDequote,
|
|
|
|
|
|
|
|
IRCBadMessage,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import sys
|
|
|
|
from string import digits
|
|
|
|
|
|
|
|
from random import randint
|
|
|
|
|
|
|
|
from copy import deepcopy
|
|
|
|
from copy import deepcopy
|
|
|
|
from datetime import datetime
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
from random import randint
|
|
|
|
|
|
|
|
from string import digits
|
|
|
|
|
|
|
|
|
|
|
|
from modules import userinfo
|
|
|
|
from twisted.internet import reactor, task
|
|
|
|
from modules import counters
|
|
|
|
from twisted.internet.defer import Deferred
|
|
|
|
from modules import monitor
|
|
|
|
from twisted.internet.protocol import ReconnectingClientFactory
|
|
|
|
from modules import chankeep
|
|
|
|
from twisted.internet.ssl import DefaultOpenSSLContextFactory
|
|
|
|
from modules import regproc
|
|
|
|
from twisted.internet.task import LoopingCall
|
|
|
|
|
|
|
|
from twisted.words.protocols.irc import (IRCBadMessage, IRCClient, lowDequote,
|
|
|
|
|
|
|
|
numeric_to_symbolic,
|
|
|
|
|
|
|
|
symbolic_to_numeric)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import main
|
|
|
|
from core.relay import sendRelayNotification
|
|
|
|
from core.relay import sendRelayNotification
|
|
|
|
|
|
|
|
from modules import chankeep, counters, monitor, regproc, userinfo
|
|
|
|
from utils.dedup import dedup
|
|
|
|
from utils.dedup import dedup
|
|
|
|
from utils.get import getRelay
|
|
|
|
from utils.get import getRelay
|
|
|
|
|
|
|
|
|
|
|
|
import main
|
|
|
|
|
|
|
|
from utils.logging.log import *
|
|
|
|
|
|
|
|
from utils.logging.debug import *
|
|
|
|
from utils.logging.debug import *
|
|
|
|
|
|
|
|
from utils.logging.log import *
|
|
|
|
from utils.logging.send import *
|
|
|
|
from utils.logging.send import *
|
|
|
|
from utils.parsing import parsen
|
|
|
|
from utils.parsing import parsen
|
|
|
|
|
|
|
|
|
|
|
|
from twisted.internet.ssl import DefaultOpenSSLContextFactory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def deliverRelayCommands(num, relayCommands, user=None, stage2=None):
|
|
|
|
def deliverRelayCommands(num, relayCommands, user=None, stage2=None):
|
|
|
|
keyFN = main.certPath + main.config["Key"]
|
|
|
|
keyFN = main.certPath + main.config["Key"]
|
|
|
|
certFN = main.certPath + main.config["Certificate"]
|
|
|
|
certFN = main.certPath + main.config["Certificate"]
|
|
|
|
contextFactory = DefaultOpenSSLContextFactory(keyFN.encode("utf-8", "replace"), certFN.encode("utf-8", "replace"))
|
|
|
|
contextFactory = DefaultOpenSSLContextFactory(
|
|
|
|
bot = IRCBotFactory(net=None, num=num, relayCommands=relayCommands, user=user, stage2=stage2)
|
|
|
|
keyFN.encode("utf-8", "replace"), certFN.encode("utf-8", "replace")
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
bot = IRCBotFactory(
|
|
|
|
|
|
|
|
net=None, num=num, relayCommands=relayCommands, user=user, stage2=stage2
|
|
|
|
|
|
|
|
)
|
|
|
|
host, port = getRelay(num)
|
|
|
|
host, port = getRelay(num)
|
|
|
|
rct = reactor.connectSSL(host, port, bot, contextFactory)
|
|
|
|
rct = reactor.connectSSL(host, port, bot, contextFactory)
|
|
|
|
|
|
|
|
|
|
|
@ -165,7 +158,9 @@ class IRCBot(IRCClient):
|
|
|
|
self.listAttempted = False # we asked for a list
|
|
|
|
self.listAttempted = False # we asked for a list
|
|
|
|
self.listSimple = False # after asking again we got the list, so use the simple
|
|
|
|
self.listSimple = False # after asking again we got the list, so use the simple
|
|
|
|
# syntax from now on
|
|
|
|
# syntax from now on
|
|
|
|
self.wantList = False # we want to send a LIST, but not all relays are active yet
|
|
|
|
self.wantList = (
|
|
|
|
|
|
|
|
False # we want to send a LIST, but not all relays are active yet
|
|
|
|
|
|
|
|
)
|
|
|
|
self.chanlimit = 0
|
|
|
|
self.chanlimit = 0
|
|
|
|
self.prefix = {}
|
|
|
|
self.prefix = {}
|
|
|
|
self.servername = None
|
|
|
|
self.servername = None
|
|
|
@ -197,9 +192,14 @@ class IRCBot(IRCClient):
|
|
|
|
if not i in self.channels:
|
|
|
|
if not i in self.channels:
|
|
|
|
if self.net in main.blacklist.keys():
|
|
|
|
if self.net in main.blacklist.keys():
|
|
|
|
if i in main.blacklist[self.net]:
|
|
|
|
if i in main.blacklist[self.net]:
|
|
|
|
debug("Not joining blacklisted channel %s on %s - %i" % (i, self.net, self.num))
|
|
|
|
debug(
|
|
|
|
|
|
|
|
"Not joining blacklisted channel %s on %s - %i"
|
|
|
|
|
|
|
|
% (i, self.net, self.num)
|
|
|
|
|
|
|
|
)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
debug(self.net, "-", self.num, ": joining", i, "in", sleeptime, "seconds")
|
|
|
|
debug(
|
|
|
|
|
|
|
|
self.net, "-", self.num, ": joining", i, "in", sleeptime, "seconds"
|
|
|
|
|
|
|
|
)
|
|
|
|
reactor.callLater(sleeptime, self.join, i)
|
|
|
|
reactor.callLater(sleeptime, self.join, i)
|
|
|
|
sleeptime += increment
|
|
|
|
sleeptime += increment
|
|
|
|
if sleeptime == 10:
|
|
|
|
if sleeptime == 10:
|
|
|
@ -207,11 +207,17 @@ class IRCBot(IRCClient):
|
|
|
|
increment = 0.7
|
|
|
|
increment = 0.7
|
|
|
|
increment += 0.1
|
|
|
|
increment += 0.1
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
error("%s - Cannot join channel we are already on: %s - %i" % (i, self.net, self.num))
|
|
|
|
error(
|
|
|
|
|
|
|
|
"%s - Cannot join channel we are already on: %s - %i"
|
|
|
|
|
|
|
|
% (i, self.net, self.num)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def checkChannels(self):
|
|
|
|
def checkChannels(self):
|
|
|
|
if not chankeep.allRelaysActive(self.net):
|
|
|
|
if not chankeep.allRelaysActive(self.net):
|
|
|
|
debug("Skipping channel check as we have inactive relays: %s - %i" % (self.net, self.num))
|
|
|
|
debug(
|
|
|
|
|
|
|
|
"Skipping channel check as we have inactive relays: %s - %i"
|
|
|
|
|
|
|
|
% (self.net, self.num)
|
|
|
|
|
|
|
|
)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
if self.net in main.TempChan.keys():
|
|
|
|
if self.net in main.TempChan.keys():
|
|
|
|
if self.num in main.TempChan[self.net].keys():
|
|
|
|
if self.num in main.TempChan[self.net].keys():
|
|
|
@ -225,7 +231,9 @@ class IRCBot(IRCClient):
|
|
|
|
cast["ts"] = str(datetime.now().isoformat())
|
|
|
|
cast["ts"] = str(datetime.now().isoformat())
|
|
|
|
|
|
|
|
|
|
|
|
# remove odd stuff
|
|
|
|
# remove odd stuff
|
|
|
|
for i in list(cast.keys()): # Make a copy of the .keys() as Python 3 cannot handle iterating over
|
|
|
|
for i in list(
|
|
|
|
|
|
|
|
cast.keys()
|
|
|
|
|
|
|
|
): # Make a copy of the .keys() as Python 3 cannot handle iterating over
|
|
|
|
if cast[i] == "": # a dictionary that changes length with each iteration
|
|
|
|
if cast[i] == "": # a dictionary that changes length with each iteration
|
|
|
|
del cast[i]
|
|
|
|
del cast[i]
|
|
|
|
# remove server stuff
|
|
|
|
# remove server stuff
|
|
|
@ -359,7 +367,9 @@ class IRCBot(IRCClient):
|
|
|
|
|
|
|
|
|
|
|
|
def irc_ERR_PASSWDMISMATCH(self, prefix, params):
|
|
|
|
def irc_ERR_PASSWDMISMATCH(self, prefix, params):
|
|
|
|
log("%s - %i: password mismatch as %s" % (self.net, self.num, self.username))
|
|
|
|
log("%s - %i: password mismatch as %s" % (self.net, self.num, self.username))
|
|
|
|
sendAll("%s - %i: password mismatch as %s" % (self.net, self.num, self.username))
|
|
|
|
sendAll(
|
|
|
|
|
|
|
|
"%s - %i: password mismatch as %s" % (self.net, self.num, self.username)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def _who(self, channel):
|
|
|
|
def _who(self, channel):
|
|
|
|
d = Deferred()
|
|
|
|
d = Deferred()
|
|
|
@ -474,12 +484,17 @@ class IRCBot(IRCClient):
|
|
|
|
debug("Will not send LIST, unauthenticated: %s - %i" % (self.net, self.num))
|
|
|
|
debug("Will not send LIST, unauthenticated: %s - %i" % (self.net, self.num))
|
|
|
|
return
|
|
|
|
return
|
|
|
|
if self.listAttempted:
|
|
|
|
if self.listAttempted:
|
|
|
|
debug("List request dropped, already asked for LIST - %s - %i" % (self.net, self.num))
|
|
|
|
debug(
|
|
|
|
|
|
|
|
"List request dropped, already asked for LIST - %s - %i"
|
|
|
|
|
|
|
|
% (self.net, self.num)
|
|
|
|
|
|
|
|
)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
self.listAttempted = True
|
|
|
|
self.listAttempted = True
|
|
|
|
if self.listOngoing:
|
|
|
|
if self.listOngoing:
|
|
|
|
debug("LIST request dropped, already ongoing - %s - %i" % (self.net, self.num))
|
|
|
|
debug(
|
|
|
|
|
|
|
|
"LIST request dropped, already ongoing - %s - %i" % (self.net, self.num)
|
|
|
|
|
|
|
|
)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
if nocheck:
|
|
|
|
if nocheck:
|
|
|
@ -504,7 +519,9 @@ class IRCBot(IRCClient):
|
|
|
|
self._tempList[1].append([channel, users, topic])
|
|
|
|
self._tempList[1].append([channel, users, topic])
|
|
|
|
|
|
|
|
|
|
|
|
def irc_RPL_LISTEND(self, prefix, params):
|
|
|
|
def irc_RPL_LISTEND(self, prefix, params):
|
|
|
|
if not len(self._tempList[0]) > 0: # there are no callbacks, can't do anything there
|
|
|
|
if (
|
|
|
|
|
|
|
|
not len(self._tempList[0]) > 0
|
|
|
|
|
|
|
|
): # there are no callbacks, can't do anything there
|
|
|
|
debug("We didn't ask for this LIST, discarding")
|
|
|
|
debug("We didn't ask for this LIST, discarding")
|
|
|
|
self._tempList[0].clear()
|
|
|
|
self._tempList[0].clear()
|
|
|
|
self._tempList[1].clear()
|
|
|
|
self._tempList[1].clear()
|
|
|
@ -529,7 +546,10 @@ class IRCBot(IRCClient):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
if self.listRetried:
|
|
|
|
if self.listRetried:
|
|
|
|
self.listRetried = False
|
|
|
|
self.listRetried = False
|
|
|
|
debug("List received after retry - defaulting to simple list syntax: %s - %i" % (self.net, self.num))
|
|
|
|
debug(
|
|
|
|
|
|
|
|
"List received after retry - defaulting to simple list syntax: %s - %i"
|
|
|
|
|
|
|
|
% (self.net, self.num)
|
|
|
|
|
|
|
|
)
|
|
|
|
self.listSimple = True
|
|
|
|
self.listSimple = True
|
|
|
|
|
|
|
|
|
|
|
|
def got_list(self, listinfo):
|
|
|
|
def got_list(self, listinfo):
|
|
|
@ -543,7 +563,10 @@ class IRCBot(IRCClient):
|
|
|
|
name = self.net + "1"
|
|
|
|
name = self.net + "1"
|
|
|
|
if main.IRCPool[name].wantList == True:
|
|
|
|
if main.IRCPool[name].wantList == True:
|
|
|
|
main.IRCPool[name].list(nocheck=True)
|
|
|
|
main.IRCPool[name].list(nocheck=True)
|
|
|
|
debug("Asking for a list for %s after final relay %i connected" % (self.net, self.num))
|
|
|
|
debug(
|
|
|
|
|
|
|
|
"Asking for a list for %s after final relay %i connected"
|
|
|
|
|
|
|
|
% (self.net, self.num)
|
|
|
|
|
|
|
|
)
|
|
|
|
if self.num == 1: # Only one instance should do a list
|
|
|
|
if self.num == 1: # Only one instance should do a list
|
|
|
|
if self.chanlimit:
|
|
|
|
if self.chanlimit:
|
|
|
|
if allRelays:
|
|
|
|
if allRelays:
|
|
|
@ -560,7 +583,9 @@ class IRCBot(IRCClient):
|
|
|
|
]: # TODO: add check for register request sent, only send it once
|
|
|
|
]: # TODO: add check for register request sent, only send it once
|
|
|
|
if main.config["AutoReg"]:
|
|
|
|
if main.config["AutoReg"]:
|
|
|
|
if not self.authenticated:
|
|
|
|
if not self.authenticated:
|
|
|
|
self._regAttempt = reactor.callLater(5, regproc.registerAccount, self.net, self.num)
|
|
|
|
self._regAttempt = reactor.callLater(
|
|
|
|
|
|
|
|
5, regproc.registerAccount, self.net, self.num
|
|
|
|
|
|
|
|
)
|
|
|
|
# regproc.registerAccount(self.net, self.num)
|
|
|
|
# regproc.registerAccount(self.net, self.num)
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.chanlimit = int(chanlimit)
|
|
|
|
self.chanlimit = int(chanlimit)
|
|
|
@ -568,7 +593,9 @@ class IRCBot(IRCClient):
|
|
|
|
warn("Invalid chanlimit: %s" % i)
|
|
|
|
warn("Invalid chanlimit: %s" % i)
|
|
|
|
if self.chanlimit == 0:
|
|
|
|
if self.chanlimit == 0:
|
|
|
|
self.chanlimit = 200 # don't take the piss if it's not limited
|
|
|
|
self.chanlimit = 200 # don't take the piss if it's not limited
|
|
|
|
if not regproc.needToRegister(self.net): # if we need to register, only recheck on auth confirmation
|
|
|
|
if not regproc.needToRegister(
|
|
|
|
|
|
|
|
self.net
|
|
|
|
|
|
|
|
): # if we need to register, only recheck on auth confirmation
|
|
|
|
self.recheckList()
|
|
|
|
self.recheckList()
|
|
|
|
|
|
|
|
|
|
|
|
def seed_prefix(self, prefix):
|
|
|
|
def seed_prefix(self, prefix):
|
|
|
@ -669,7 +696,9 @@ class IRCBot(IRCClient):
|
|
|
|
if negativepass == True:
|
|
|
|
if negativepass == True:
|
|
|
|
if self._negativePass == None:
|
|
|
|
if self._negativePass == None:
|
|
|
|
self._negativePass = True
|
|
|
|
self._negativePass = True
|
|
|
|
debug("Positive registration check - %s - %i" % (self.net, self.num))
|
|
|
|
debug(
|
|
|
|
|
|
|
|
"Positive registration check - %s - %i" % (self.net, self.num)
|
|
|
|
|
|
|
|
)
|
|
|
|
if sinst["ping"]:
|
|
|
|
if sinst["ping"]:
|
|
|
|
debug("Sending ping - %s - %i" % (self.net, self.num))
|
|
|
|
debug("Sending ping - %s - %i" % (self.net, self.num))
|
|
|
|
self.msg(sinst["entity"], sinst["pingmsg"])
|
|
|
|
self.msg(sinst["entity"], sinst["pingmsg"])
|
|
|
@ -725,7 +754,9 @@ class IRCBot(IRCClient):
|
|
|
|
lc = self._getWho[channel]
|
|
|
|
lc = self._getWho[channel]
|
|
|
|
lc.stop()
|
|
|
|
lc.stop()
|
|
|
|
del self._getWho[channel]
|
|
|
|
del self._getWho[channel]
|
|
|
|
userinfo.delChannels(self.net, [channel]) # < we do not need to deduplicate this
|
|
|
|
userinfo.delChannels(
|
|
|
|
|
|
|
|
self.net, [channel]
|
|
|
|
|
|
|
|
) # < we do not need to deduplicate this
|
|
|
|
# log("Can no longer cover %s, removing records" % channel)# as it will only be matched once --
|
|
|
|
# log("Can no longer cover %s, removing records" % channel)# as it will only be matched once --
|
|
|
|
# other bots have different nicknames so
|
|
|
|
# other bots have different nicknames so
|
|
|
|
|
|
|
|
|
|
|
|