Fix capability negotiation to be more sane (and IRCv3.2-compliant)
This commit is contained in:
parent
1a506907c9
commit
452c1b1ede
@ -186,19 +186,15 @@ class IRCClient(object):
|
|||||||
if not self.blocking:
|
if not self.blocking:
|
||||||
self.socket.setblocking(0)
|
self.socket.setblocking(0)
|
||||||
|
|
||||||
|
self.cap("LS", "302")
|
||||||
|
|
||||||
if not self.sasl_auth:
|
if not self.sasl_auth:
|
||||||
self.send("PASS {0}:{1}".format(self.authname if self.authname else self.nickname,
|
self.send("PASS {0}:{1}".format(self.authname if self.authname else self.nickname,
|
||||||
self.password if self.password else "NOPASS"))
|
self.password if self.password else "NOPASS"))
|
||||||
else:
|
|
||||||
self.cap("LS")
|
|
||||||
|
|
||||||
self.nick(self.nickname)
|
self.nick(self.nickname)
|
||||||
self.user(self.ident, self.real_name)
|
self.user(self.ident, self.real_name)
|
||||||
|
|
||||||
if self.sasl_auth:
|
|
||||||
self.cap("REQ", "multi-prefix")
|
|
||||||
self.cap("REQ", "sasl")
|
|
||||||
|
|
||||||
if self.connect_cb:
|
if self.connect_cb:
|
||||||
try:
|
try:
|
||||||
self.connect_cb(self)
|
self.connect_cb(self)
|
||||||
|
@ -143,23 +143,52 @@ def connect_callback(cli):
|
|||||||
hook("unavailresource")(mustrelease)
|
hook("unavailresource")(mustrelease)
|
||||||
hook("nicknameinuse")(mustregain)
|
hook("nicknameinuse")(mustregain)
|
||||||
|
|
||||||
if botconfig.SASL_AUTHENTICATION:
|
request_caps = {"account-notify", "extended-join", "multi-prefix"}
|
||||||
|
|
||||||
|
if botconfig.SASL_AUTHENTICATION:
|
||||||
|
request_caps.add("sasl")
|
||||||
|
|
||||||
|
supported_caps = set()
|
||||||
|
|
||||||
|
|
||||||
|
@hook("cap")
|
||||||
|
def on_cap(cli, svr, mynick, cmd, caps, star=None):
|
||||||
|
if cmd == "LS":
|
||||||
|
if caps == "*":
|
||||||
|
# Multi-line LS
|
||||||
|
supported_caps.update(star.split())
|
||||||
|
else:
|
||||||
|
supported_caps.update(caps.split())
|
||||||
|
|
||||||
|
print(supported_caps)
|
||||||
|
|
||||||
|
if botconfig.SASL_AUTHENTICATION and "sasl" not in supported_caps:
|
||||||
|
alog("Server does not support SASL authentication")
|
||||||
|
cli.quit()
|
||||||
|
|
||||||
|
common_caps = request_caps & supported_caps
|
||||||
|
|
||||||
|
if common_caps:
|
||||||
|
cli.cap("REQ", ":{0}".format(" ".join(common_caps)))
|
||||||
|
elif cmd == "ACK":
|
||||||
|
if "sasl" in caps:
|
||||||
|
cli.send("AUTHENTICATE PLAIN")
|
||||||
|
else:
|
||||||
|
cli.cap("END")
|
||||||
|
elif cmd == "NAK":
|
||||||
|
# This isn't supposed to happen. The server claimed to support a
|
||||||
|
# capability but now claims otherwise.
|
||||||
|
alog("Server refused capabilities: {0}".format(" ".join(caps)))
|
||||||
|
|
||||||
|
|
||||||
|
if botconfig.SASL_AUTHENTICATION:
|
||||||
@hook("authenticate")
|
@hook("authenticate")
|
||||||
def auth_plus(cli, something, plus):
|
def auth_plus(cli, something, plus):
|
||||||
if plus == "+":
|
if plus == "+":
|
||||||
nick_b = bytes(botconfig.USERNAME if botconfig.USERNAME else botconfig.NICK, "utf-8")
|
account = (botconfig.USERNAME or botconfig.NICK).encode("utf-8")
|
||||||
pass_b = bytes(botconfig.PASS, "utf-8")
|
password = botconfig.PASS.encode("utf-8")
|
||||||
secrt_msg = b'\0'.join((nick_b, nick_b, pass_b))
|
auth_token = base64.b64encode(b"\0".join((account, account, password))).decode("utf-8")
|
||||||
cli.send("AUTHENTICATE " + base64.b64encode(secrt_msg).decode("utf-8"))
|
cli.send("AUTHENTICATE " + auth_token)
|
||||||
|
|
||||||
@hook("cap")
|
|
||||||
def on_cap(cli, svr, mynick, ack, cap):
|
|
||||||
if ack.upper() == "ACK" and "sasl" in cap:
|
|
||||||
cli.send("AUTHENTICATE PLAIN")
|
|
||||||
elif ack.upper() == "NAK" and "sasl" in cap:
|
|
||||||
cli.quit()
|
|
||||||
alog("Server does not support SASL authentication")
|
|
||||||
|
|
||||||
@hook("903")
|
@hook("903")
|
||||||
def on_successful_auth(cli, blah, blahh, blahhh):
|
def on_successful_auth(cli, blah, blahh, blahhh):
|
||||||
@ -170,9 +199,9 @@ def connect_callback(cli):
|
|||||||
@hook("906")
|
@hook("906")
|
||||||
@hook("907")
|
@hook("907")
|
||||||
def on_failure_auth(cli, *etc):
|
def on_failure_auth(cli, *etc):
|
||||||
|
alog("Authentication failed. Did you fill the account name "
|
||||||
|
"in botconfig.USERNAME if it's different from the bot nick?")
|
||||||
cli.quit()
|
cli.quit()
|
||||||
alog("Authentication failed. Did you fill the account name "+
|
|
||||||
"in botconfig.USERNAME if it's different from the bot nick?")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user