aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar jesopo2018-09-07 15:51:41 +0100
committerGravatar jesopo2018-09-07 15:51:41 +0100
commit7e3d7542b9c37e8980c78089a739add9be8b0606 (patch)
treef6ccbbe38d5bfffdc1b1eca0909f97d045068a5d
parentSupport server-time, even if it's ignored for the moment (diff)
Support CAP 3.2
-rw-r--r--IRCLineHandler.py46
-rw-r--r--IRCServer.py3
-rw-r--r--modules/sasl.py11
3 files changed, 42 insertions, 18 deletions
diff --git a/IRCLineHandler.py b/IRCLineHandler.py
index d9c65126..faa97471 100644
--- a/IRCLineHandler.py
+++ b/IRCLineHandler.py
@@ -287,27 +287,43 @@ class LineHandler(object):
# the server is telling us about its capabilities!
def cap(self, event):
- capabilities = (event["arbitrary"] or "").split(" ")
+ capabilities_list = (event["arbitrary"] or "").split(" ")
+ capabilities = {}
+ for capability in capabilities_list:
+ argument = None
+ if "=" in capability:
+ capability, argument = capability.split("=", 1)
+ capabilities[capability] = argument
+
subcommand = event["args"][1].lower()
+ is_multiline = len(event["args"]) > 2 and event["args"][2] == "*"
if subcommand == "ls":
- matched_capabilities = set(capabilities) & CAPABILITIES
- if matched_capabilities:
- event["server"].queue_capabilities(matched_capabilities)
+ event["server"].server_capabilities.update(capabilities)
+ if not is_multiline:
+ matched_capabilities = set(event["server"
+ ].server_capabilities.keys()) & CAPABILITIES
+ if matched_capabilities:
+ event["server"].queue_capabilities(matched_capabilities)
- self.events.on("received.cap").on(subcommand).call(
- capabilities=capabilities, server=event["server"])
+ self.events.on("received.cap.ls").call(
+ capabilities=event["server"].server_capabilities,
+ server=event["server"])
- if subcommand == "ls":
- if event["server"].has_capability_queue():
- event["server"].send_capability_queue()
- else:
- event["server"].send_capability_end()
+ if event["server"].has_capability_queue():
+ event["server"].send_capability_queue()
+ else:
+ event["server"].send_capability_end()
elif subcommand == "ack":
- if not event["server"].waiting_for_capabilities():
- event["server"].send_capability_end()
- event["server"].capabilities = set(capabilities)
- elif subcommand == "ack" or subcommand == "nack":
+ event["server"].capabilities.update(capabilities)
+ if not is_multiline:
+ self.events.on("received.cap.ack").call(
+ capabilities=event["server"].capabilities,
+ server=event["server"])
+
+ if not event["server"].waiting_for_capabilities():
+ event["server"].send_capability_end()
+ elif subcommand == "nack":
event["server"].send_capability_end()
# the server is asking for authentication
diff --git a/IRCServer.py b/IRCServer.py
index 81c64eed..30e29580 100644
--- a/IRCServer.py
+++ b/IRCServer.py
@@ -30,6 +30,7 @@ class Server(object):
self._capability_queue = set([])
self._capabilities_waiting = set([])
self.capabilities = set([])
+ self.server_capabilities = {}
self.write_buffer = b""
self.buffered_lines = []
@@ -278,7 +279,7 @@ class Server(object):
self.send("NICK %s" % nickname)
def send_capibility_ls(self):
- self.send("CAP LS")
+ self.send("CAP LS 302")
def queue_capability(self, capability):
self._capability_queue.add(capability)
def queue_capabilities(self, capabilities):
diff --git a/modules/sasl.py b/modules/sasl.py
index 7bde0813..8df4b3c9 100644
--- a/modules/sasl.py
+++ b/modules/sasl.py
@@ -14,9 +14,16 @@ class Module(object):
event["server"].send_capability_request("sasl")
def on_cap(self, event):
- if "sasl" in event["capabilities"] and event["server"].get_setting(
- "sasl", None):
+ has_sasl = "sasl" in event["capabilities"]
+ has_mechanisms = has_sasl and not event["capabilities"]["sasl"
+ ] == None
+ has_plaintext = has_mechanisms and "PLAIN" in event["capabilities"
+ ]["sasl"].split(",")
+
+ if has_sasl and (has_plaintext or not has_mechanisms) and event[
+ "server"].get_setting("sasl", None):
event["server"].queue_capability("sasl")
+
def on_cap_ack(self, event):
if "sasl" in event["capabilities"]:
event["server"].send_authenticate("PLAIN")