Add error checking in places, set up automatic relay provisioning and fix starting bots

This commit is contained in:
Mark Veidemanis 2019-08-25 21:29:11 +01:00
parent ff74968ff8
commit 2d70d5af11
19 changed files with 242 additions and 262 deletions

29
commands/auto.py Normal file
View File

@ -0,0 +1,29 @@
import main
from modules import provision
class AutoCommand:
def __init__(self, *args):
self.auto(*args)
def auto(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed:
if length == 3:
if not spl[1] in main.network.keys():
failure("No such network: %s" % spl[1])
return
if not spl[2].isdigit():
failure("Must be integer, not %s" % spl[2])
return
id, alias = main.network[spl[1]].add_relay(int(spl[2]))
success("Successfully created relay %s on network %s with alias %s" % (str(id), spl[1], alias))
main.saveConf("network")
rtrn = provision.provisionRelay(int(spl[2]), spl[1])
success("Started provisioning network %s on relay %s for alias %s" % (spl[1], spl[2], rtrn))
return
else:
incUsage("auto")
return
else:
incUsage(None)

View File

@ -8,16 +8,12 @@ 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.network.keys(): if not spl[1].isdigit():
failure("No such network: %s" % spl[1]) failure("Must be integer, not %s" % spl[1])
return return
if not int(spl[2]) in main.network[spl[1]].relays.keys(): commands = {spl[3]: [" ".join(spl[4:])]}
failure("No such relay: %s on network: %s" % (spl[2], spl[1]))
return
commands = {spl[4]: [" ".join(spl[5:])]}
success("Sending commands to relay %s as user %s" % (spl[2], spl[3])) success("Sending commands to relay %s as user %s" % (spl[2], spl[3]))
deliverRelayCommands(main.network[spl[1]].relays[spl[2]], commands, user=spl[3]+"/"+spl[1]) deliverRelayCommands(int(spl[1]), commands, user=spl[2])
return return
else: else:
incUsage("cmd") incUsage("cmd")

View File

@ -11,16 +11,18 @@ class EnableCommand:
if not spl[1] in main.network.keys(): if not spl[1] in main.network.keys():
failure("No such network: %s" % spl[1]) failure("No such network: %s" % spl[1])
return return
if not spl[2].isdigit():
failure("Must be a number, not %s" % spl[2])
return
if not int(spl[2]) in main.network[spl[1]].relays.keys(): if not int(spl[2]) in main.network[spl[1]].relays.keys():
failure("No such relay: %s in network %s" % (spl[2], spl[1])) failure("No such relay on %s: %s" % (spl[2], spl[1]))
return return
main.network[spl[1]].relays[int(spl[2])]["enabled"] = True main.network[spl[1]].relays[int(spl[2])]["enabled"] = True
user = main.network[spl[1]].aliases[int(spl[2])] user = main.network[spl[1]].aliases[int(spl[2])]["nick"]
network = spl[1] 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(int(spl[2]), commands, user=user+"/"+network)
main.saveConf("network") main.saveConf("network")
if not spl[1]+spl[2] in main.IRCPool.keys(): if not spl[1]+spl[2] in main.IRCPool.keys():
main.network[spl[1]].start_bot(int(spl[2])) main.network[spl[1]].start_bot(int(spl[2]))

View File

@ -1,22 +0,0 @@
import main
class GetCommand:
def __init__(self, *args):
self.get(*args)
def get(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed:
if length == 3:
if not spl[1] in main.pool.keys():
failure("Name does not exist: %s" % spl[1])
return
if not spl[1] in main.IRCPool.keys():
failure("Name has no instance: %s" % spl[1])
return
info(str(main.IRCPool[spl[1]].get(spl[2])))
return
else:
incUsage("get")
return
else:
incUsage(None)

View File

@ -11,7 +11,7 @@ class JoinCommand:
failure("Network does not exist: %s" % spl[1]) failure("Network does not exist: %s" % spl[1])
return return
if not int(spl[2]) in main.network[spl[1]].relays.keys(): if not int(spl[2]) in main.network[spl[1]].relays.keys():
failure("Relay % does not exist on network %", (spl[2], spl[1])) failure("Relay %s does not exist on network %s" % (spl[2], spl[1]))
return return
if not spl[1]+spl[2] in main.IRCPool.keys(): 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])

View File

@ -23,7 +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]] = Network(spl[2], spl[3], spl[4], spl[5].lower(), spl[6].lower()) main.network[spl[2]] = Network(spl[2], spl[3], int(spl[4]), spl[5].lower(), 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

@ -1,60 +0,0 @@
import main
from modules import provision
class ProvisionCommand:
def __init__(self, *args):
self.provision(*args)
def provision(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed:
if length == 4 or length == 3:
if not spl[1] in main.relay.keys():
failure("No such relay: %s" % spl[1])
return
if not spl[2] in main.alias.keys():
failure("No such alias: %s" % spl[2])
return
if length == 4: # provision for relay, alias and network
if not spl[3] in main.network.keys():
failure("No such network: %s" % spl[3])
return
#if "users" in main.relay[spl[1]]:
# if not spl[2] in main.relay[spl[1]]["users"]:
# failure("Relay %s not provisioned for alias %s" % (spl[1], spl[2]))
# return
#else:
# failure("Relay %s not provisioned for alias %s" % (spl[1], spl[2]))
# return
rtrn = provision.provisionRelayForNetwork(spl[1], spl[2], spl[3])
#if rtrn == "PROVISIONED":
# failure("Relay %s already provisioned for alias %s on network %s" % (spl[1], spl[2], spl[3]))
# return
#elif rtrn == "DUPLICATE":
# failure("Instance with relay %s and alias %s already exists for network %s" % (spl[1], spl[2], spl[3]))
# return
if rtrn:
success("Started provisioning network %s on relay %s for alias %s" % (spl[3], spl[1], spl[2]))
info("Instance name is %s" % rtrn)
return
else:
failure("Failure while provisioning relay %s" % spl[1])
return
if length == 3: # provision for relay and alias only
rtrn = provision.provisionRelayForAlias(spl[1], spl[2])
#if rtrn == "PROVISIONED":
# failure("Relay %s already provisioned for alias %s" % (spl[1], spl[2]))
# return
if rtrn:
success("Started provisioning relay %s for alias %s" % (spl[1], spl[2]))
return
else:
failure("Failure while provisioning relay %s" % spl[1])
return
else:
incUsage("provision")
return
else:
incUsage(None)

View File

@ -7,29 +7,47 @@ class RelayCommand:
def relay(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length): def relay(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed: if authed:
if length == 7: if length == 3:
if spl[1] == "add": if spl[1] == "add":
if spl[2] not in main.network.keys(): if spl[2] in main.network.keys():
failure("No such network: %s" % spl[2]) id, alias = main.network[spl[2]].add_relay()
return
if not spl[4].isdigit():
failure("Port must be an integer, not %s" % spl[4])
return
else:
id, alias = main.network[spl[2]].add_relay(spl[3], spl[4], spl[5], spl[6])
success("Successfully created relay %s on network %s with alias %s" % (str(id), spl[2], alias)) success("Successfully created relay %s on network %s with alias %s" % (str(id), spl[2], alias))
main.saveConf("network") main.saveConf("network")
return return
else:
failure("No such network: %s" % spl[2])
return
elif spl[1] == "list":
if spl[2] not in main.network.keys():
failure("No such network: %s" % spl[2])
return
info(dump(main.network[spl[2]].relays))
return
else: else:
incUsage("relay") incUsage("relay")
return return
elif length == 4: elif length == 4:
if spl[1] == "del": if spl[1] == "add":
if spl[2] not in main.network.keys(): if spl[2] in main.network.keys():
if not spl[3].isdigit():
failure("Must be a number, not %s" % spl[3])
return
id, alias = main.network[spl[2]].add_relay(int(spl[3]))
success("Successfully created relay %s on network %s with alias %s" % (str(id), spl[2], alias))
main.saveConf("network")
return
else:
failure("No such network: %s" % spl[2]) failure("No such network: %s" % spl[2])
return return
if int(spl[3]) not in main.network[spl[2]].relays.keys(): elif spl[1] == "del":
if not spl[2] in main.network.keys():
failure("No such network: %s" % spl[2])
return
if not spl[3].isdigit():
failure("Must be a number, not %s" % spl[3])
return
if not int(spl[3]) in main.network[spl[2]].relays.keys():
failure("No such relay: %s on network %s" % (spl[3], 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])) main.network[spl[2]].delete_relay(int(spl[3]))
@ -39,16 +57,6 @@ class RelayCommand:
else: else:
incUsage("relay") incUsage("relay")
return return
elif length == 3:
if spl[1] == "list":
if spl[2] not in main.network.keys():
failure("No such network: %s" % spl[2])
return
info(dump(main.network[spl[2]].relays))
return
else:
incUsage("relay")
return
else: else:
incUsage("relay") incUsage("relay")
return return

40
commands/swho.py Normal file
View File

@ -0,0 +1,40 @@
import main
class SwhoCommand:
def __init__(self, *args):
self.swho(*args)
def swho(self, addr, authed, data, obj, spl, success, failure, info, incUsage, length):
if authed:
if length == 2:
if not spl[1] in main.network.keys():
failure("Network does not exist: %s" % spl[1])
return
for i in main.IRCPool.keys():
if spl[1] in i:
for x in main.IRCPool[i].channels:
main.IRCPool[i].who(x)
success("Sent WHO to all channels on all networks on %s" % spl[1])
return
elif length == 3:
if not spl[1] in main.network.keys():
failure("Network does not exist: %s" % spl[1])
return
matches = []
for i in main.IRCPool.keys():
if spl[1] in i:
for x in main.IRCPool[i].channels:
if x == spl[2]:
main.IRCPool[i].who(x)
matches.append(i)
if matches == []:
failure("No matches found for channel %s" % spl[2])
return
success("Sent WHO to %s on: %s" % (spl[2], ", ".join(matches)))
return
else:
incUsage("swho")
return
else:
incUsage(None)

View File

@ -4,7 +4,7 @@
"Address": "127.0.0.1", "Address": "127.0.0.1",
"UseSSL": true "UseSSL": true
}, },
"Relay": { "RelayAPI": {
"Enabled": true, "Enabled": true,
"Port": 13868, "Port": 13868,
"Address": "127.0.0.1", "Address": "127.0.0.1",
@ -16,6 +16,12 @@
"UsePassword": true, "UsePassword": true,
"ConnectOnCreate": false, "ConnectOnCreate": false,
"Debug": false, "Debug": false,
"Relay": {
"Host": "127.0.0.1",
"Port": "201x",
"User": "sir",
"Password": "sir"
},
"Dist": { "Dist": {
"Enabled": true, "Enabled": true,
"SendOutput": false, "SendOutput": false,

View File

@ -1,27 +1,27 @@
{ {
"pass": "pass <password>", "pass": "pass <password>",
"logout": "logout", "logout": "logout",
"del": "del <network> <relay>", "del": "del <name>",
"mod": "mod <network> <variable> <value>", "mod": "mod <name> [<key>] [<value>]",
"get": "get <name> <variable>",
"who": "who <query>", "who": "who <query>",
"join": "join <network> <relay> <channel> [<key>]", "join": "join <name> <num> <channel> [<key>]",
"part": "part <network> <relay> <channel>", "part": "part <name> <num> <channel>",
"enable": "enable <network> <id>", "enable": "enable <name> <num>",
"disable": "disable <network> <id>", "disable": "disable <name> <num>",
"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 <network> <relay> <target> <message...>", "msg": "msg <name> <target> <message...>",
"mon": "mon -h", "mon": "mon -h",
"chans": "chans <nick> [<nick> ...]", "chans": "chans <nick> [<nick> ...]",
"users": "users <channel> [<channel> ...]", "users": "users <channel> [<channel> ...]",
"relay": "relay <add|del|list> [<network> <host> <port> <user> <password> | <network> <id> | <network>]", "relay": "relay <add|del|list> [<network>] [<num>]",
"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>]", "auto": "auto <network> <relay>",
"cmd": "cmd <network> <relay> <user> <entity> <text ...>", "cmd": "cmd <relay> <user> <entity> <text ...>",
"token": "token <add|del|list> [<key>] [<relay>]", "token": "token <add|del|list> [<key>] [<relay>]",
"all": "all <entity> <text ...>", "all": "all <entity> <text ...>",
"allc": "allc <network|alias> <(network)|(alias)> <entity> <text ...>" "allc": "allc <network|alias> <(network)|(alias)> <entity> <text ...>"

View File

@ -1 +0,0 @@
[]

View File

@ -14,6 +14,7 @@ from modules import monitor
from core.relay import sendRelayNotification from core.relay import sendRelayNotification
from utils.dedup import dedup from utils.dedup import dedup
from utils.getrelay import getRelay
import main import main
from utils.logging.log import * from utils.logging.log import *
@ -21,33 +22,34 @@ 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(num, relayCommands, user=None, stage2=None):
# where relay is a dictionary extracted from the Network object # 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(net=None, num=num, relayCommands=relayCommands, user=user, stage2=stage2)
rct = reactor.connectSSL(relay["host"], host, port = getRelay(num)
int(relay["port"]), rct = reactor.connectSSL(host,
port,
bot, contextFactory) bot, contextFactory)
class IRCRelay(IRCClient): class IRCRelay(IRCClient):
def __init__(self, relay, relayCommands, user, stage2): def __init__(self, num, relayCommands, user, stage2):
self.connected = False self.connected = False
self.buffer = "" self.buffer = ""
if user == None: if user == None:
self.user = relay["user"] self.user = main.config["Relay"]["User"]
else: else:
self.user = user self.user = user
password = relay["password"] password = main.config["Relay"]["Password"]
self.nickname = self.user self.nickname = "relay"
self.realname = self.user self.realname = "relay"
self.username = self.user self.username = self.user
self.password = self.user+":"+password self.password = self.user+":"+password
self.relayCommands = relayCommands self.relayCommands = relayCommands
self.relay = relay self.num = num
self.stage2 = stage2 self.stage2 = stage2
def parsen(self, user): def parsen(self, user):
@ -67,15 +69,16 @@ class IRCRelay(IRCClient):
if nick[0] == main.config["Tweaks"]["ZNC"]["Prefix"]: if nick[0] == main.config["Tweaks"]["ZNC"]["Prefix"]:
nick = nick[1:] nick = nick[1:]
if nick in self.relayCommands.keys(): if nick in self.relayCommands.keys():
sendAll("[%s] %s -> %s" % (self.relay, nick, msg)) sendAll("[%s] %s -> %s" % (self.num, nick, msg))
def irc_ERR_PASSWDMISMATCH(self, prefix, params): def irc_ERR_PASSWDMISMATCH(self, prefix, params):
log("%s: relay password mismatch" % self.relay) print(', '.join("%s: %s" % item for item in vars(self).items()))
sendAll("%s: relay password mismatch" % self.relay) log("%s: relay password mismatch" % self.num)
sendAll("%s: relay password mismatch" % self.num)
def signedOn(self): def signedOn(self):
self.connected = True self.connected = True
log("signed on as a relay: %s" % self.relay) log("signed on as a relay: %s" % self.num)
#sendRelayNotification("Relay", {"type": "conn", "status": "connected"}) nobody actually cares #sendRelayNotification("Relay", {"type": "conn", "status": "connected"}) nobody actually cares
for i in self.relayCommands.keys(): for i in self.relayCommands.keys():
for x in self.relayCommands[i]: for x in self.relayCommands[i]:
@ -85,25 +88,24 @@ class IRCRelay(IRCClient):
user = self.stage2[0].pop(0) user = self.stage2[0].pop(0)
commands = self.stage2[0].pop(0) commands = self.stage2[0].pop(0)
del self.stage2[0] del self.stage2[0]
deliverRelayCommands(self.relay, commands, user, self.stage2) deliverRelayCommands(self.num, commands, user, self.stage2)
deferLater(reactor, 1, self.transport.loseConnection) deferLater(reactor, 1, self.transport.loseConnection)
return return
class IRCBot(IRCClient): class IRCBot(IRCClient):
def __init__(self, name, relay): def __init__(self, net, num):
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 = net
if self.net == "": self.num = num
error("Network with all numbers: %s" % name)
self.buffer = "" self.buffer = ""
self.name = name self.name = net + str(num)
alias = relay["alias"] alias = main.network[self.net].aliases[num]
relay = main.network[self.net].relays[num]
self.nickname = alias["nick"] self.nickname = alias["nick"]
self.realname = alias["realname"] self.realname = alias["realname"]
self.username = alias["nick"]+"/"+relay["net"] self.username = alias["nick"]+"/"+relay["net"]
self.password = relay["password"] self.password = main.config["Relay"]["Password"]
self.userinfo = None self.userinfo = None
self.fingerReply = None self.fingerReply = None
self.versionName = None self.versionName = None
@ -445,26 +447,30 @@ class IRCBot(IRCClient):
self.event(type="mode", muser=user, target=channel, modes=m, status=toset, modeargs=a) self.event(type="mode", muser=user, target=channel, modes=m, status=toset, modeargs=a)
class IRCBotFactory(ReconnectingClientFactory): class IRCBotFactory(ReconnectingClientFactory):
def __init__(self, name, relay=None, relayCommands=None, user=None, stage2=None): def __init__(self, net, num=None, relayCommands=None, user=None, stage2=None):
if not name == None: if net == None:
self.name = name self.num = num
self.net = "".join([x for x in self.name if not x in digits]) self.name = "Relay to %i" % num
self.relay = True
else: else:
self.name = "Relay to "+relay["net"]+relay["id"] self.name = net + str(num)
self.num = num
self.net = net
self.relay = False
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"]
self.factor = main.config["Tweaks"]["Delays"]["Factor"] self.factor = main.config["Tweaks"]["Delays"]["Factor"]
self.jitter = main.config["Tweaks"]["Delays"]["Jitter"] self.jitter = main.config["Tweaks"]["Delays"]["Jitter"]
self.relay, self.relayCommands, self.user, self.stage2 = relay, relayCommands, user, stage2 self.relayCommands, self.user, self.stage2 = relayCommands, user, stage2
def buildProtocol(self, addr): def buildProtocol(self, addr):
if self.relay == None: if self.net == None:
entry = IRCBot(self.name, self.relay) entry = IRCRelay(self.num, self.relayCommands, self.user, self.stage2)
main.IRCPool[self.name] = entry
else: else:
entry = IRCRelay(self.relay, self.relayCommands, self.user, self.stage2) entry = IRCBot(self.net, self.num)
main.IRCPool[self.name] = entry
self.client = entry self.client = entry
return entry return entry

View File

@ -108,7 +108,7 @@ class Relay(Protocol):
return return
def connectionMade(self): def connectionMade(self):
log("Connection from %s:%s" % (self.addr.host, self.addr.port)) log("Relay connection from %s:%s" % (self.addr.host, self.addr.port))
#self.send("Greetings.") #self.send("Greetings.")
def connectionLost(self, reason): def connectionLost(self, reason):

View File

@ -1,14 +1,16 @@
from twisted.internet.ssl import DefaultOpenSSLContextFactory
import json import json
import modules.alias as alias import modules.alias as alias
from twisted.internet import reactor from twisted.internet import reactor
from core.bot import IRCBot, IRCBotFactory from core.bot import IRCBot, IRCBotFactory
from twisted.internet.ssl import DefaultOpenSSLContextFactory
import main import main
from utils.logging.log import * from utils.logging.log import *
from utils.getrelay import getRelay
class Network: class Network:
def __init__(self, name, host, port, security, auth): def __init__(self, net, host, port, security, auth):
self.name = name self.net = net
self.host = host self.host = host
self.port = port self.port = port
self.security = security self.security = security
@ -18,40 +20,39 @@ class Network:
self.relays = {} self.relays = {}
self.aliases = {} self.aliases = {}
def add_relay(self, host, port, user, password): def add_relay(self, num=None):
self.last += 1 if not num:
self.relays[self.last] = { self.last += 1
"host": host, num = self.last
"port": port, self.relays[num] = {
"user": user,
"password": password,
"enabled": False, "enabled": False,
"net": self.name, "net": self.net,
"id": self.last "id": num
} }
self.aliases[self.last] = alias.generate_alias() self.aliases[num] = alias.generate_alias()
return self.last, self.aliases[self.last]["nick"] return num, self.aliases[num]["nick"]
def delete_relay(self, id): def delete_relay(self, id):
del self.relays[id] del self.relays[id]
del self.aliases[id] del self.aliases[id]
def start_bot(self, relay): def start_bot(self, num):
# a single name is given to relays in the backend # a single name is given to relays in the backend
# e.g. freenode1 for the first relay on freenode network # e.g. freenode1 for the first relay on freenode network
name = self.name + relay
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(keyFN.encode("utf-8", "replace"), certFN.encode("utf-8", "replace"))
bot = IRCBotFactory(name) bot = IRCBotFactory(self.net, num)
rct = reactor.connectSSL(k, port, bot, contextFactory) #host, port = self.relays[num]["host"], self.relays[num]["port"]
host, port = getRelay(num)
rct = reactor.connectSSL(host, port, bot, contextFactory)
name = self.net + str(num)
main.ReactorPool[name] = rct main.ReactorPool[name] = rct
main.FactoryPool[name] = bot main.FactoryPool[name] = bot
log("Started bot on relay %s on %s", (relay, self.host)) log("Started bot on relay %s on %s" % (num, self.host))
def start_bots(self): def start_bots(self):
for relay in self.relays: for num in self.relays.keys():
if relay["enabled"]: if self.relays[num]["enabled"]:
start_bot(relay) self.start_bot(num)

View File

@ -1,36 +1,35 @@
import main import main
from core.bot import deliverRelayCommands from core.bot import deliverRelayCommands
from utils.logging.log import * from utils.logging.log import *
from core.helper import startBot
def provisionUserData(relay, alias, nick, altnick, ident, realname, password): def provisionUserData(num, nick, altnick, ident, realname, unused): # last field is password, which we don't want to inherit here, but still want to use * expansion, so this is a bit of a hack
commands = {} commands = {}
commands["controlpanel"] = [] commands["controlpanel"] = []
commands["controlpanel"].append("AddUser %s %s" % (alias, password)) commands["controlpanel"].append("AddUser %s %s" % (nick, main.config["Relay"]["Password"]))
commands["controlpanel"].append("Set Nick %s %s" % (alias, nick)) commands["controlpanel"].append("Set Nick %s %s" % (nick, nick))
commands["controlpanel"].append("Set Altnick %s %s" % (alias, altnick)) commands["controlpanel"].append("Set Altnick %s %s" % (nick, altnick))
commands["controlpanel"].append("Set Ident %s %s" % (alias, ident)) commands["controlpanel"].append("Set Ident %s %s" % (nick, ident))
commands["controlpanel"].append("Set RealName %s %s" % (alias, realname)) commands["controlpanel"].append("Set RealName %s %s" % (nick, realname))
deliverRelayCommands(relay, commands) deliverRelayCommands(num, commands)
return return
def provisionNetworkData(relay, alias, network, host, port, security, auth, password): def provisionNetworkData(num, nick, network, host, port, security, auth, password):
commands = {} commands = {}
stage2commands = {} stage2commands = {}
stage3commands = {} stage3commands = {}
commands["controlpanel"] = [] commands["controlpanel"] = []
commands["controlpanel"].append("AddNetwork %s %s" % (alias, network)) commands["controlpanel"].append("AddNetwork %s %s" % (nick, network))
if security == "ssl": if security == "ssl":
commands["controlpanel"].append("SetNetwork TrustAllCerts %s %s true" % (alias, network)) # Don't judge me commands["controlpanel"].append("SetNetwork TrustAllCerts %s %s true" % (nick, network)) # Don't judge me
commands["controlpanel"].append("AddServer %s %s %s +%s" % (alias, network, host, port)) commands["controlpanel"].append("AddServer %s %s %s +%s" % (nick, network, host, port))
elif security == "plain": elif security == "plain":
commands["controlpanel"].append("AddServer %s %s %s %s" % (alias, network, host, port)) commands["controlpanel"].append("AddServer %s %s %s %s" % (nick, network, host, port))
if auth == "sasl": if auth == "sasl":
stage2commands["status"] = [] stage2commands["status"] = []
stage2commands["sasl"] = [] stage2commands["sasl"] = []
stage2commands["status"].append("LoadMod sasl") stage2commands["status"].append("LoadMod sasl")
stage2commands["sasl"].append("Mechanism plain") stage2commands["sasl"].append("Mechanism plain")
stage2commands["sasl"].append("Set %s %s" % (alias, password)) stage2commands["sasl"].append("Set %s %s" % (nick, password))
elif auth == "ns": elif auth == "ns":
stage2commands["status"] = [] stage2commands["status"] = []
stage2commands["nickserv"] = [] stage2commands["nickserv"] = []
@ -43,60 +42,23 @@ def provisionNetworkData(relay, alias, network, host, port, security, auth, pass
stage2commands["status"] = [] stage2commands["status"] = []
stage2commands["status"].append("LoadMod disconkick") stage2commands["status"].append("LoadMod disconkick")
stage2commands["status"].append("LoadMod chansaver") stage2commands["status"].append("LoadMod chansaver")
deliverRelayCommands(relay, commands, deliverRelayCommands(num, commands,
stage2=[[alias+"/"+network, stage2commands], stage2=[[nick+"/"+network, stage2commands],
[alias+"/"+network, stage3commands]]) [nick+"/"+network, stage3commands]])
return return
def provisionRelayForAlias(relay, alias): def provisionRelayForNetwork(num, alias, network):
#if "users" in main.relay[relay].keys(): provisionNetworkData(num, alias, network,
# if alias in main.relay[relay]["users"]: main.network[network].host,
# return "PROVISIONED" main.network[network].port,
#else: main.network[network].security,
# main.relay[relay]["users"] = [] main.network[network].auth,
#main.relay[relay]["users"].append(alias) main.network[network].aliases[num]["password"])
provisionUserData(relay, alias, main.alias[alias]["nick"], return
main.alias[alias]["altnick"],
main.alias[alias]["ident"],
main.alias[alias]["realname"],
main.relay[relay]["password"])
#main.saveConf("relay")
return True
def provisionRelayForNetwork(relay, alias, network): def provisionRelay(num, network):
#if set(["users", "networks"]).issubset(main.relay[relay].keys()): aliasObj = main.network[network].aliases[num]
# if network in main.relay[relay]["networks"] and alias in main.relay[relay]["users"]: alias = aliasObj["nick"]
# return "PROVISIONED" provisionUserData(num, *aliasObj.values())
#else: provisionRelayForNetwork(num, alias, network)
# main.relay[relay]["networks"] = [] return alias
#main.relay[relay]["networks"].append(network)
provisionNetworkData(relay, alias, network,
main.network[network]["host"],
main.network[network]["port"],
main.network[network]["security"],
main.network[network]["auth"],
main.alias[alias]["password"])
#main.saveConf("relay")
storedNetwork = False
num = 1
while not storedNetwork:
i = str(num)
if num == 1000:
error("Iteration limit exceeded while trying to choose name for r: %s a: %s n: %s" % (relay, alias, network))
return False
if network+i in main.pool.keys():
if main.pool[network+i]["alias"] == alias and main.pool[network+i]["relay"] == relay:
return "DUPLICATE"
num += 1
else:
main.pool[network+i] = {"relay": relay,
"alias": alias,
"network": network,
"enabled": main.config["ConnectOnCreate"]}
main.saveConf("pool")
if main.config["ConnectOnCreate"]:
startBot(network+i)
storedNetwork = True
return network+i

View File

@ -29,14 +29,14 @@ if __name__ == "__main__":
else: else:
reactor.listenTCP(main.config["Listener"]["Port"], listener, interface=main.config["Listener"]["Address"]) reactor.listenTCP(main.config["Listener"]["Port"], listener, interface=main.config["Listener"]["Address"])
log("Threshold running on %s:%s" % (main.config["Listener"]["Address"], main.config["Listener"]["Port"])) log("Threshold running on %s:%s" % (main.config["Listener"]["Address"], main.config["Listener"]["Port"]))
if main.config["Relay"]["Enabled"]: if main.config["RelayAPI"]["Enabled"]:
relay = RelayFactory() relay = RelayFactory()
if main.config["Relay"]["UseSSL"] == True: if main.config["RelayAPI"]["UseSSL"] == True:
reactor.listenSSL(main.config["Relay"]["Port"], relay, DefaultOpenSSLContextFactory(main.certPath+main.config["Key"], main.certPath+main.config["Certificate"]), interface=main.config["Relay"]["Address"]) reactor.listenSSL(main.config["RelayAPI"]["Port"], relay, DefaultOpenSSLContextFactory(main.certPath+main.config["Key"], main.certPath+main.config["Certificate"]), interface=main.config["RelayAPI"]["Address"])
log("Threshold relay running with SSL on %s:%s" % (main.config["Relay"]["Address"], main.config["Relay"]["Port"])) log("Threshold relay running with SSL on %s:%s" % (main.config["RelayAPI"]["Address"], main.config["RelayAPI"]["Port"]))
else: else:
reactor.listenTCP(main.config["Relay"]["Port"], relay, interface=main.config["Relay"]["Address"]) reactor.listenTCP(main.config["RelayAPI"]["Port"], relay, interface=main.config["RelayAPI"]["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["RelayAPI"]["Address"], main.config["RelayAPI"]["Port"]))
for net in main.network.keys(): for net in main.network.keys():
main.network[net].start_bots() main.network[net].start_bots()
modules.counters.setupCounterLoop() modules.counters.setupCounterLoop()

12
utils/getrelay.py Normal file
View File

@ -0,0 +1,12 @@
import main
def getRelay(num):
host = main.config["Relay"]["Host"].replace("x", str(num))
port = int(str(main.config["Relay"]["Port"]).replace("x", str(num)))
user = main.config["Relay"]["User"]
password = main.config["Relay"]["Password"]
try:
port = int(port)
except ValueError:
return False
return [host, port]

View File

@ -1,6 +1,7 @@
from os import listdir from os import listdir
from utils.logging.debug import debug from utils.logging.debug import debug
from utils.logging.log import *
import commands import commands
from main import CommandMap from main import CommandMap