Rework data structures, storing all front-end network data in Network objects

This commit is contained in:
Al Beano 2019-08-11 21:58:14 +01:00
parent f6657cb905
commit e5adcfef4c
24 changed files with 258 additions and 284 deletions

6
.gitignore vendored
View File

@ -1,15 +1,13 @@
*.pyc *.pyc
*.pem *.pem
*.swp
__pycache__/ __pycache__/
conf/config.json conf/config.json
conf/pool.json
conf/wholist.json conf/wholist.json
conf/counters.json conf/counters.json
conf/masterbuf.json conf/masterbuf.json
conf/monitor.json conf/monitor.json
conf/alias.json
conf/relay.json
conf/network.json
conf/tokens.json conf/tokens.json
conf/network.dat
conf/dist.sh conf/dist.sh
env/ env/

View File

@ -1,61 +0,0 @@
import main
from yaml import dump
import modules.alias as alias
class AliasCommand:
def __init__(self, *args):
self.alias(*args)
def alias(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed:
if length == 8:
if spl[1] == "add":
if spl[2] in main.alias.keys():
failure("Alias already exists: %s" % spl[2])
return
else:
main.alias[spl[2]] = {"nick": spl[3],
"altnick": spl[4],
"ident": spl[5],
"realname": spl[6],
"password": spl[7]}
success("Successfully created alias: %s" % spl[2])
main.saveConf("alias")
return
else:
incUsage("alias")
return
elif length == 3:
if spl[1] == "del":
if spl[2] in main.alias.keys():
del main.alias[spl[2]]
success("Successfully removed alias: %s" % spl[2])
main.saveConf("alias")
return
else:
failure("No such alias: %s" % spl[2])
return
elif spl[1] == "add" and spl[2] == "auto":
newalias = alias.generate_alias()
while newalias["nick"] in main.alias.keys():
newalias = alias.generate_alias()
main.alias[newalias["nick"]] = newalias
success("Successfully created alias: %s" % newalias["nick"])
main.saveConf("alias")
return
else:
incUsage("alias")
return
elif length == 2:
if spl[1] == "list":
info(dump(main.alias))
return
else:
incUsage("alias")
return
else:
incUsage("alias")
return
else:
incUsage(None)

View File

@ -8,14 +8,16 @@ class CmdCommand:
def cmd(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length): def cmd(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed: if authed:
if length > 4: if length > 4:
if not spl[1] in main.relay.keys(): if not spl[1] in main.network.keys():
failure("No such relay: %s" % spl[1]) failure("No such network: %s" % spl[1])
return
if not int(spl[2]) in main.network[spl[1]].relays.keys():
failure("No such relay: %s on network: %s" % (spl[2], spl[1]))
return return
commands = {spl[3]: [" ".join(spl[4:])]} commands = {spl[4]: [" ".join(spl[5:])]}
print(" ".join(spl[4:])) success("Sending commands to relay %s as user %s" % (spl[2], spl[3]))
success("Sending commands to relay %s as user %s" % (spl[1], spl[2])) deliverRelayCommands(main.network[spl[1]].relays[spl[2]], commands, user=spl[3]+"/"+spl[1])
deliverRelayCommands(spl[1], commands, user=spl[2])
return return
else: else:
incUsage("cmd") incUsage("cmd")

View File

@ -6,21 +6,25 @@ class DelCommand:
def delete(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length): def delete(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed: if authed:
if length == 2: if length == 3:
if not spl[1] in main.pool.keys(): if not spl[1] in main.network.keys():
failure("Name does not exist: %s" % spl[1]) failure("No such network: %s" % spl[1])
return return
del main.pool[spl[1]] if not int(spl[2]) in main.network[spl[1]].relays.keys():
if spl[1] in main.ReactorPool.keys(): failure("No such relay: %s in network %s" % (spl[2], spl[1]))
if spl[1] in main.FactoryPool.keys(): return
main.FactoryPool[spl[1]].stopTrying()
main.ReactorPool[spl[1]].disconnect() main.network[spl[1]].delete_relay(int(spl[2]))
if spl[1] in main.IRCPool.keys(): if spl[1]+spl[2] in main.ReactorPool.keys():
del main.IRCPool[spl[1]] if spl[1]+spl[2] in main.FactoryPool.keys():
del main.ReactorPool[spl[1]] main.FactoryPool[spl[1]+spl[2]].stopTrying()
del main.FactoryPool[spl[1]] main.ReactorPool[spl[1]+spl[2]].disconnect()
if spl[1]+spl[2] in main.IRCPool.keys():
del main.IRCPool[spl[1]+spl[2]]
del main.ReactorPool[spl[1]+spl[2]]
del main.FactoryPool[spl[1]+spl[2]]
success("Successfully removed bot: %s" % spl[1]) success("Successfully removed bot: %s" % spl[1])
main.saveConf("pool") main.saveConf("network")
return return
else: else:
incUsage("del") incUsage("del")

View File

@ -7,26 +7,30 @@ class DisableCommand:
def disable(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length): def disable(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed: if authed:
if length == 2: if length == 3:
if not spl[1] in main.pool.keys(): if not spl[1] in main.network.keys():
failure("Name does not exist: %s" % spl[1]) failure("No such network: %s" % spl[1])
return return
main.pool[spl[1]]["enabled"] = False if not int(spl[2]) in main.network[spl[1]].relays.keys():
user = main.pool[spl[1]]["alias"] failure("No such relay: %s in network %s" % (spl[2], spl[1]))
network = main.pool[spl[1]]["network"] return
relay = main.pool[spl[1]]["relay"]
main.network[spl[1]].relays[int(spl[2])]["enabled"] = False
user = main.network[spl[1]].aliases[int(spl[2])]
network = spl[1]
relay = main.network[spl[1]].relays[int(spl[2])]
commands = {"status": ["Disconnect"]} commands = {"status": ["Disconnect"]}
deliverRelayCommands(relay, commands, user=user+"/"+network) deliverRelayCommands(relay, commands, user=user+"/"+network)
main.saveConf("pool") main.saveConf("network")
if spl[1] in main.ReactorPool.keys(): if spl[1]+spl[2] in main.ReactorPool.keys():
if spl[1] in main.FactoryPool.keys(): if spl[1]+spl[2] in main.FactoryPool.keys():
main.FactoryPool[spl[1]].stopTrying() main.FactoryPool[spl[1]+spl[2]].stopTrying()
main.ReactorPool[spl[1]].disconnect() main.ReactorPool[spl[1]+spl[2]].disconnect()
if spl[1] in main.IRCPool.keys(): if spl[1] in main.IRCPool.keys():
del main.IRCPool[spl[1]] del main.IRCPool[spl[1]+spl[2]]
del main.ReactorPool[spl[1]] del main.ReactorPool[spl[1]+spl[2]]
del main.FactoryPool[spl[1]] del main.FactoryPool[spl[1]+spl[2]]
success("Successfully disabled bot %s" % spl[1]) success("Successfully disabled bot %s on network %s" % (spl[2], spl[1]))
return return
else: else:
incUsage("disable") incUsage("disable")

View File

@ -1,5 +1,4 @@
import main import main
from core.helper import startBot
from core.bot import deliverRelayCommands from core.bot import deliverRelayCommands
class EnableCommand: class EnableCommand:
@ -8,22 +7,26 @@ class EnableCommand:
def enable(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length): def enable(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed: if authed:
if length == 2: if length == 3:
if not spl[1] in main.pool.keys(): if not spl[1] in main.network.keys():
failure("Name does not exist: %s" % spl[1]) failure("No such network: %s" % spl[1])
return return
main.pool[spl[1]]["enabled"] = True if not int(spl[2]) in main.network[spl[1]].relays.keys():
user = main.pool[spl[1]]["alias"] failure("No such relay: %s in network %s" % (spl[2], spl[1]))
network = main.pool[spl[1]]["network"] return
relay = main.pool[spl[1]]["relay"]
main.network[spl[1]].relays[int(spl[2])]["enabled"] = True
user = main.network[spl[1]].aliases[int(spl[2])]
network = spl[1]
relay = main.network[spl[1]].relays[int(spl[2])]
commands = {"status": ["Connect"]} commands = {"status": ["Connect"]}
deliverRelayCommands(relay, commands, user=user+"/"+network) deliverRelayCommands(relay, commands, user=user+"/"+network)
main.saveConf("pool") main.saveConf("network")
if not spl[1] in main.IRCPool.keys(): if not spl[1]+spl[2] in main.IRCPool.keys():
startBot(spl[1]) main.network[spl[1]].start_bot(int(spl[2]))
else: else:
pass pass
success("Successfully enabled bot %s" % spl[1]) success("Successfully enabled bot %s on network %s" % (spl[2], spl[1]))
return return
else: else:
incUsage("enable") incUsage("enable")

View File

@ -6,25 +6,31 @@ class JoinCommand:
def join(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length): def join(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed: if authed:
if length == 3: if length == 4:
if not spl[1] in main.pool.keys(): if not spl[1] in main.network.keys():
failure("Name does not exist: %s" % spl[1]) failure("Network does not exist: %s" % spl[1])
return return
if not spl[1] in main.IRCPool.keys(): if not int(spl[2]) in main.network[spl[1]].relays.keys():
failure("Relay % does not exist on network %", (spl[2], spl[1]))
return
if not spl[1]+spl[2] in main.IRCPool.keys():
failure("Name has no instance: %s" % spl[1]) failure("Name has no instance: %s" % spl[1])
return return
main.IRCPool[spl[1]].join(spl[2]) main.IRCPool[spl[1]+spl[2]].join(spl[3])
success("Joined %s" % spl[2]) success("Joined %s" % spl[3])
return return
elif length == 4: elif length == 5:
if not spl[1] in main.pool.keys(): if not spl[1] in main.network.keys():
failure("Name does not exist: %s" % spl[1]) failure("Network does not exist: %s" % spl[1])
return return
if not spl[1] in main.IRCPool.keys(): if not int(spl[2]) in main.network[spl[1]].relays.keys():
failure("Relay % does not exist on network %", (spl[2], spl[1]))
return
if not spl[1]+spl[2] in main.IRCPool.keys():
failure("Name has no instance: %s" % spl[1]) failure("Name has no instance: %s" % spl[1])
return return
main.IRCPool[spl[1]].join(spl[2], spl[3]) main.IRCPool[spl[1]+spl[2]].join(spl[3], spl[4])
success("Joined %s with key %s" % (spl[2], spl[3])) success("Joined %s with key %s" % (spl[3], spl[4]))
return return
else: else:
incUsage("join") incUsage("join")

View File

@ -1,13 +0,0 @@
import main
from yaml import dump
class ListCommand:
def __init__(self, *args):
self.list(*args)
def list(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed:
info(dump(main.pool))
return
else:
incUsage(None)

View File

@ -2,49 +2,42 @@ import main
from yaml import dump from yaml import dump
class ModCommand: class ModCommand:
# This could be greatly improved, but not really important right now
def __init__(self, *args): def __init__(self, *args):
self.mod(*args) self.mod(*args)
def mod(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length): def mod(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed: if authed:
if length == 2: if length == 4:
if not spl[1] in main.pool.keys(): if not spl[1] in main.network.keys():
failure("Name does not exist: %s" % spl[1]) failure("Network does not exist: %s" % spl[1])
return
info(dump({spl[1]: main.pool[spl[1]]}))
return
elif length == 3:
if not spl[1] in main.pool.keys():
failure("Name does not exist: %s" % spl[1])
return
if not spl[2] in main.pool[spl[1]].keys():
failure("No such key: %s" % spl[2])
return
info("%s: %s" % (spl[2], main.pool[spl[1]][spl[2]]))
return
elif length == 4:
if not spl[1] in main.pool.keys():
failure("Name does not exist: %s" % spl[1])
return
if not spl[2] in main.pool[spl[1]].keys():
failure("No such key: %s" % spl[2])
return return
if spl[3] == main.pool[spl[1]][spl[2]]: try:
failure("Value already exists: %s" % spl[3]) setattr(main.network[spl[1]], spl[2], spl[3])
except e:
failure("Something went wrong.")
return return
if spl[2] == "enabled": main.saveConf("network")
failure("Use the enable and disable commands to manage this")
return
main.pool[spl[1]][spl[2]] = spl[3]
main.saveConf("pool")
success("Successfully set key %s to %s on %s" % (spl[2], spl[3], spl[1])) success("Successfully set key %s to %s on %s" % (spl[2], spl[3], spl[1]))
return return
elif length == 6:
if not spl[1] in main.network.keys():
failure("Network does not exist: %s" % spl[1])
return
if not int(spl[3]) in main.network[spl[1]].relays.keys():
failure("Relay/alias does not exist: %s" % spl[3])
return
try:
x = getattr(main.network[spl[1]], spl[2])
x[spl[3]] = spl[4]
except e:
failure("Something went wrong.")
return
else: else:
incUsage("mod") incUsage("mod")
return return

View File

@ -6,17 +6,20 @@ class MsgCommand:
def msg(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length): def msg(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed: if authed:
if length >= 4: if length >= 5:
if not spl[1] in main.pool.keys(): if not spl[1] in main.network.keys():
failure("Name does not exist: %s" % spl[1]) failure("Network does not exist: %s" % spl[1])
return return
if not spl[1] in main.IRCPool.keys(): if not int(spl[2]) in main.network[spl[1]].relays.keys():
failure("Relay % does not exist on network %" % (spl[2], spl[1]))
return
if not spl[1]+spl[2] in main.IRCPool.keys():
failure("Name has no instance: %s" % spl[1]) failure("Name has no instance: %s" % spl[1])
return return
if not spl[2] in main.IRCPool[spl[1]].channels: if not spl[3] in main.IRCPool[spl[1]+spl[2]].channels:
info("Bot not on channel: %s" % spl[2]) info("Bot not on channel: %s" % spl[3])
main.IRCPool[spl[1]].msg(spl[2], " ".join(spl[3:])) main.IRCPool[spl[1]+spl[2]].msg(spl[3], " ".join(spl[4:]))
success("Sent %s to %s on %s" % (" ".join(spl[3:]), spl[2], spl[1])) success("Sent %s to %s on relay %s on network %s" % (" ".join(spl[4:]), spl[3], spl[2], spl[1]))
return return
else: else:
incUsage("msg") incUsage("msg")

View File

@ -1,5 +1,6 @@
import main import main
from yaml import dump from yaml import dump
from modules.network import Network
class NetworkCommand: class NetworkCommand:
def __init__(self, *args): def __init__(self, *args):
@ -22,10 +23,7 @@ class NetworkCommand:
failure("Auth must be sasl, ns or none, not %s" % spl[5]) failure("Auth must be sasl, ns or none, not %s" % spl[5])
return return
else: else:
main.network[spl[2]] = {"host": spl[3], main.network[spl[2]] = Network(spl[2], spl[3], spl[4], spl[5].lower(), spl[6].lower())
"port": spl[4],
"security": spl[5].lower(),
"auth": spl[6].lower()}
success("Successfully created network: %s" % spl[2]) success("Successfully created network: %s" % spl[2])
main.saveConf("network") main.saveConf("network")
return return

View File

@ -6,15 +6,18 @@ class PartCommand:
def part(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length): def part(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed: if authed:
if length == 3: if length == 4:
if not spl[1] in main.pool.keys(): if not spl[1] in main.network.keys():
failure("Name does not exist: %s" % spl[1]) failure("Network does not exist: %s" % spl[1])
return return
if not spl[1] in main.IRCPool.keys(): if not int(spl[2]) in main.network[spl[1]].relays.keys():
failure("Name has no instance: %s" % spl[1]) failure("Relay % does not exist on network %", (spl[2], spl[1]))
return return
main.IRCPool[spl[1]].part(spl[2]) if not spl[1]+spl[2] in main.IRCPool.keys():
success("Left %s" % spl[2]) failure("Name has no instance: %s" % spl[1]+spl[2])
return
main.IRCPool[spl[1]+spl[2]].part(spl[3])
success("Left %s" % spl[3])
return return
else: else:
incUsage("part") incUsage("part")

View File

@ -9,40 +9,42 @@ class RelayCommand:
if authed: if authed:
if length == 7: if length == 7:
if spl[1] == "add": if spl[1] == "add":
if spl[2] in main.relay.keys(): if spl[2] not in main.network.keys():
failure("Relay already exists: %s" % spl[2]) failure("No such network: %s" % spl[2])
return return
if not spl[4].isdigit(): if not spl[4].isdigit():
failure("Port must be an integer, not %s" % spl[4]) failure("Port must be an integer, not %s" % spl[4])
return return
else: else:
main.relay[spl[2]] = {"host": spl[3], id, alias = main.network[spl[2]].add_relay(spl[3], spl[4], spl[5], spl[6])
"port": spl[4], success("Successfully created relay %s on network %s with alias %s" % (str(id), spl[2], alias))
"user": spl[5], main.saveConf("network")
"password": spl[6]}
success("Successfully created relay: %s" % spl[2])
main.saveConf("relay")
return return
else: else:
incUsage("relay") incUsage("relay")
return return
elif length == 3: elif length == 4:
if spl[1] == "del": if spl[1] == "del":
if spl[2] in main.relay.keys(): if spl[2] not in main.network.keys():
del main.relay[spl[2]] failure("No such network: %s" % spl[2])
success("Successfully removed relay: %s" % spl[2])
main.saveConf("relay")
return return
else: if int(spl[3]) not in main.network[spl[2]].relays.keys():
failure("No such relay: %s" % spl[2]) failure("No such relay: %s on network %s" % (spl[3], spl[2]))
return return
main.network[spl[2]].delete_relay(int(spl[3]))
success("Successfully deleted relay %s on network %s" % (spl[3], spl[2]))
main.saveConf("network")
return
else: else:
incUsage("relay") incUsage("relay")
return return
elif length == 2: elif length == 3:
if spl[1] == "list": if spl[1] == "list":
info(dump(main.relay)) if spl[2] not in main.network.keys():
failure("No such network: %s" % spl[2])
return
info(dump(main.network[spl[2]].relays))
return return
else: else:
incUsage("relay") incUsage("relay")

View File

@ -17,8 +17,7 @@ class StatsCommand:
numChannels += len(main.IRCPool[i].channels) numChannels += len(main.IRCPool[i].channels)
numWhoEntries += userinfo.getNumTotalWhoEntries() numWhoEntries += userinfo.getNumTotalWhoEntries()
stats.append("Registered servers:") stats.append("Registered servers:")
stats.append(" Total: %s" % len(main.pool.keys())) stats.append(" Total: %s" % len(main.network.keys()))
stats.append(" Unique: %s" % len(main.nets()))
stats.append("Online servers:") stats.append("Online servers:")
stats.append(" Total: %s" % len(main.IRCPool.keys())) stats.append(" Total: %s" % len(main.IRCPool.keys()))
stats.append(" Unique: %s" % len(main.liveNets())) stats.append(" Unique: %s" % len(main.liveNets()))

View File

@ -1 +0,0 @@
{}

View File

@ -1 +0,0 @@
{}

View File

@ -1 +0,0 @@
{}

View File

@ -1 +0,0 @@
{}

View File

@ -1,29 +1,27 @@
{ {
"pass": "pass <password>", "pass": "pass <password>",
"logout": "logout", "logout": "logout",
"del": "del <name>", "del": "del <network> <relay>",
"mod": "mod <name> [<key>] [<value>]", "mod": "mod <network> <variable> <value>",
"get": "get <name> <variable>", "get": "get <name>",
"key": "key <master|list|add|del|except|unexcept|listexcept|monitor> [<name>] [<target>] [<key...>] [<on|off>]", "key": "key <master|list|add|del|except|unexcept|listexcept|monitor> [<name>] [<target>] [<key...>] [<on|off>]",
"who": "who <query>", "who": "who <query>",
"join": "join <name> <channel> [<key>]", "join": "join <network> <relay> <channel> [<key>]",
"part": "part <name> <channel>", "part": "part <network> <relay> <channel>",
"enable": "enable <name>", "enable": "enable <network> <id>",
"disable": "disable <name>", "disable": "disable <network> <id>",
"list": "list",
"stats": "stats [<name>]", "stats": "stats [<name>]",
"save": "save <(file)|list|all>", "save": "save <(file)|list|all>",
"load": "load <(file)|list|all>", "load": "load <(file)|list|all>",
"dist": "dist", "dist": "dist",
"loadmod": "loadmod <module>", "loadmod": "loadmod <module>",
"msg": "msg <name> <target> <message...>", "msg": "msg <network> <relay> <target> <message...>",
"mon": "mon -h", "mon": "mon -h",
"chans": "chans <nick> [<nick> ...]", "chans": "chans <nick> [<nick> ...]",
"users": "users <channel> [<channel> ...]", "users": "users <channel> [<channel> ...]",
"alias": "alias <add|del|list> [<alias> <nickname> <altnick> <ident> <realname> <password> OR auto]", "relay": "relay <add|del|list> [<network> <host> <port> <user> <password> | <network> <id> | <network>]",
"relay": "relay <add|del|list> [<relay> <host> <port> <user> <password>]",
"network": "network <add|del|list> [<name> <address> <port> <ssl|plain> <sasl|ns|none>]", "network": "network <add|del|list> [<name> <address> <port> <ssl|plain> <sasl|ns|none>]",
"provision": "provision <relay> <alias> [<network>]", "provision": "provision <relay> <alias> [<network>]",
"cmd": "cmd <relay> <user> <entity> <text ...>", "cmd": "cmd <network> <relay> <user> <entity> <text ...>",
"token": "token <add|del|list> [<key>] [<relay>]" "token": "token <add|del|list> [<key>] [<relay>]"
} }

View File

@ -20,13 +20,14 @@ from utils.logging.send import *
from twisted.internet.ssl import DefaultOpenSSLContextFactory from twisted.internet.ssl import DefaultOpenSSLContextFactory
def deliverRelayCommands(relay, relayCommands, user=None, stage2=None): def deliverRelayCommands(relay, relayCommands, user=None, stage2=None):
# where relay is a dictionary extracted from the Network object
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"), contextFactory = DefaultOpenSSLContextFactory(keyFN.encode("utf-8", "replace"),
certFN.encode("utf-8", "replace")) certFN.encode("utf-8", "replace"))
bot = IRCBotFactory(None, relay, relayCommands, user, stage2) bot = IRCBotFactory(None, relay, relayCommands, user, stage2)
rct = reactor.connectSSL(main.relay[relay]["host"], rct = reactor.connectSSL(relay["host"],
int(main.relay[relay]["port"]), int(relay["port"]),
bot, contextFactory) bot, contextFactory)
class IRCRelay(IRCClient): class IRCRelay(IRCClient):
@ -34,10 +35,10 @@ class IRCRelay(IRCClient):
self.connected = False self.connected = False
self.buffer = "" self.buffer = ""
if user == None: if user == None:
self.user = main.relay[relay]["user"] self.user = relay["user"]
else: else:
self.user = user self.user = user
password = main.relay[relay]["password"] password = relay["password"]
self.nickname = self.user self.nickname = self.user
self.realname = self.user self.realname = self.user
self.username = self.user self.username = self.user
@ -88,7 +89,7 @@ class IRCRelay(IRCClient):
return return
class IRCBot(IRCClient): class IRCBot(IRCClient):
def __init__(self, name): def __init__(self, name, relay):
self.connected = False self.connected = False
self.channels = [] self.channels = []
self.net = "".join([x for x in name if not x in digits]) self.net = "".join([x for x in name if not x in digits])
@ -96,14 +97,11 @@ class IRCBot(IRCClient):
error("Network with all numbers: %s" % name) error("Network with all numbers: %s" % name)
self.buffer = "" self.buffer = ""
self.name = name self.name = name
inst = main.pool[name] alias = relay["alias"]
alias = main.alias[inst["alias"]]
relay = main.relay[inst["relay"]]
network = main.network[inst["network"]]
self.nickname = alias["nick"] self.nickname = alias["nick"]
self.realname = alias["realname"] self.realname = alias["realname"]
self.username = inst["alias"]+"/"+inst["network"] self.username = alias["nick"]+"/"+relay["net"]
self.password = relay["password"] self.password = relay["password"]
self.userinfo = None self.userinfo = None
self.fingerReply = None self.fingerReply = None
@ -448,7 +446,7 @@ class IRCBotFactory(ReconnectingClientFactory):
self.name = name self.name = name
self.net = "".join([x for x in self.name if not x in digits]) self.net = "".join([x for x in self.name if not x in digits])
else: else:
self.name = "Relay to "+relay self.name = "Relay to "+relay["net"]+relay["id"]
self.client = None self.client = None
self.maxDelay = main.config["Tweaks"]["Delays"]["MaxDelay"] self.maxDelay = main.config["Tweaks"]["Delays"]["MaxDelay"]
self.initialDelay = main.config["Tweaks"]["Delays"]["InitialDelay"] self.initialDelay = main.config["Tweaks"]["Delays"]["InitialDelay"]
@ -459,7 +457,7 @@ class IRCBotFactory(ReconnectingClientFactory):
def buildProtocol(self, addr): def buildProtocol(self, addr):
if self.relay == None: if self.relay == None:
entry = IRCBot(self.name) entry = IRCBot(self.name, self.relay)
main.IRCPool[self.name] = entry main.IRCPool[self.name] = entry
else: else:
entry = IRCRelay(self.relay, self.relayCommands, self.user, self.stage2) entry = IRCRelay(self.relay, self.relayCommands, self.user, self.stage2)

View File

@ -1,27 +0,0 @@
from twisted.internet import reactor
from core.bot import IRCBot, IRCBotFactory
from twisted.internet.ssl import DefaultOpenSSLContextFactory
import main
from utils.logging.log import *
def startBot(name):
inst = main.pool[name]
relay, alias, network = inst["relay"], inst["alias"], inst["network"]
host = main.relay[relay]["host"]
port = int(main.relay[relay]["port"])
log("Started bot %s to %s network %s" % (name, relay, network))
keyFN = main.certPath+main.config["Key"]
certFN = main.certPath+main.config["Certificate"]
contextFactory = DefaultOpenSSLContextFactory(keyFN.encode("utf-8", "replace"),
certFN.encode("utf-8", "replace"))
bot = IRCBotFactory(name)
rct = reactor.connectSSL(host,
port,
bot, contextFactory)
main.ReactorPool[name] = rct
main.FactoryPool[name] = bot
return

49
main.py
View File

@ -1,4 +1,5 @@
from json import load, dump, loads import json
import pickle
from redis import StrictRedis from redis import StrictRedis
from string import digits from string import digits
from utils.logging.log import * from utils.logging.log import *
@ -7,17 +8,17 @@ configPath = "conf/"
certPath = "cert/" certPath = "cert/"
filemap = { filemap = {
"config": ["config.json", "configuration"], # JSON configs
"pool": ["pool.json", "network, alias and relay mappings"], "config": ["config.json", "configuration", "json"],
"help": ["help.json", "command help"], "help": ["help.json", "command help", "json"],
"counters": ["counters.json", "counters file"], "counters": ["counters.json", "counters file", "json"],
"masterbuf": ["masterbuf.json", "master buffer"], "masterbuf": ["masterbuf.json", "master buffer", "json"],
"monitor": ["monitor.json", "monitoring database"], "monitor": ["monitor.json", "monitoring database", "json"],
"alias": ["alias.json", "alias details"], "tokens": ["tokens.json", "authentication tokens", "json"],
"relay": ["relay.json", "relay list"], "aliasdata": ["aliasdata.json", "data for alias generation", "json"],
"network": ["network.json", "network list"],
"tokens": ["tokens.json", "authentication tokens"], # Binary (pickle) configs
"aliasdata": ["aliasdata.json", "data for alias generation"] "network": ["network.dat", "network list", "pickle"]
} }
connections = {} connections = {}
@ -48,13 +49,27 @@ def liveNets():
return networks return networks
def saveConf(var): def saveConf(var):
with open(configPath+filemap[var][0], "w") as f: if filemap[var][2] == "json":
dump(globals()[var], f, indent=4) with open(configPath+filemap[var][0], "w") as f:
return json.dump(globals()[var], f, indent=4)
elif filemap[var][2] == "pickle":
with open(configPath+filemap[var][0], "wb") as f:
pickle.dump(globals()[var], f)
else:
raise Exception("invalid format")
def loadConf(var): def loadConf(var):
with open(configPath+filemap[var][0], "r") as f: if filemap[var][2] == "json":
globals()[var] = load(f) with open(configPath+filemap[var][0], "r") as f:
globals()[var] = json.load(f)
elif filemap[var][2] == "pickle":
try:
with open(configPath+filemap[var][0], "rb") as f:
globals()[var] = pickle.load(f)
except FileNotFoundError:
globals()[var] = {}
else:
raise Exception("invalid format")
def initConf(): def initConf():
for i in filemap.keys(): for i in filemap.keys():

57
modules/network.py Normal file
View File

@ -0,0 +1,57 @@
import json
import modules.alias as alias
from twisted.internet import reactor
from core.bot import IRCBot, IRCBotFactory
from twisted.internet.ssl import DefaultOpenSSLContextFactory
import main
from utils.logging.log import *
class Network:
def __init__(self, name, host, port, security, auth):
self.name = name
self.host = host
self.port = port
self.security = security
self.auth = auth
self.last = 0
self.relays = {}
self.aliases = {}
def add_relay(self, host, port, user, password):
self.last += 1
self.relays[self.last] = {
"host": host,
"port": port,
"user": user,
"password": password,
"enabled": False,
"net": self.name,
"id": self.last
}
self.aliases[self.last] = alias.generate_alias()
return self.last, self.aliases[self.last]["nick"]
def delete_relay(self, id):
del self.relays[id]
del self.aliases[id]
def start_bot(self, relay):
# a single name is given to relays in the backend
# e.g. freenode1 for the first relay on freenode network
name = self.name + relay
keyFN = main.certPath+main.config["Key"]
certFN = main.certPath+main.config["Certificate"]
contextFactory = DefaultOpenSSLContextFactory(keyFN.encode("utf-8", "replace"), certFN.encode("utf-8", "replace"))
bot = IRCBotFactory(name)
rct = reactor.connectSSL(k, port, bot, contextFactory)
main.ReactorPool[name] = rct
main.FactoryPool[name] = bot
log("Started bot on relay %s on %s", (relay, self.host))
def start_bots(self):
for relay in self.relays:
if relay["enabled"]:
start_bot(relay)

View File

@ -11,7 +11,6 @@ main.initMain()
from utils.logging.log import * from utils.logging.log import *
from utils.loaders.command_loader import loadCommands from utils.loaders.command_loader import loadCommands
from core.helper import startBot
from core.server import Server, ServerFactory from core.server import Server, ServerFactory
from core.relay import Relay, RelayFactory from core.relay import Relay, RelayFactory
import modules.counters import modules.counters
@ -33,10 +32,7 @@ if __name__ == "__main__":
else: else:
reactor.listenTCP(main.config["Relay"]["Port"], relay, interface=main.config["Relay"]["Address"]) reactor.listenTCP(main.config["Relay"]["Port"], relay, interface=main.config["Relay"]["Address"])
log("Threshold relay running on %s:%s" % (main.config["Relay"]["Address"], main.config["Relay"]["Port"])) log("Threshold relay running on %s:%s" % (main.config["Relay"]["Address"], main.config["Relay"]["Port"]))
for i in main.pool.keys(): for net in main.network.keys():
if not "enabled" in main.pool[i]: main.network[net].start_bots()
continue
if main.pool[i]["enabled"] == True:
startBot(i)
modules.counters.setupCounterLoop() modules.counters.setupCounterLoop()
reactor.run() reactor.run()