2019-08-11 20:58:14 +00:00
|
|
|
import json
|
|
|
|
import pickle
|
2022-07-21 12:40:01 +00:00
|
|
|
from os import urandom
|
2022-07-28 20:11:01 +00:00
|
|
|
from os.path import exists
|
2022-07-21 12:40:09 +00:00
|
|
|
from string import digits
|
|
|
|
|
|
|
|
from redis import StrictRedis
|
2022-07-29 07:31:01 +00:00
|
|
|
from os import getenv
|
2019-08-15 20:20:49 +00:00
|
|
|
|
2019-12-07 16:35:29 +00:00
|
|
|
# List of errors ZNC can give us
|
2022-07-21 12:39:41 +00:00
|
|
|
ZNCErrors = ["Error:", "Unable to load", "does not exist", "doesn't exist"]
|
2019-10-13 11:38:44 +00:00
|
|
|
|
2022-07-29 07:32:39 +00:00
|
|
|
configPath = "conf/live/"
|
|
|
|
templateConfigPath = "conf/templates/"
|
|
|
|
certPath = "conf/cert/"
|
2018-02-23 22:05:40 +00:00
|
|
|
|
|
|
|
filemap = {
|
2019-08-11 20:58:14 +00:00
|
|
|
# JSON configs
|
|
|
|
"config": ["config.json", "configuration", "json"],
|
|
|
|
"help": ["help.json", "command help", "json"],
|
|
|
|
"counters": ["counters.json", "counters file", "json"],
|
|
|
|
"tokens": ["tokens.json", "authentication tokens", "json"],
|
|
|
|
"aliasdata": ["aliasdata.json", "data for alias generation", "json"],
|
2019-09-29 21:45:16 +00:00
|
|
|
"alias": ["alias.json", "provisioned alias data", "json"],
|
2019-12-28 17:50:38 +00:00
|
|
|
"irc": ["irc.json", "IRC network definitions", "json"],
|
2020-11-01 19:54:24 +00:00
|
|
|
"blacklist": ["blacklist.json", "IRC channel blacklist", "json"],
|
2019-08-11 20:58:14 +00:00
|
|
|
# Binary (pickle) configs
|
2022-07-21 12:39:41 +00:00
|
|
|
"network": ["network.dat", "network list", "pickle"],
|
2019-08-11 21:01:29 +00:00
|
|
|
}
|
2018-02-23 22:05:40 +00:00
|
|
|
|
2019-12-07 16:35:29 +00:00
|
|
|
# Connections to the plain-text interface
|
2018-02-23 22:05:40 +00:00
|
|
|
connections = {}
|
2019-12-07 16:35:29 +00:00
|
|
|
# Connections to the JSON interface
|
2019-03-18 21:01:28 +00:00
|
|
|
relayConnections = {}
|
2019-12-07 16:35:29 +00:00
|
|
|
|
|
|
|
# Mapping of network names to Protocol (IRCClient) instances
|
2018-02-23 22:05:40 +00:00
|
|
|
IRCPool = {}
|
2019-12-07 16:35:29 +00:00
|
|
|
|
|
|
|
# Mapping of network names to Reactor instances
|
|
|
|
# Needed for calling .disconnect()
|
2018-02-23 22:05:40 +00:00
|
|
|
ReactorPool = {}
|
2019-12-07 16:35:29 +00:00
|
|
|
|
|
|
|
# Mapping of network names to Factory instances
|
|
|
|
# Needed for calling .stopTrying()
|
2018-02-23 22:05:40 +00:00
|
|
|
FactoryPool = {}
|
|
|
|
|
2019-12-07 16:35:29 +00:00
|
|
|
# Temporary store for channels allocated after a LIST
|
|
|
|
# Will get purged as the instances fire up and pop() from
|
|
|
|
# their respective keys in here
|
|
|
|
TempChan = {}
|
2018-02-23 22:05:40 +00:00
|
|
|
|
2019-12-07 16:35:29 +00:00
|
|
|
# Mapping of command names to their functions
|
2018-02-23 22:05:40 +00:00
|
|
|
CommandMap = {}
|
|
|
|
|
2019-12-07 16:35:29 +00:00
|
|
|
# Incremented by 1 for each event reaching modules.counters.event()
|
|
|
|
# and cloned into lastMinuteSample every minute
|
2019-07-28 14:07:46 +00:00
|
|
|
runningSample = 0
|
|
|
|
lastMinuteSample = 0
|
|
|
|
|
2019-08-15 20:20:49 +00:00
|
|
|
# Generate 16-byte hex key for message checksums
|
|
|
|
hashKey = urandom(16)
|
|
|
|
lastEvents = {}
|
|
|
|
|
2022-07-21 12:40:05 +00:00
|
|
|
|
2019-12-07 16:35:29 +00:00
|
|
|
# Get networks that are currently online and dedupliate
|
2018-10-21 16:14:50 +00:00
|
|
|
def liveNets():
|
|
|
|
networks = set()
|
|
|
|
for i in IRCPool.keys():
|
2022-07-21 12:40:05 +00:00
|
|
|
networks.add("".join([x for x in i if x not in digits]))
|
2018-10-14 13:47:08 +00:00
|
|
|
return networks
|
|
|
|
|
2022-07-21 12:39:41 +00:00
|
|
|
|
2018-02-23 22:05:40 +00:00
|
|
|
def saveConf(var):
|
2022-07-29 07:31:01 +00:00
|
|
|
if var in ("help", "aliasdata"):
|
|
|
|
return # no need to save this
|
2019-08-11 20:58:14 +00:00
|
|
|
if filemap[var][2] == "json":
|
2022-07-21 12:39:41 +00:00
|
|
|
with open(configPath + filemap[var][0], "w") as f:
|
2019-08-11 20:58:14 +00:00
|
|
|
json.dump(globals()[var], f, indent=4)
|
|
|
|
elif filemap[var][2] == "pickle":
|
2022-07-21 12:39:41 +00:00
|
|
|
with open(configPath + filemap[var][0], "wb") as f:
|
2019-08-11 20:58:14 +00:00
|
|
|
pickle.dump(globals()[var], f)
|
|
|
|
else:
|
|
|
|
raise Exception("invalid format")
|
2018-02-23 22:05:40 +00:00
|
|
|
|
2022-07-21 12:39:41 +00:00
|
|
|
|
2018-02-23 22:05:40 +00:00
|
|
|
def loadConf(var):
|
2019-08-11 20:58:14 +00:00
|
|
|
if filemap[var][2] == "json":
|
2022-07-28 20:11:01 +00:00
|
|
|
filename = configPath + filemap[var][0]
|
2022-07-29 07:31:01 +00:00
|
|
|
# Only take the help from the templates
|
|
|
|
if var in ("help", "aliasdata"):
|
|
|
|
filename = templateConfigPath + filemap[var][0]
|
2022-07-28 20:11:01 +00:00
|
|
|
if not exists(filename):
|
2022-07-29 07:31:01 +00:00
|
|
|
# Load the template config
|
2022-07-28 20:11:01 +00:00
|
|
|
if var == "config":
|
2022-07-29 07:31:01 +00:00
|
|
|
filename = templateConfigPath + filemap[var][0]
|
2022-07-28 20:11:01 +00:00
|
|
|
else:
|
2022-07-29 07:31:01 +00:00
|
|
|
# Everything else should be blank
|
2022-07-28 20:11:01 +00:00
|
|
|
globals()[var] = {}
|
|
|
|
return
|
|
|
|
with open(filename, "r") as f:
|
2019-08-11 20:58:14 +00:00
|
|
|
globals()[var] = json.load(f)
|
2019-09-29 21:45:16 +00:00
|
|
|
if var == "alias":
|
2019-12-07 16:35:29 +00:00
|
|
|
# This is a workaround to convert all the keys into integers since JSON
|
2019-09-29 21:45:16 +00:00
|
|
|
# turns them into strings...
|
|
|
|
# Dammit Jason!
|
|
|
|
global alias
|
2022-07-21 12:39:41 +00:00
|
|
|
alias = {int(x): y for x, y in alias.items()}
|
2022-07-29 07:31:01 +00:00
|
|
|
|
2019-08-11 20:58:14 +00:00
|
|
|
elif filemap[var][2] == "pickle":
|
|
|
|
try:
|
2022-07-21 12:39:41 +00:00
|
|
|
with open(configPath + filemap[var][0], "rb") as f:
|
2019-08-11 20:58:14 +00:00
|
|
|
globals()[var] = pickle.load(f)
|
|
|
|
except FileNotFoundError:
|
|
|
|
globals()[var] = {}
|
|
|
|
else:
|
|
|
|
raise Exception("invalid format")
|
2018-02-23 22:05:40 +00:00
|
|
|
|
2022-07-21 12:39:41 +00:00
|
|
|
|
2018-02-23 22:05:40 +00:00
|
|
|
def initConf():
|
|
|
|
for i in filemap.keys():
|
|
|
|
loadConf(i)
|
|
|
|
|
2022-07-21 12:39:41 +00:00
|
|
|
|
2018-02-23 22:05:40 +00:00
|
|
|
def initMain():
|
2019-10-08 20:07:54 +00:00
|
|
|
global r, g
|
2018-02-23 22:05:40 +00:00
|
|
|
initConf()
|
2022-07-21 12:40:03 +00:00
|
|
|
r = StrictRedis(
|
2022-07-21 12:40:05 +00:00
|
|
|
unix_socket_path=config["RedisSocket"], db=config["RedisDBEphemeral"] # noqa
|
2022-07-21 12:40:03 +00:00
|
|
|
) # Ephemeral - flushed on quit
|
2022-07-21 12:40:05 +00:00
|
|
|
g = StrictRedis(unix_socket_path=config["RedisSocket"], db=config["RedisDBPersistent"]) # noqa
|