diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | core/sessionmanager.lua | 1 | ||||
-rw-r--r-- | core/stanza_router.lua | 47 | ||||
-rw-r--r-- | net/websocket.lua | 15 | ||||
-rw-r--r-- | plugins/mod_s2s/mod_s2s.lua | 1 | ||||
-rwxr-xr-x | prosodyctl | 4 |
6 files changed, 40 insertions, 31 deletions
@@ -31,8 +31,9 @@ install: prosody.install prosodyctl.install prosody.cfg.lua.install util/encodin install -m755 ./prosodyctl.install $(BIN)/prosodyctl install -m644 core/* $(SOURCE)/core install -m644 net/*.lua $(SOURCE)/net - install -d $(SOURCE)/net/http + install -d $(SOURCE)/net/http $(SOURCE)/net/websocket install -m644 net/http/*.lua $(SOURCE)/net/http + install -m644 net/websocket/*.lua $(SOURCE)/net/websocket install -m644 util/*.lua $(SOURCE)/util install -m644 util/*.so $(SOURCE)/util install -d $(SOURCE)/util/sasl diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua index 5f7f688e..65e5156c 100644 --- a/core/sessionmanager.lua +++ b/core/sessionmanager.lua @@ -67,6 +67,7 @@ function retire_session(session) function session.send(data) log("debug", "Discarding data sent to resting session: %s", tostring(data)); return false; end function session.data(data) log("debug", "Discarding data received from resting session: %s", tostring(data)); end + session.thread = { run = function (_, data) return session.data(data) end }; return setmetatable(session, resting_session); end diff --git a/core/stanza_router.lua b/core/stanza_router.lua index c78a657a..4f529129 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -29,24 +29,25 @@ deprecated_warning"core_post_stanza"; deprecated_warning"core_process_stanza"; deprecated_warning"core_route_stanza"; +local valid_stanzas = { message = true, presence = true, iq = true }; local function handle_unhandled_stanza(host, origin, stanza) local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns or "jabber:client", origin.type; - if name == "iq" and xmlns == "jabber:client" then - if stanza.attr.type == "get" or stanza.attr.type == "set" then + if xmlns == "jabber:client" and valid_stanzas[name] then + -- A normal stanza + local st_type = stanza.attr.type; + if st_type == "error" or (name == "iq" and st_type == "result") then + log("debug", "Discarding %s from %s of type: %s", name, origin_type, st_type or '<nil>'); + return; + end + if name == "iq" and (st_type == "get" or st_type == "set") and stanza.tags[1] then xmlns = stanza.tags[1].attr.xmlns or "jabber:client"; - log("debug", "Stanza of type %s from %s has xmlns: %s", name, origin_type, xmlns); - else - log("debug", "Discarding %s from %s of type: %s", name, origin_type, stanza.attr.type); - return true; end - end - if stanza.attr.xmlns == nil and origin.send then - log("debug", "Unhandled %s stanza: %s; xmlns=%s", origin.type, stanza.name, xmlns); -- we didn't handle it - if stanza.attr.type ~= "error" and stanza.attr.type ~= "result" then + log("debug", "Unhandled %s stanza: %s; xmlns=%s", origin_type, name, xmlns); + if origin.send then origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); end - elseif not((name == "features" or name == "error") and xmlns == "http://etherx.jabber.org/streams") then -- FIXME remove check once we handle S2S features - log("warn", "Unhandled %s stream element or stanza: %s; xmlns=%s: %s", origin.type, stanza.name, xmlns, tostring(stanza)); -- we didn't handle it + else + log("warn", "Unhandled %s stream element or stanza: %s; xmlns=%s: %s", origin_type, name, xmlns, tostring(stanza)); -- we didn't handle it origin:close("unsupported-stanza-type"); end end @@ -55,19 +56,21 @@ local iq_types = { set=true, get=true, result=true, error=true }; function core_process_stanza(origin, stanza) (origin.log or log)("debug", "Received[%s]: %s", origin.type, stanza:top_tag()) - -- TODO verify validity of stanza (as well as JID validity) - if stanza.attr.type == "error" and #stanza.tags == 0 then return; end -- TODO invalid stanza, log - if stanza.name == "iq" then - if not stanza.attr.id then stanza.attr.id = ""; end -- COMPAT Jabiru doesn't send the id attribute on roster requests - if not iq_types[stanza.attr.type] or ((stanza.attr.type == "set" or stanza.attr.type == "get") and (#stanza.tags ~= 1)) then - origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid IQ type or incorrect number of children")); - return; + if origin.type == "c2s" and not stanza.attr.xmlns then + local name, st_type = stanza.name, stanza.attr.type; + if st_type == "error" and #stanza.tags == 0 then + return handle_unhandled_stanza(origin.host, origin, stanza); + end + if name == "iq" then + if not stanza.attr.id then stanza.attr.id = ""; end -- COMPAT Jabiru doesn't send the id attribute on roster requests + if not iq_types[st_type] or (st_type ~= "result" and #stanza.tags ~= 1) then + origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid IQ type or incorrect number of children")); + return; + end end - end - if origin.type == "c2s" and not stanza.attr.xmlns then if not origin.full_jid - and not(stanza.name == "iq" and stanza.attr.type == "set" and stanza.tags[1] and stanza.tags[1].name == "bind" + and not(name == "iq" and st_type == "set" and stanza.tags[1] and stanza.tags[1].name == "bind" and stanza.tags[1].attr.xmlns == "urn:ietf:params:xml:ns:xmpp-bind") then -- authenticated client isn't bound and current stanza is not a bind request if stanza.attr.type ~= "result" and stanza.attr.type ~= "error" then diff --git a/net/websocket.lua b/net/websocket.lua index 3c4746b7..f8daa278 100644 --- a/net/websocket.lua +++ b/net/websocket.lua @@ -190,17 +190,20 @@ local function connect(url, ex, listeners) -- Either a single protocol string or an array of protocol strings. local protocol = ex.protocol; if type(protocol) == "string" then - protocol = { protocol }; - end - for _, v in ipairs(protocol) do - protocol[v] = true; + protocol = { protocol, [protocol] = true }; + elseif type(protocol) == "table" and protocol[1] then + for _, v in ipairs(protocol) do + protocol[v] = true; + end + else + protocol = nil; end local headers = { ["Upgrade"] = "websocket"; ["Connection"] = "Upgrade"; ["Sec-WebSocket-Key"] = key; - ["Sec-WebSocket-Protocol"] = t_concat(protocol, ", "); + ["Sec-WebSocket-Protocol"] = protocol and t_concat(protocol, ", "); ["Sec-WebSocket-Version"] = "13"; ["Sec-WebSocket-Extensions"] = ex.extensions; } @@ -238,7 +241,7 @@ local function connect(url, ex, listeners) or r.headers["connection"]:lower() ~= "upgrade" or r.headers["upgrade"] ~= "websocket" or r.headers["sec-websocket-accept"] ~= base64.encode(sha1(key .. "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")) - or not protocol[r.headers["sec-websocket-protocol"]] + or (protocol and not protocol[r.headers["sec-websocket-protocol"]]) then s.readyState = 3; log("warn", "WebSocket connection to %s failed: %s", url, tostring(b)); diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua index 0a2b5bb7..7ff921d9 100644 --- a/plugins/mod_s2s/mod_s2s.lua +++ b/plugins/mod_s2s/mod_s2s.lua @@ -153,6 +153,7 @@ function module.add_host(module) -- Stream is authenticated and we are seem to be done with feature negotiation, -- so the stream is ready for stanzas. RFC 6120 Section 4.3 mark_connected(session); + return true; end end, -1); end @@ -736,7 +736,7 @@ function cert_commands.request(arg) end local _, key_filename = cert_commands.key({arg[1]}); local _, conf_filename = cert_commands.config(arg); - if openssl.req{new=true, key=key_filename, utf8=true, config=conf_filename, out=req_filename} then + if openssl.req{new=true, key=key_filename, utf8=true, sha256=true, config=conf_filename, out=req_filename} then show_message("Certificate request written to ".. req_filename); else show_message("There was a problem, see OpenSSL output"); @@ -757,7 +757,7 @@ function cert_commands.generate(arg) local ret; if key_filename and conf_filename and cert_filename and openssl.req{new=true, x509=true, nodes=true, key=key_filename, - days=365, sha1=true, utf8=true, config=conf_filename, out=cert_filename} then + days=365, sha256=true, utf8=true, config=conf_filename, out=cert_filename} then show_message("Certificate written to ".. cert_filename); else show_message("There was a problem, see OpenSSL output"); |