aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_c2s.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mod_c2s.lua')
-rw-r--r--plugins/mod_c2s.lua57
1 files changed, 47 insertions, 10 deletions
diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua
index 8d4dcfb8..fc838c0d 100644
--- a/plugins/mod_c2s.lua
+++ b/plugins/mod_c2s.lua
@@ -56,7 +56,17 @@ end);
local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'};
function stream_callbacks.streamopened(session, attr)
+ -- run _streamopened in async context
+ session.thread:run({ stream = "opened", attr = attr });
+end
+
+function stream_callbacks._streamopened(session, attr)
local send = session.send;
+ if not attr.to then
+ session:close{ condition = "improper-addressing",
+ text = "A 'to' attribute is required on stream headers" };
+ return;
+ end
local host = nameprep(attr.to);
if not host then
session:close{ condition = "improper-addressing",
@@ -80,7 +90,7 @@ function stream_callbacks.streamopened(session, attr)
return;
end
- session:open_stream();
+ session:open_stream(host, attr.from);
(session.log or log)("debug", "Sent reply <stream:stream> to client");
session.notopen = nil;
@@ -98,7 +108,6 @@ function stream_callbacks.streamopened(session, attr)
session.compressed = info.compression;
else
(session.log or log)("info", "Stream encrypted");
- session.compressed = sock.compression and sock:compression(); --COMPAT mw/luasec-hg
end
end
@@ -107,12 +116,23 @@ function stream_callbacks.streamopened(session, attr)
if features.tags[1] or session.full_jid then
send(features);
else
- (session.log or log)("warn", "No stream features to offer");
+ if session.secure then
+ -- Here SASL should be offered
+ (session.log or log)("warn", "No stream features to offer on secure session. Check authentication settings.");
+ else
+ -- Normally STARTTLS would be offered
+ (session.log or log)("warn", "No stream features to offer on insecure session. Check encryption and security settings.");
+ end
session:close{ condition = "undefined-condition", text = "No stream features to proceed with" };
end
end
-function stream_callbacks.streamclosed(session)
+function stream_callbacks.streamclosed(session, attr)
+ -- run _streamclosed in async context
+ session.thread:run({ stream = "closed", attr = attr });
+end
+
+function stream_callbacks._streamclosed(session)
session.log("debug", "Received </stream:stream>");
session:close(false);
end
@@ -122,7 +142,7 @@ function stream_callbacks.error(session, error, data)
session.log("debug", "Invalid opening stream header (%s)", (data:gsub("^([^\1]+)\1", "{%1}")));
session:close("invalid-namespace");
elseif error == "parse-error" then
- (session.log or log)("debug", "Client XML parse error: %s", tostring(data));
+ (session.log or log)("debug", "Client XML parse error: %s", data);
session:close("not-well-formed");
elseif error == "stream-error" then
local condition, text = "undefined-condition";
@@ -260,8 +280,6 @@ function listener.onconnect(conn)
local sock = conn:socket();
if sock.info then
session.compressed = sock:info"compression";
- elseif sock.compression then
- session.compressed = sock:compression(); --COMPAT mw/luasec-hg
end
end
@@ -281,7 +299,13 @@ function listener.onconnect(conn)
end
session.thread = runner(function (stanza)
- core_process_stanza(session, stanza);
+ if st.is_stanza(stanza) then
+ core_process_stanza(session, stanza);
+ elseif stanza.stream == "opened" then
+ stream_callbacks._streamopened(session, stanza.attr);
+ elseif stanza.stream == "closed" then
+ stream_callbacks._streamclosed(session, stanza.attr);
+ end
end, runner_callbacks, session);
local filter = session.filter;
@@ -292,8 +316,12 @@ function listener.onconnect(conn)
if data then
local ok, err = stream:feed(data);
if not ok then
- log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_"));
- session:close("not-well-formed");
+ log("debug", "Received invalid XML (%s) %d bytes: %q", err, #data, data:sub(1, 300));
+ if err == "stanza-too-large" then
+ session:close({ condition = "policy-violation", text = "XML stanza is too big" });
+ else
+ session:close("not-well-formed");
+ end
end
end
end
@@ -302,6 +330,7 @@ function listener.onconnect(conn)
if c2s_timeout then
add_task(c2s_timeout, function ()
if session.type == "c2s_unauthed" then
+ (session.log or log)("debug", "Connection still not authenticated after c2s_timeout=%gs, closing it", c2s_timeout);
session:close("connection-timeout");
end
end);
@@ -336,6 +365,13 @@ function listener.onreadtimeout(conn)
end
end
+function listener.ondrain(conn)
+ local session = sessions[conn];
+ if session then
+ return (hosts[session.host] or prosody).events.fire_event("c2s-ondrain", { session = session });
+ end
+end
+
local function keepalive(event)
local session = event.session;
if not session.notopen then
@@ -368,6 +404,7 @@ module:provides("net", {
default_port = 5222;
encryption = "starttls";
multiplex = {
+ protocol = "xmpp-client";
pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:client%1.*>";
};
});