You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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