234 lines
7.7 KiB
Python
234 lines
7.7 KiB
Python
from copy import deepcopy
|
|
from random import choice
|
|
|
|
import main
|
|
from modules import provision
|
|
from utils.logging.debug import debug
|
|
from utils.logging.log import error
|
|
|
|
|
|
def needToRegister(net):
|
|
# Check if the network does not support authentication
|
|
networkObj = main.network[net]
|
|
if networkObj.auth == "none":
|
|
return False
|
|
# Check if the IRC network definition has registration disabled
|
|
inst = selectInst(net)
|
|
if "register" in inst.keys():
|
|
if inst["register"]:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def needToAuth(net):
|
|
networkObj = main.network[net]
|
|
if networkObj.auth == "none":
|
|
return False
|
|
return True
|
|
|
|
|
|
def selectInst(net):
|
|
if net in main.irc.keys():
|
|
inst = deepcopy(main.irc[net])
|
|
for i in main.irc["_"].keys():
|
|
if i not in inst:
|
|
inst[i] = main.irc["_"][i]
|
|
else:
|
|
inst = deepcopy(main.irc["_"])
|
|
return inst
|
|
|
|
|
|
def substitute(net, num, token=None):
|
|
inst = selectInst(net)
|
|
alias = main.alias[num]
|
|
gotemail = False
|
|
if "emails" in alias:
|
|
# First priority is explicit email lists
|
|
if alias["emails"]:
|
|
email = choice(alias["emails"])
|
|
gotemail = True
|
|
if "domains" in inst:
|
|
if inst["domains"]:
|
|
if not gotemail:
|
|
domain = choice(inst["domains"])
|
|
email = f"{alias['nickname']}@{domain}"
|
|
gotemail = True
|
|
if not gotemail:
|
|
inst["email"] = False
|
|
nickname = alias["nick"]
|
|
# username = nickname + "/" + net
|
|
password = main.network[net].aliases[num]["password"]
|
|
# inst["email"] = inst["email"].replace("{nickname}", nickname)
|
|
|
|
name = f"{net}{num}"
|
|
if name in main.IRCPool:
|
|
curnick = main.IRCPool[name].nickname
|
|
else:
|
|
curnick = nickname
|
|
for i in inst.keys():
|
|
if not isinstance(inst[i], str):
|
|
continue
|
|
inst[i] = inst[i].replace("{nickname}", nickname)
|
|
inst[i] = inst[i].replace("{curnick}", curnick)
|
|
inst[i] = inst[i].replace("{password}", password)
|
|
if gotemail:
|
|
inst[i] = inst[i].replace("{email}", email)
|
|
if token:
|
|
inst[i] = inst[i].replace("{token}", token)
|
|
return inst
|
|
|
|
|
|
def registerAccount(net, num):
|
|
debug("Attempting to register: %s - %i" % (net, num))
|
|
sinst = substitute(net, num)
|
|
if not sinst:
|
|
error(f"Register account failed for {net} - {num}")
|
|
return
|
|
if not sinst["email"]:
|
|
error(f"Could not get email for {net} - {num}")
|
|
return
|
|
if not sinst["register"]:
|
|
error("Cannot register for %s: function disabled" % (net))
|
|
return False
|
|
name = net + str(num)
|
|
if not main.IRCPool[name].authenticated:
|
|
main.IRCPool[name].msg(sinst["entity"], sinst["registermsg"])
|
|
|
|
|
|
def confirmAccount(net, num, token):
|
|
sinst = substitute(net, num, token=token)
|
|
name = net + str(num)
|
|
if name in main.IRCPool:
|
|
main.IRCPool[name].msg(sinst["entity"], sinst["confirm"])
|
|
enableAuthentication(net, num)
|
|
|
|
|
|
def confirmRegistration(net, num, negativepass=None):
|
|
obj = main.network[net]
|
|
name = net + str(num)
|
|
if name in main.IRCPool.keys():
|
|
if negativepass is not None:
|
|
main.IRCPool[name].regPing(negativepass=negativepass)
|
|
return
|
|
debug("Relay authenticated: %s - %i" % (net, num))
|
|
main.IRCPool[name].authenticated = True
|
|
main.IRCPool[name].recheckList()
|
|
if obj.relays[num]["registered"]:
|
|
return
|
|
if name in main.IRCPool.keys():
|
|
if main.IRCPool[name]._regAttempt:
|
|
try:
|
|
main.IRCPool[name]._regAttempt.cancel()
|
|
except: # noqa
|
|
pass
|
|
obj.relays[num]["registered"] = True
|
|
main.saveConf("network")
|
|
|
|
|
|
def attemptManualAuthentication(net, num):
|
|
sinst = substitute(net, num)
|
|
identifymsg = sinst["identifymsg"]
|
|
entity = sinst["entity"]
|
|
name = f"{net}{num}"
|
|
if name not in main.IRCPool:
|
|
return
|
|
main.IRCPool[name].sendmsg(entity, identifymsg, in_query=True)
|
|
|
|
|
|
def enableAuthentication(net, num, jump=True, run_now=False):
|
|
obj = main.network[net]
|
|
nick = main.alias[num]["nick"]
|
|
auth = obj.auth
|
|
name = f"{net}{num}"
|
|
if name not in main.IRCPool:
|
|
return
|
|
# uname = main.alias[num]["nick"] + "/" + net
|
|
password = main.network[net].aliases[num]["password"]
|
|
provision.provisionAuthenticationData(num, nick, net, auth, password) # Set up for auth
|
|
if jump:
|
|
main.IRCPool[name].msg(main.config["Tweaks"]["ZNC"]["Prefix"] + "status", "Jump")
|
|
if run_now:
|
|
attemptManualAuthentication(net, num)
|
|
if selectInst(net)["check"] is False:
|
|
confirmRegistration(net, num)
|
|
|
|
|
|
def get_unregistered_relays(net=None):
|
|
"""
|
|
Get a dict of unregistereed relays, either globally or
|
|
for a network.
|
|
Returns:
|
|
{"net": [["nick1", 1], ["nick2", 2], ...]}
|
|
"""
|
|
unreg = {}
|
|
if net:
|
|
nets = [net]
|
|
else:
|
|
nets = main.network.keys()
|
|
for i in nets:
|
|
for num in main.network[i].relays.keys():
|
|
if not main.network[i].relays[num]["registered"]:
|
|
nick = main.alias[num]["nick"]
|
|
if i in unreg:
|
|
unreg[i].append([nick, num])
|
|
else:
|
|
unreg[i] = [[nick, num]]
|
|
return unreg
|
|
|
|
|
|
def registerTest(c):
|
|
sinst = substitute(c["net"], c["num"])
|
|
name = c["net"] + str(c["num"])
|
|
net = c["net"]
|
|
num = c["num"]
|
|
if sinst["check"] is False:
|
|
return
|
|
if "msg" in c.keys() and not c["msg"] is None:
|
|
if sinst["negative"]:
|
|
if name in main.IRCPool.keys():
|
|
if main.IRCPool[name]._negativePass is not True:
|
|
if c["type"] == "query" and c["nick"] == sinst["entity"]:
|
|
if sinst["checknegativemsg"] in c["msg"]:
|
|
confirmRegistration(
|
|
c["net"], c["num"], negativepass=False
|
|
) # Not passed negative check, report back
|
|
return
|
|
if sinst["checkendnegative"] in c["msg"]:
|
|
confirmRegistration(
|
|
c["net"], c["num"], negativepass=True
|
|
) # Passed the negative check, report back
|
|
return
|
|
if sinst["ping"]:
|
|
if sinst["checkmsg2"] in c["msg"] and c["nick"] == sinst["entity"]:
|
|
confirmRegistration(c["net"], c["num"])
|
|
debug(
|
|
(
|
|
f"registerTest() {net} - {num} passed ping:checkmsg2 "
|
|
f"check, {sinst['checkmsg2']} present in message"
|
|
)
|
|
)
|
|
return
|
|
if sinst["checktype"] == "msg":
|
|
if sinst["checkmsg"] in c["msg"]:
|
|
confirmRegistration(c["net"], c["num"])
|
|
debug(
|
|
(
|
|
f"registerTest() {net} - {num} passed checktype:msg:checkmsg check, "
|
|
f"{sinst['checkmsg']} present in message"
|
|
)
|
|
)
|
|
return
|
|
elif sinst["checktype"] == "mode":
|
|
if c["type"] == "self":
|
|
if c["mtype"] == "mode":
|
|
if sinst["checkmode"] in c["mode"] and c["status"] is True:
|
|
confirmRegistration(c["net"], c["num"])
|
|
debug(
|
|
(
|
|
f"registerTest() {net} - {num} passed checktype:mode:checkmost check, "
|
|
f"{sinst['checkmode']} present in mode"
|
|
)
|
|
)
|
|
return
|