Merge 0.10->trunk
authorKim Alvefur <zash@zash.se>
Wed, 10 Sep 2014 23:17:56 +0000 (01:17 +0200)
committerKim Alvefur <zash@zash.se>
Wed, 10 Sep 2014 23:17:56 +0000 (01:17 +0200)
Makefile
core/sessionmanager.lua
core/stanza_router.lua
net/websocket.lua
plugins/mod_s2s/mod_s2s.lua
prosodyctl

index a1de1b6d7e49b63fc2c6e9541bb2ae7b1d0e9daa..85eca971f6f46faf26cabdc408937f4295e2353c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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
index 5f7f688eb90ce61e712b5b0c2074f03df3370529..65e5156cbdca694aecd2eb04a372e52d5ba5bfc7 100644 (file)
@@ -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
 
index c78a657af48051591165100f07f9cbe696f93f9d..4f529129d91ce121f261f696d554db17e2004acc 100644 (file)
@@ -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
index 3c4746b7bcdbb6ee20c5c6b9de22a5167829ab5a..f8daa2788bc3e044cc66fccecbdce3b90ad7feef 100644 (file)
@@ -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));
index 0a2b5bb773bd08cad82ad808c58ce3f5d2af938a..7ff921d927dc415639fb7afc5295f97b0bdf9ea4 100644 (file)
@@ -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
index 910b96bf2cb8f82f7874a0a6ab58985bced007fa..df8c8e755312df4b20ba4869cdba6a1a8a0aadbe 100755 (executable)
@@ -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");