From 6f147fde17da5bd5037247fac6b653cb439a4774 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 7 Dec 2011 02:58:22 +0000 Subject: mod_bosh: Store time to destroy session in inactive_sessions, removing dependency on session.bosh_max_inactive in cleanup timer --- plugins/mod_bosh.lua | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 834b128a..ffba5c11 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -91,9 +91,10 @@ function on_destroy_request(request) end -- If this session now has no requests open, mark it as inactive - if #requests == 0 and session.bosh_max_inactive and not inactive_sessions[session] then - inactive_sessions[session] = os_time(); - (session.log or log)("debug", "BOSH session marked as inactive at %d", inactive_sessions[session]); + local max_inactive = session.bosh_max_inactive; + if max_inactive and #requests == 0 then + inactive_sessions[session] = os_time() + max_inactive; + (session.log or log)("debug", "BOSH session marked as inactive (for %ds)", max_inactive); end end end @@ -402,17 +403,13 @@ function on_timer() now = now - 3; local n_dead_sessions = 0; - for session, inactive_since in pairs(inactive_sessions) do - if session.bosh_max_inactive then - if now - inactive_since > session.bosh_max_inactive then - (session.log or log)("debug", "BOSH client inactive too long, destroying session at %d", now); - sessions[session.sid] = nil; - inactive_sessions[session] = nil; - n_dead_sessions = n_dead_sessions + 1; - dead_sessions[n_dead_sessions] = session; - end - else + for session, close_after in pairs(inactive_sessions) do + if close_after < now then + (session.log or log)("debug", "BOSH client inactive too long, destroying session at %d", now); + sessions[session.sid] = nil; inactive_sessions[session] = nil; + n_dead_sessions = n_dead_sessions + 1; + dead_sessions[n_dead_sessions] = session; end end -- cgit v1.2.3 From d968e72bfbc364561846d88f07a6ad191cabf332 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 7 Dec 2011 03:54:28 +0000 Subject: mod_bosh: Remove a session from inactive_sessions before destroying it --- plugins/mod_bosh.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index ffba5c11..3541f614 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -214,6 +214,7 @@ local function bosh_close_stream(session, reason) held_request:destroy(); end sessions[session.sid] = nil; + inactive_sessions[session] = nil; sm_destroy_session(session); end -- cgit v1.2.3 From 65e0b32a7e546136672837aba6acc8f9b1b53be7 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 7 Dec 2011 04:57:51 +0000 Subject: mod_bosh: Move stream:features sending until after the current request has been added to session.requests. Ensures correct inactivity logic. --- plugins/mod_bosh.lua | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 3541f614..b8759f60 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -120,10 +120,17 @@ function handle_request(method, body, request) request.on_destroy = on_destroy_request; local stream = new_xmpp_stream(request, stream_callbacks); + -- stream:feed() calls the stream_callbacks, so all stanzas in -- the body are processed in this next line before it returns. + -- In particular, the streamopened() stream callback is where + -- much of the session logic happens, because it's where we first + -- get to see the 'sid' of this request. stream:feed(body); + -- Stanzas (if any) in the request have now been processed, and + -- we take care of the high-level BOSH logic here, including + -- giving a response or putting the request "on hold". local session = sessions[request.sid]; if session then -- Session was marked as inactive, since we have @@ -218,6 +225,7 @@ local function bosh_close_stream(session, reason) sm_destroy_session(session); end +-- Handle the tag in the request payload. function stream_callbacks.streamopened(request, attr) local sid = attr.sid; log("debug", "BOSH body open (sid: %s)", sid or ""); @@ -340,14 +348,6 @@ function stream_callbacks.streamopened(request, attr) session.rid = rid; end - if session.notopen then - local features = st.stanza("stream:features"); - hosts[session.host].events.fire_event("stream-features", { origin = session, features = features }); - fire_event("stream-features", session, features); - session.send(features); - session.notopen = nil; - end - if attr.type == "terminate" then -- Client wants to end this session, which we'll do -- after processing any stanzas in this request @@ -357,6 +357,14 @@ function stream_callbacks.streamopened(request, attr) request.notopen = nil; -- Signals that we accept this opening tag t_insert(session.requests, request); request.sid = sid; + + if session.notopen then + local features = st.stanza("stream:features"); + hosts[session.host].events.fire_event("stream-features", { origin = session, features = features }); + fire_event("stream-features", session, features); + session.send(features); + session.notopen = nil; + end end function stream_callbacks.handlestanza(request, stanza) -- cgit v1.2.3 From b212e28356f112a0d36311fa6909db82d2ab2c15 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 7 Dec 2011 05:54:17 +0000 Subject: mod_bosh: Experimental option 'bosh_auto_cork' which witholds any response to a request until all stanzas in it have been processed. --- plugins/mod_bosh.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index b8759f60..e45ebeb4 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -35,6 +35,7 @@ local BOSH_DEFAULT_POLLING = module:get_option_number("bosh_max_polling", 5); local BOSH_DEFAULT_REQUESTS = module:get_option_number("bosh_max_requests", 2); local consider_bosh_secure = module:get_option_boolean("consider_bosh_secure"); +local auto_cork = module:get_option_boolean("bosh_auto_cork", false); local default_headers = { ["Content-Type"] = "text/xml; charset=utf-8" }; @@ -268,7 +269,7 @@ function stream_callbacks.streamopened(request, attr) end --log("debug", "Sending BOSH data: %s", tostring(s)); local oldest_request = r[1]; - if oldest_request then + if oldest_request and (not(auto_cork) or waiting_requests[oldest_request]) then log("debug", "We have an open request, so sending on that"); response.body = t_concat({ " Date: Fri, 9 Dec 2011 11:44:00 +0500 Subject: mod_bosh: Fixed use of a private HTTP request property. --- plugins/mod_bosh.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index e45ebeb4..f4b38bfd 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -58,7 +58,7 @@ end local trusted_proxies = module:get_option_set("trusted_proxies", {"127.0.0.1"})._items; local function get_ip_from_request(request) - local ip = request.handler:ip(); + local ip = request.conn:ip(); local forwarded_for = request.headers["x-forwarded-for"]; if forwarded_for then forwarded_for = forwarded_for..", "..ip; -- cgit v1.2.3 From 78a5742d5d0feda55680168cb4b54a1b1e6bfde6 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 10 Dec 2011 05:45:07 +0000 Subject: mod_adhoc: Use module:handle_items() --- plugins/adhoc/mod_adhoc.lua | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'plugins') diff --git a/plugins/adhoc/mod_adhoc.lua b/plugins/adhoc/mod_adhoc.lua index 6d826338..49d07103 100644 --- a/plugins/adhoc/mod_adhoc.lua +++ b/plugins/adhoc/mod_adhoc.lua @@ -90,19 +90,13 @@ module:hook("iq/host/"..xmlns_cmd..":command", function (event) end end, 500); -local function handle_item_added(item) +local function adhoc_added(event) + local item = event.item; commands[item.node] = item; end -module:hook("item-added/adhoc", function (event) - return handle_item_added(event.item); -end, 500); - -module:hook("item-removed/adhoc", function (event) +local function adhoc_removed(event) commands[event.item.node] = nil; -end, 500); - --- Pick up any items that are already added -for _, item in ipairs(module:get_host_items("adhoc")) do - handle_item_added(item); end + +module:handle_items("adhoc", adhoc_added, adhoc_removed); -- cgit v1.2.3 From fe1b3127b2789925f0bac40c4e279edbdf773982 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Mon, 12 Dec 2011 14:53:12 +0500 Subject: mod_watchregistrations: Fixed an undefined global access (thanks Medics). --- plugins/mod_watchregistrations.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_watchregistrations.lua b/plugins/mod_watchregistrations.lua index ee51566b..42f9c017 100644 --- a/plugins/mod_watchregistrations.lua +++ b/plugins/mod_watchregistrations.lua @@ -18,7 +18,7 @@ module:hook("user-registered", function (user) module:log("debug", "Notifying of new registration"); local message = st.message{ type = "chat", from = host } :tag("body") - :text(registration_alert:gsub("%$(%w+)", function (v) + :text(registration_notification:gsub("%$(%w+)", function (v) return user[v] or user.session and user.session[v] or nil; end)); for _, jid in ipairs(registration_watchers) do -- cgit v1.2.3 From e246f6a8d7d5526c16ea307719f7c0febd340103 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 14 Dec 2011 06:42:23 +0500 Subject: mod_bosh: Remove unused reference to lxp --- plugins/mod_bosh.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index f4b38bfd..9de27b4b 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -9,7 +9,6 @@ module.host = "*" -- Global module local hosts = _G.hosts; -local lxp = require "lxp"; local new_xmpp_stream = require "util.xmppstream".new; local httpserver = require "net.httpserver"; local sm = require "core.sessionmanager"; -- cgit v1.2.3 From 351b8347c855bf3bef851bf2aa28b4dc73f21743 Mon Sep 17 00:00:00 2001 From: Marco Cirillo Date: Fri, 6 Jan 2012 21:45:33 +0000 Subject: mod_component: removed unused variable reference, added "flagging" to assert if a component is connected or not. --- plugins/mod_component.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index 97c46a8c..f7d09930 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -10,8 +10,6 @@ if module:get_host_type() ~= "component" then error("Don't load mod_component manually, it should be for a component, please see http://prosody.im/doc/components", 0); end -local hosts = _G.hosts; - local t_concat = table.concat; local sha1 = require "util.hashes".sha1; @@ -23,6 +21,7 @@ local main_session, send; local function on_destroy(session, err) if main_session == session then + connected = false; main_session = nil; send = nil; session.on_destroy = nil; @@ -83,6 +82,7 @@ function handle_component_auth(event) -- If component not already created for this host, create one now if not main_session then + connected = true; send = session.send; main_session = session; session.on_destroy = on_destroy; -- cgit v1.2.3 From 32d3713a7aaf792565a435f6b657a1102c34c012 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 18 Jan 2012 15:07:26 +0000 Subject: mod_tls: Fix log statement (thanks Zash) --- plugins/mod_tls.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_tls.lua b/plugins/mod_tls.lua index cace2d69..707ae8f5 100644 --- a/plugins/mod_tls.lua +++ b/plugins/mod_tls.lua @@ -75,7 +75,7 @@ end); module:hook_stanza("http://etherx.jabber.org/streams", "features", function (session, stanza) module:log("debug", "Received features element"); if can_do_tls(session) and stanza:child_with_ns(xmlns_starttls) then - module:log("%s is offering TLS, taking up the offer...", session.to_host); + module:log("debug", "%s is offering TLS, taking up the offer...", session.to_host); session.sends2s(""); return true; end -- cgit v1.2.3 From 54d1d2ec6ee3ebb535f16930966edfc1128f2834 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 19 Jan 2012 16:38:04 +0100 Subject: mod_compression: Use get_option_number --- plugins/mod_compression.lua | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_compression.lua b/plugins/mod_compression.lua index 82403016..b5031d72 100644 --- a/plugins/mod_compression.lua +++ b/plugins/mod_compression.lua @@ -16,12 +16,8 @@ local xmlns_stream = "http://etherx.jabber.org/streams"; local compression_stream_feature = st.stanza("compression", {xmlns=xmlns_compression_feature}):tag("method"):text("zlib"):up(); local add_filter = require "util.filters".add_filter; -local compression_level = module:get_option("compression_level"); --- if not defined assume admin wants best compression -if compression_level == nil then compression_level = 9 end; +local compression_level = module:get_option_number("compression_level", 9); - -compression_level = tonumber(compression_level); if not compression_level or compression_level < 1 or compression_level > 9 then module:log("warn", "Invalid compression level in config: %s", tostring(compression_level)); module:log("warn", "Module loading aborted. Compression won't be available."); -- cgit v1.2.3 From c707eb0fa1ca277926b2c7cc58fad5faf5896f86 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 19 Jan 2012 16:47:12 +0100 Subject: mod_compression: Change default compression level to 7 --- plugins/mod_compression.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_compression.lua b/plugins/mod_compression.lua index b5031d72..62c0fa2e 100644 --- a/plugins/mod_compression.lua +++ b/plugins/mod_compression.lua @@ -16,7 +16,7 @@ local xmlns_stream = "http://etherx.jabber.org/streams"; local compression_stream_feature = st.stanza("compression", {xmlns=xmlns_compression_feature}):tag("method"):text("zlib"):up(); local add_filter = require "util.filters".add_filter; -local compression_level = module:get_option_number("compression_level", 9); +local compression_level = module:get_option_number("compression_level", 7); if not compression_level or compression_level < 1 or compression_level > 9 then module:log("warn", "Invalid compression level in config: %s", tostring(compression_level)); -- cgit v1.2.3 From 8292f713bab8e71624f03111115bd3a97cf8dae9 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 22 Jan 2012 19:50:08 +0000 Subject: mod_admin_telnet: Use module:shared() to expose commands table and default console environment --- plugins/mod_admin_telnet.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index b211d271..b118e27a 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -21,12 +21,10 @@ local jid_bare = require "util.jid".bare; local set, array = require "util.set", require "util.array"; local cert_verify_identity = require "util.x509".verify_identity; -local commands = {}; -local def_env = {}; +local commands = module:shared("commands") +local def_env = module:shared("env"); local default_env_mt = { __index = def_env }; -prosody.console = { commands = commands, env = def_env }; - local function redirect_output(_G, session) local env = setmetatable({ print = session.print }, { __index = function (t, k) return rawget(_G, k); end }); env.dofile = function(name) -- cgit v1.2.3 From 13b36f8ded00794f3142887c41ac8b31efb01e4b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 22 Jan 2012 23:57:13 +0000 Subject: mod_c2s, sessionmanager, xmppclient_listener: Move all c2s network and stream logic into a new module, mod_c2s --- plugins/mod_c2s.lua | 224 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 plugins/mod_c2s.lua (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua new file mode 100644 index 00000000..2fbed1c9 --- /dev/null +++ b/plugins/mod_c2s.lua @@ -0,0 +1,224 @@ +-- Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + +module:set_global(); + +local new_xmpp_stream = require "util.xmppstream".new; +local nameprep = require "util.encodings".stringprep.nameprep; +local portmanager = require "core.portmanager"; +local sessionmanager = require "core.sessionmanager"; +local st = require "util.stanza"; +local sm_new_session, sm_destroy_session = sessionmanager.new_session, sessionmanager.destroy_session; +local uuid_generate = require "util.uuid".generate; + +local xpcall, tostring, type = xpcall, tostring, type; +local format = string.format; +local traceback = debug.traceback; + +local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; + +local log = module._log; + +local opt_keepalives = module:get_option_boolean("tcp_keepalives", false); + +local sessions = module:shared("sessions"); + +local stream_callbacks = { default_ns = "jabber:client", handlestanza = core_process_stanza }; +local listener = { default_port = 5222, default_mode = "*a" }; + +--- Stream events handlers +local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; +local default_stream_attr = { ["xmlns:stream"] = "http://etherx.jabber.org/streams", xmlns = stream_callbacks.default_ns, version = "1.0", id = "" }; + +function stream_callbacks.streamopened(session, attr) + local send = session.send; + session.host = attr.to; + if not session.host then + session:close{ condition = "improper-addressing", + text = "A 'to' attribute is required on stream headers" }; + return; + end + session.host = nameprep(session.host); + session.version = tonumber(attr.version) or 0; + session.streamid = uuid_generate(); + (session.log or session)("debug", "Client sent opening to %s", session.host); + + if not hosts[session.host] then + -- We don't serve this host... + session:close{ condition = "host-unknown", text = "This server does not serve "..tostring(session.host)}; + return; + end + + send(""); + send(format("", session.streamid, session.host)); + + (session.log or log)("debug", "Sent reply to client"); + session.notopen = nil; + + -- If session.secure is *false* (not nil) then it means we /were/ encrypting + -- since we now have a new stream header, session is secured + if session.secure == false then + session.secure = true; + end + + local features = st.stanza("stream:features"); + hosts[session.host].events.fire_event("stream-features", { origin = session, features = features }); + module:fire_event("stream-features", session, features); + + send(features); +end + +function stream_callbacks.streamclosed(session) + session.log("debug", "Received "); + session:close(); +end + +function stream_callbacks.error(session, error, data) + if error == "no-stream" then + session.log("debug", "Invalid opening stream header"); + session:close("invalid-namespace"); + elseif error == "parse-error" then + (session.log or log)("debug", "Client XML parse error: %s", tostring(data)); + session:close("not-well-formed"); + elseif error == "stream-error" then + local condition, text = "undefined-condition"; + for child in data:children() do + if child.attr.xmlns == xmlns_xmpp_streams then + if child.name ~= "text" then + condition = child.name; + else + text = child:get_text(); + end + if condition ~= "undefined-condition" and text then + break; + end + end + end + text = condition .. (text and (" ("..text..")") or ""); + session.log("info", "Session closed by remote with error: %s", text); + session:close(nil, text); + end +end + +local function handleerr(err) log("error", "Traceback[c2s]: %s: %s", tostring(err), traceback()); end +function stream_callbacks.handlestanza(session, stanza) + stanza = session.filter("stanzas/in", stanza); + if stanza then + return xpcall(function () return core_process_stanza(session, stanza) end, handleerr); + end +end + +--- Session methods +local function session_close(session, reason) + local log = session.log or log; + if session.conn then + if session.notopen then + session.send(""); + session.send(st.stanza("stream:stream", default_stream_attr):top_tag()); + end + if reason then + if type(reason) == "string" then -- assume stream error + log("info", "Disconnecting client, is: %s", reason); + session.send(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' })); + elseif type(reason) == "table" then + if reason.condition then + local stanza = st.stanza("stream:error"):tag(reason.condition, stream_xmlns_attr):up(); + if reason.text then + stanza:tag("text", stream_xmlns_attr):text(reason.text):up(); + end + if reason.extra then + stanza:add_child(reason.extra); + end + log("info", "Disconnecting client, is: %s", tostring(stanza)); + session.send(stanza); + elseif reason.name then -- a stanza + log("info", "Disconnecting client, is: %s", tostring(reason)); + session.send(reason); + end + end + end + session.send(""); + session.conn:close(); + listener.ondisconnect(session.conn, (reason and (reason.text or reason.condition)) or reason or "session closed"); + end +end + +--- Port listener +function listener.onconnect(conn) + local session = sm_new_session(conn); + sessions[conn] = session; + + session.log("info", "Client connected"); + + -- Client is using legacy SSL (otherwise mod_tls sets this flag) + if conn:ssl() then + session.secure = true; + end + + if opt_keepalives then + conn:setoption("keepalive", opt_keepalives); + end + + session.close = session_close; + + local stream = new_xmpp_stream(session, stream_callbacks); + session.stream = stream; + session.notopen = true; + + function session.reset_stream() + session.notopen = true; + session.stream:reset(); + end + + local filter = session.filter; + function session.data(data) + data = filter("bytes/in", data); + if data then + local ok, err = stream:feed(data); + if ok then return; end + 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"); + end + end + + session.dispatch_stanza = stream_callbacks.handlestanza; +end + +function listener.onincoming(conn, data) + local session = sessions[conn]; + if session then + session.data(data); + end +end + +function listener.ondisconnect(conn, err) + local session = sessions[conn]; + if session then + (session.log or log)("info", "Client disconnected: %s", err); + sm_destroy_session(session, err); + sessions[conn] = nil; + session = nil; + end +end + +function listener.associate_session(conn, session) + sessions[conn] = session; +end + +portmanager.register_service("c2s", { + listener = listener; + default_port = 5222; + encryption = "starttls"; +}); + +portmanager.register_service("legacy_ssl", { + listener = listener; + encryption = "ssl"; +}); + + -- cgit v1.2.3 From b14f0af41d94b5ee137d48e269ad29b45ee765d9 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Jan 2012 00:56:57 +0000 Subject: sessionmanager, mod_c2s: Move timeout logic to mod_c2s --- plugins/mod_c2s.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 2fbed1c9..4d7318a5 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -8,6 +8,7 @@ module:set_global(); +local add_task = require "util.timer".add_task; local new_xmpp_stream = require "util.xmppstream".new; local nameprep = require "util.encodings".stringprep.nameprep; local portmanager = require "core.portmanager"; @@ -24,6 +25,7 @@ local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; local log = module._log; +local c2s_timeout = module:get_option_number("c2s_timeout"); local opt_keepalives = module:get_option_boolean("tcp_keepalives", false); local sessions = module:shared("sessions"); @@ -186,6 +188,15 @@ function listener.onconnect(conn) end end + + if c2s_timeout then + add_task(c2s_timeout, function () + if session.type == "c2s_unauthed" then + session:close("connection-timeout"); + end + end); + end + session.dispatch_stanza = stream_callbacks.handlestanza; end -- cgit v1.2.3 From 7a2a2a4cd7a54945df1a849af7f37a9a91783d53 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Jan 2012 01:05:32 +0000 Subject: mod_admin_telnet: Port to portmanager --- plugins/mod_admin_telnet.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index b118e27a..9e9065bb 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -12,9 +12,8 @@ local _G = _G; local prosody = _G.prosody; local hosts = prosody.hosts; -local connlisteners_register = require "net.connlisteners".register; -local console_listener = { default_port = 5582; default_mode = "*l"; default_interface = "127.0.0.1" }; +local console_listener = { default_port = 5582; default_mode = "*l"; interface = "127.0.0.1" }; require "util.iterators"; local jid_bare = require "util.jid".bare; @@ -147,8 +146,6 @@ function console_listener.ondisconnect(conn, err) end end -connlisteners_register('console', console_listener); - -- Console commands -- -- These are simple commands, not valid standalone in Lua @@ -776,4 +773,7 @@ if option and option ~= "short" and option ~= "full" and option ~= "graphic" the end end -prosody.net_activate_ports("console", "console", {5582}, "tcp"); +require "core.portmanager".register_service("console", { + listener = console_listener; + default_port = 5582; +}); -- cgit v1.2.3 From 5c1ba3bb130a78863510e6f62f9be51f83e94a95 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Jan 2012 02:15:28 +0000 Subject: mod_c2s: Code reduction --- plugins/mod_c2s.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 4d7318a5..682c4e3b 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -39,13 +39,12 @@ local default_stream_attr = { ["xmlns:stream"] = "http://etherx.jabber.org/strea function stream_callbacks.streamopened(session, attr) local send = session.send; - session.host = attr.to; + session.host = nameprep(attr.to); if not session.host then session:close{ condition = "improper-addressing", - text = "A 'to' attribute is required on stream headers" }; + text = "A valid 'to' attribute is required on stream headers" }; return; end - session.host = nameprep(session.host); session.version = tonumber(attr.version) or 0; session.streamid = uuid_generate(); (session.log or session)("debug", "Client sent opening to %s", session.host); -- cgit v1.2.3 From f851289311ce15196d3dc7ae0d912b17586901b9 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Jan 2012 16:28:20 +0000 Subject: s2smanager, mod_s2s, mod_s2s/s2sout: Split connection handling out of s2smanager into mod_s2s, and further split connection logic for s2sout to a module lib, s2sout.lib.lua --- plugins/s2s/mod_s2s.lua | 447 +++++++++++++++++++++++++++++++++++++++++++++ plugins/s2s/s2sout.lib.lua | 314 +++++++++++++++++++++++++++++++ 2 files changed, 761 insertions(+) create mode 100644 plugins/s2s/mod_s2s.lua create mode 100644 plugins/s2s/s2sout.lib.lua (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua new file mode 100644 index 00000000..5be4d84b --- /dev/null +++ b/plugins/s2s/mod_s2s.lua @@ -0,0 +1,447 @@ +-- Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + +module:set_global(); + +local tostring, type = tostring, type; +local xpcall, traceback = xpcall, debug.traceback; + +local add_task = require "util.timer".add_task; +local st = require "util.stanza"; +local initialize_filters = require "util.filters".initialize; +local new_xmpp_stream = require "util.xmppstream".new; +local s2s_new_incoming = require "core.s2smanager".new_incoming; +local s2s_new_outgoing = require "core.s2smanager".new_outgoing; +local s2s_destroy_session = require "core.s2smanager".destroy_session; + +local s2sout = module:require("s2sout"); + +local connect_timeout = module:get_option_number("s2s_timeout", 60); + +local sessions = module:shared("sessions"); + +--- Handle stanzas to remote domains + +local bouncy_stanzas = { message = true, presence = true, iq = true }; +local function bounce_sendq(session, reason) + local sendq = session.sendq; + if not sendq then return; end + session.log("info", "sending error replies for "..#sendq.." queued stanzas because of failed outgoing connection to "..tostring(session.to_host)); + local dummy = { + type = "s2sin"; + send = function(s) + (session.log or log)("error", "Replying to to an s2s error reply, please report this! Traceback: %s", get_traceback()); + end; + dummy = true; + }; + for i, data in ipairs(sendq) do + local reply = data[2]; + if reply and not(reply.attr.xmlns) and bouncy_stanzas[reply.name] then + reply.attr.type = "error"; + reply:tag("error", {type = "cancel"}) + :tag("remote-server-not-found", {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"}):up(); + if reason then + reply:tag("text", {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"}) + :text("Server-to-server connection failed: "..reason):up(); + end + core_process_stanza(dummy, reply); + end + sendq[i] = nil; + end + session.sendq = nil; +end + +function send_to_host(from_host, to_host, stanza) + if not hosts[from_host] then + log("warn", "Attempt to send stanza from %s - a host we don't serve", from_host); + return false; + end + local host = hosts[from_host].s2sout[to_host]; + if host then + -- We have a connection to this host already + if host.type == "s2sout_unauthed" and (stanza.name ~= "db:verify" or not host.dialback_key) then + (host.log or log)("debug", "trying to send over unauthed s2sout to "..to_host); + + -- Queue stanza until we are able to send it + if host.sendq then t_insert(host.sendq, {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)}); + else host.sendq = { {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)} }; end + host.log("debug", "stanza [%s] queued ", stanza.name); + elseif host.type == "local" or host.type == "component" then + log("error", "Trying to send a stanza to ourselves??") + log("error", "Traceback: %s", get_traceback()); + log("error", "Stanza: %s", tostring(stanza)); + return false; + else + (host.log or log)("debug", "going to send stanza to "..to_host.." from "..from_host); + -- FIXME + if host.from_host ~= from_host then + log("error", "WARNING! This might, possibly, be a bug, but it might not..."); + log("error", "We are going to send from %s instead of %s", tostring(host.from_host), tostring(from_host)); + end + host.sends2s(stanza); + host.log("debug", "stanza sent over "..host.type); + end + else + log("debug", "opening a new outgoing connection for this stanza"); + local host_session = s2s_new_outgoing(from_host, to_host); + + -- Store in buffer + host_session.bounce_sendq = bounce_sendq; + host_session.sendq = { {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)} }; + log("debug", "stanza [%s] queued until connection complete", tostring(stanza.name)); + if (not host_session.connecting) and (not host_session.conn) then + log("warn", "Connection to %s failed already, destroying session...", to_host); + if not s2s_destroy_session(host_session, "Connection failed") then + -- Already destroyed, we need to bounce our stanza + host_session:bounce_sendq(host_session.destruction_reason); + end + return false; + end + s2sout.initiate_connection(host_session); + end + return true; +end + +module:hook("route/remote", function (event) + return send_to_host(event.from_host, event.to_host, event.stanza); +end); + +--- Helper to check that a session peer's certificate is valid +local function check_cert_status(session) + local conn = session.conn:socket() + local cert + if conn.getpeercertificate then + cert = conn:getpeercertificate() + end + + if cert then + local chain_valid, errors = conn:getpeerverification() + -- Is there any interest in printing out all/the number of errors here? + if not chain_valid then + (session.log or log)("debug", "certificate chain validation result: invalid"); + session.cert_chain_status = "invalid"; + else + (session.log or log)("debug", "certificate chain validation result: valid"); + session.cert_chain_status = "valid"; + + local host = session.direction == "incoming" and session.from_host or session.to_host + + -- We'll go ahead and verify the asserted identity if the + -- connecting server specified one. + if host then + if cert_verify_identity(host, "xmpp-server", cert) then + session.cert_identity_status = "valid" + else + session.cert_identity_status = "invalid" + end + end + end + end +end + +--- XMPP stream event handlers + +local stream_callbacks = { default_ns = "jabber:server", handlestanza = core_process_stanza }; + +local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; + +function stream_callbacks.streamopened(session, attr) + local send = session.sends2s; + + -- TODO: #29: SASL/TLS on s2s streams + session.version = tonumber(attr.version) or 0; + + -- TODO: Rename session.secure to session.encrypted + if session.secure == false then + session.secure = true; + end + + if session.direction == "incoming" then + -- Send a reply stream header + session.to_host = attr.to and nameprep(attr.to); + session.from_host = attr.from and nameprep(attr.from); + + session.streamid = uuid_gen(); + (session.log or log)("debug", "Incoming s2s received "); + if session.to_host then + if not hosts[session.to_host] then + -- Attempting to connect to a host we don't serve + session:close({ + condition = "host-unknown"; + text = "This host does not serve "..session.to_host + }); + return; + elseif hosts[session.to_host].disallow_s2s then + -- Attempting to connect to a host that disallows s2s + session:close({ + condition = "policy-violation"; + text = "Server-to-server communication is not allowed to this host"; + }); + return; + end + end + + if session.secure and not session.cert_chain_status then check_cert_status(session); end + + send(""); + send(stanza("stream:stream", { xmlns='jabber:server', ["xmlns:db"]='jabber:server:dialback', + ["xmlns:stream"]='http://etherx.jabber.org/streams', id=session.streamid, from=session.to_host, to=session.from_host, version=(session.version > 0 and "1.0" or nil) }):top_tag()); + if session.version >= 1.0 then + local features = st.stanza("stream:features"); + + if session.to_host then + hosts[session.to_host].events.fire_event("s2s-stream-features", { origin = session, features = features }); + else + (session.log or log)("warn", "No 'to' on stream header from %s means we can't offer any features", session.from_host or "unknown host"); + end + + log("debug", "Sending stream features: %s", tostring(features)); + send(features); + end + elseif session.direction == "outgoing" then + -- If we are just using the connection for verifying dialback keys, we won't try and auth it + if not attr.id then error("stream response did not give us a streamid!!!"); end + session.streamid = attr.id; + + if session.secure and not session.cert_chain_status then check_cert_status(session); end + + -- Send unauthed buffer + -- (stanzas which are fine to send before dialback) + -- Note that this is *not* the stanza queue (which + -- we can only send if auth succeeds) :) + local send_buffer = session.send_buffer; + if send_buffer and #send_buffer > 0 then + log("debug", "Sending s2s send_buffer now..."); + for i, data in ipairs(send_buffer) do + session.sends2s(tostring(data)); + send_buffer[i] = nil; + end + end + session.send_buffer = nil; + + -- If server is pre-1.0, don't wait for features, just do dialback + if session.version < 1.0 then + if not session.dialback_verifying then + log("debug", "Initiating dialback..."); + initiate_dialback(session); + else + s2s_mark_connected(session); + end + end + end + session.notopen = nil; +end + +function stream_callbacks.streamclosed(session) + (session.log or log)("debug", "Received "); + session:close(); +end + +function stream_callbacks.streamdisconnected(session, err) + if err and err ~= "closed" then + (session.log or log)("debug", "s2s connection attempt failed: %s", err); + if s2sout.attempt_connection(session, err) then + (session.log or log)("debug", "...so we're going to try another target"); + return true; -- Session lives for now + end + end + (session.log or log)("info", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "closed")); + sessions[session.conn] = nil; + s2s_destroy_session(session, err); +end + +function stream_callbacks.error(session, error, data) + if error == "no-stream" then + session:close("invalid-namespace"); + elseif error == "parse-error" then + session.log("debug", "Server-to-server XML parse error: %s", tostring(error)); + session:close("not-well-formed"); + elseif error == "stream-error" then + local condition, text = "undefined-condition"; + for child in data:children() do + if child.attr.xmlns == xmlns_xmpp_streams then + if child.name ~= "text" then + condition = child.name; + else + text = child:get_text(); + end + if condition ~= "undefined-condition" and text then + break; + end + end + end + text = condition .. (text and (" ("..text..")") or ""); + session.log("info", "Session closed by remote with error: %s", text); + session:close(nil, text); + end +end + +local function handleerr(err) log("error", "Traceback[s2s]: %s: %s", tostring(err), traceback()); end +function stream_callbacks.handlestanza(session, stanza) + if stanza.attr.xmlns == "jabber:client" then --COMPAT: Prosody pre-0.6.2 may send jabber:client + stanza.attr.xmlns = nil; + end + stanza = session.filter("stanzas/in", stanza); + if stanza then + return xpcall(function () return core_process_stanza(session, stanza) end, handleerr); + end +end + +local listener = { default_port = 5269, default_mode = "*a", default_interface = "*" }; + +--- Session methods +local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; +local default_stream_attr = { ["xmlns:stream"] = "http://etherx.jabber.org/streams", xmlns = stream_callbacks.default_ns, version = "1.0", id = "" }; +local function session_close(session, reason, remote_reason) + local log = session.log or log; + if session.conn then + if session.notopen then + session.sends2s(""); + session.sends2s(st.stanza("stream:stream", default_stream_attr):top_tag()); + end + if reason then + if type(reason) == "string" then -- assume stream error + log("info", "Disconnecting %s[%s], is: %s", session.host or "(unknown host)", session.type, reason); + session.sends2s(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' })); + elseif type(reason) == "table" then + if reason.condition then + local stanza = st.stanza("stream:error"):tag(reason.condition, stream_xmlns_attr):up(); + if reason.text then + stanza:tag("text", stream_xmlns_attr):text(reason.text):up(); + end + if reason.extra then + stanza:add_child(reason.extra); + end + log("info", "Disconnecting %s[%s], is: %s", session.host or "(unknown host)", session.type, tostring(stanza)); + session.sends2s(stanza); + elseif reason.name then -- a stanza + log("info", "Disconnecting %s->%s[%s], is: %s", session.from_host or "(unknown host)", session.to_host or "(unknown host)", session.type, tostring(reason)); + session.sends2s(reason); + end + end + end + session.sends2s(""); + if session.notopen or not session.conn:close() then + session.conn:close(true); -- Force FIXME: timer? + end + session.conn:close(); + listener.ondisconnect(session.conn, remote_reason or (reason and (reason.text or reason.condition)) or reason or "stream closed"); + end +end + +-- Session initialization logic shared by incoming and outgoing +local function initialize_session(session) + local stream = new_xmpp_stream(session, stream_callbacks); + session.stream = stream; + + session.notopen = true; + + function session.reset_stream() + session.notopen = true; + session.stream:reset(); + end + + local filter = session.filter; + function session.data(data) + data = filter("bytes/in", data); + if data then + local ok, err = stream:feed(data); + if ok then return; end + (session.log or log)("warn", "Received invalid XML: %s", data); + (session.log or log)("warn", "Problem was: %s", err); + session:close("not-well-formed"); + end + end + + session.close = session_close; + + local handlestanza = stream_callbacks.handlestanza; + function session.dispatch_stanza(session, stanza) + return handlestanza(session, stanza); + end + + local conn = session.conn; + add_task(connect_timeout, function () + if session.conn ~= conn or session.connecting + or session.type == "s2sin" or session.type == "s2sout" then + return; -- Ok, we're connect[ed|ing] + end + -- Not connected, need to close session and clean up + (session.log or log)("debug", "Destroying incomplete session %s->%s due to inactivity", + session.from_host or "(unknown)", session.to_host or "(unknown)"); + session:close("connection-timeout"); + end); +end + +function listener.onconnect(conn) + if not sessions[conn] then -- May be an existing outgoing session + local session = s2s_new_incoming(conn); + sessions[conn] = session; + session.log("debug", "Incoming s2s connection"); + + local filter = initialize_filters(session); + local w = conn.write; + session.sends2s = function (t) + log("debug", "sending: %s", t.top_tag and t:top_tag() or t:match("^([^>]*>?)")); + if t.name then + t = filter("stanzas/out", t); + end + if t then + t = filter("bytes/out", tostring(t)); + if t then + return w(conn, t); + end + end + end + + initialize_session(session); + end +end + +function listener.onincoming(conn, data) + local session = sessions[conn]; + if session then + session.data(data); + end +end + +function listener.onstatus(conn, status) + if status == "ssl-handshake-complete" then + local session = sessions[conn]; + if session and session.direction == "outgoing" then + local to_host, from_host = session.to_host, session.from_host; + session.log("debug", "Sending stream header..."); + session:open_stream(session.from_host, session.to_host); + end + end +end + +function listener.ondisconnect(conn, err) + local session = sessions[conn]; + if session then + if stream_callbacks.streamdisconnected(session, err) then + return; -- Connection lives, for now + end + end + sessions[conn] = nil; +end + +function listener.register_outgoing(conn, session) + session.direction = "outgoing"; + sessions[conn] = session; + initialize_session(session); +end + +s2sout.set_listener(listener); + +require "core.portmanager".register_service("s2s", { + listener = listener; + default_port = 5269; + encryption = "starttls"; +}); + diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua new file mode 100644 index 00000000..094126e7 --- /dev/null +++ b/plugins/s2s/s2sout.lib.lua @@ -0,0 +1,314 @@ +-- Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + +--- Module containing all the logic for connecting to a remote server + +local initialize_filters = require "util.filters".initialize; +local idna_to_ascii = require "util.encodings".idna.to_ascii; +local add_task = require "util.timer".add_task; +local socket = require "socket"; + +local s2s_destroy_session = require "core.s2smanager".destroy_session; + +local s2sout = {}; + +local s2s_listener; + +function s2sout.set_listener(listener) + s2s_listener = listener; +end + +local function compare_srv_priorities(a,b) + return a.priority < b.priority or (a.priority == b.priority and a.weight > b.weight); +end + +local function session_open_stream(session, from, to) + session.sends2s(st.stanza("stream:stream", { + xmlns='jabber:server', ["xmlns:db"]='jabber:server:dialback', + ["xmlns:stream"]='http://etherx.jabber.org/streams', + from=from, to=to, version='1.0', ["xml:lang"]='en'}):top_tag()); +end + +function s2sout.initiate_connection(host_session) + initialize_filters(host_session); + session.open_stream = session_open_stream; + + -- Kick the connection attempting machine into life + if not s2sout.attempt_connection(host_session) then + -- Intentionally not returning here, the + -- session is needed, connected or not + s2s_destroy_session(host_session); + end + + if not host_session.sends2s then + -- A sends2s which buffers data (until the stream is opened) + -- note that data in this buffer will be sent before the stream is authed + -- and will not be ack'd in any way, successful or otherwise + local buffer; + function host_session.sends2s(data) + if not buffer then + buffer = {}; + host_session.send_buffer = buffer; + end + log("debug", "Buffering data on unconnected s2sout to %s", to_host); + buffer[#buffer+1] = data; + log("debug", "Buffered item %d: %s", #buffer, tostring(data)); + end + end +end + +function s2sout.attempt_connection(host_session, err) + local from_host, to_host = host_session.from_host, host_session.to_host; + local connect_host, connect_port = to_host and idna_to_ascii(to_host), 5269; + + if not connect_host then + return false; + end + + if not err then -- This is our first attempt + log("debug", "First attempt to connect to %s, starting with SRV lookup...", to_host); + host_session.connecting = true; + local handle; + handle = adns.lookup(function (answer) + handle = nil; + host_session.connecting = nil; + if answer then + log("debug", to_host.." has SRV records, handling..."); + local srv_hosts = {}; + host_session.srv_hosts = srv_hosts; + for _, record in ipairs(answer) do + t_insert(srv_hosts, record.srv); + end + if #srv_hosts == 1 and srv_hosts[1].target == "." then + log("debug", to_host.." does not provide a XMPP service"); + s2s_destroy_session(host_session, err); -- Nothing to see here + return; + end + t_sort(srv_hosts, compare_srv_priorities); + + local srv_choice = srv_hosts[1]; + host_session.srv_choice = 1; + if srv_choice then + connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; + log("debug", "Best record found, will connect to %s:%d", connect_host, connect_port); + end + else + log("debug", to_host.." has no SRV records, falling back to A"); + end + -- Try with SRV, or just the plain hostname if no SRV + local ok, err = s2sout.try_connect(host_session, connect_host, connect_port); + if not ok then + if not s2sout.attempt_connection(host_session, err) then + -- No more attempts will be made + s2s_destroy_session(host_session, err); + end + end + end, "_xmpp-server._tcp."..connect_host..".", "SRV"); + + return true; -- Attempt in progress + elseif host_session.ip_hosts then + return s2sout.try_connect(host_session, connect_host, connect_port, err); + elseif host_session.srv_hosts and #host_session.srv_hosts > host_session.srv_choice then -- Not our first attempt, and we also have SRV + host_session.srv_choice = host_session.srv_choice + 1; + local srv_choice = host_session.srv_hosts[host_session.srv_choice]; + connect_host, connect_port = srv_choice.target or to_host, srv_choice.port or connect_port; + host_session.log("info", "Connection failed (%s). Attempt #%d: This time to %s:%d", tostring(err), host_session.srv_choice, connect_host, connect_port); + else + host_session.log("info", "Out of connection options, can't connect to %s", tostring(host_session.to_host)); + -- We're out of options + return false; + end + + if not (connect_host and connect_port) then + -- Likely we couldn't resolve DNS + log("warn", "Hmm, we're without a host (%s) and port (%s) to connect to for %s, giving up :(", tostring(connect_host), tostring(connect_port), tostring(to_host)); + return false; + end + + return s2sout.try_connect(host_session, connect_host, connect_port); +end + +function s2sout.try_next_ip(host_session) + host_session.connecting = nil; + host_session.ip_choice = host_session.ip_choice + 1; + local ip = host_session.ip_hosts[host_session.ip_choice]; + local ok, err= s2sout.make_connect(host_session, ip.ip, ip.port); + if not ok then + if not s2sout.attempt_connection(host_session, err or "closed") then + err = err and (": "..err) or ""; + s2s_destroy_session(host_session, "Connection failed"..err); + end + end +end + +function s2sout.try_connect(host_session, connect_host, connect_port, err) + host_session.connecting = true; + + if not err then + local IPs = {}; + host_session.ip_hosts = IPs; + local handle4, handle6; + local has_other = false; + + if not sources then + sources = {}; + for i, source in ipairs(cfg_sources) do + if source == "*" then + sources[i] = new_ip("0.0.0.0", "IPv4"); + else + sources[i] = new_ip(source, (source:find(":") and "IPv6") or "IPv4"); + end + end + end + + handle4 = adns.lookup(function (reply, err) + handle4 = nil; + + -- COMPAT: This is a compromise for all you CNAME-(ab)users :) + if not (reply and reply[#reply] and reply[#reply].a) then + local count = max_dns_depth; + reply = dns.peek(connect_host, "CNAME", "IN"); + while count > 0 and reply and reply[#reply] and not reply[#reply].a and reply[#reply].cname do + log("debug", "Looking up %s (DNS depth is %d)", tostring(reply[#reply].cname), count); + reply = dns.peek(reply[#reply].cname, "A", "IN") or dns.peek(reply[#reply].cname, "CNAME", "IN"); + count = count - 1; + end + end + -- end of CNAME resolving + + if reply and reply[#reply] and reply[#reply].a then + for _, ip in ipairs(reply) do + log("debug", "DNS reply for %s gives us %s", connect_host, ip.a); + IPs[#IPs+1] = new_ip(ip.a, "IPv4"); + end + end + + if has_other then + if #IPs > 0 then + rfc3484_dest(host_session.ip_hosts, sources); + for i = 1, #IPs do + IPs[i] = {ip = IPs[i], port = connect_port}; + end + host_session.ip_choice = 0; + s2sout.try_next_ip(host_session); + else + log("debug", "DNS lookup failed to get a response for %s", connect_host); + host_session.ip_hosts = nil; + if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can + log("debug", "No other records to try for %s - destroying", host_session.to_host); + err = err and (": "..err) or ""; + s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't + end + end + else + has_other = true; + end + end, connect_host, "A", "IN"); + + handle6 = adns.lookup(function (reply, err) + handle6 = nil; + + if reply and reply[#reply] and reply[#reply].aaaa then + for _, ip in ipairs(reply) do + log("debug", "DNS reply for %s gives us %s", connect_host, ip.aaaa); + IPs[#IPs+1] = new_ip(ip.aaaa, "IPv6"); + end + end + + if has_other then + if #IPs > 0 then + rfc3484_dest(host_session.ip_hosts, sources); + for i = 1, #IPs do + IPs[i] = {ip = IPs[i], port = connect_port}; + end + host_session.ip_choice = 0; + s2sout.try_next_ip(host_session); + else + log("debug", "DNS lookup failed to get a response for %s", connect_host); + host_session.ip_hosts = nil; + if not s2sout.attempt_connection(host_session, "name resolution failed") then -- Retry if we can + log("debug", "No other records to try for %s - destroying", host_session.to_host); + err = err and (": "..err) or ""; + s2s_destroy_session(host_session, "DNS resolution failed"..err); -- End of the line, we can't + end + end + else + has_other = true; + end + end, connect_host, "AAAA", "IN"); + + return true; + elseif host_session.ip_hosts and #host_session.ip_hosts > host_session.ip_choice then -- Not our first attempt, and we also have IPs left to try + s2sout.try_next_ip(host_session); + else + host_session.ip_hosts = nil; + if not s2sout.attempt_connection(host_session, "out of IP addresses") then -- Retry if we can + log("debug", "No other records to try for %s - destroying", host_session.to_host); + err = err and (": "..err) or ""; + s2s_destroy_session(host_session, "Connecting failed"..err); -- End of the line, we can't + return false; + end + end + + return true; +end + +function s2sout.make_connect(host_session, connect_host, connect_port) + (host_session.log or log)("info", "Beginning new connection attempt to %s ([%s]:%d)", host_session.to_host, connect_host.addr, connect_port); + -- Ok, we're going to try to connect + + local from_host, to_host = host_session.from_host, host_session.to_host; + + local conn, handler; + if connect_host.proto == "IPv4" then + conn, handler = socket.tcp(); + else + conn, handler = socket.tcp6(); + end + + if not conn then + log("warn", "Failed to create outgoing connection, system error: %s", handler); + return false, handler; + end + + conn:settimeout(0); + local success, err = conn:connect(connect_host.addr, connect_port); + if not success and err ~= "timeout" then + log("warn", "s2s connect() to %s (%s:%d) failed: %s", host_session.to_host, connect_host.addr, connect_port, err); + return false, err; + end + + conn = wrapclient(conn, connect_host.addr, connect_port, s2s_listener, "*a"); + host_session.conn = conn; + + local filter = initialize_filters(host_session); + local w, log = conn.write, host_session.log; + host_session.sends2s = function (t) + log("debug", "sending: %s", (t.top_tag and t:top_tag()) or t:match("^[^>]*>?")); + if t.name then + t = filter("stanzas/out", t); + end + if t then + t = filter("bytes/out", tostring(t)); + if t then + return w(conn, tostring(t)); + end + end + end + + -- Register this outgoing connection so that xmppserver_listener knows about it + -- otherwise it will assume it is a new incoming connection + s2s_listener.register_outgoing(conn, host_session); + + host_session:open_stream(from_host, to_host); + + log("debug", "Connection attempt in progress..."); + return true; +end + +return s2sout; -- cgit v1.2.3 From 6193d32da9e97508e62c3f4dfb0eb4d1a129c72a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 22 Feb 2012 23:12:57 +0100 Subject: mod_s2s: Add some missing imports --- plugins/s2s/mod_s2s.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 5be4d84b..219e6952 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -18,6 +18,9 @@ local new_xmpp_stream = require "util.xmppstream".new; local s2s_new_incoming = require "core.s2smanager".new_incoming; local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2s_destroy_session = require "core.s2smanager".destroy_session; +local nameprep = require "util.encodings".stringprep.nameprep; +local uuid_gen = require "util.uuid".generate; +local cert_verify_identity = require "util.x509".verify_identity; local s2sout = module:require("s2sout"); -- cgit v1.2.3 From 364c78e2497fcc5d2e285970c48935e88a0261ff Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 22 Feb 2012 23:14:21 +0100 Subject: mod_s2s: Fix typo --- plugins/s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 219e6952..7c0a99de 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -192,7 +192,7 @@ function stream_callbacks.streamopened(session, attr) if session.secure and not session.cert_chain_status then check_cert_status(session); end send(""); - send(stanza("stream:stream", { xmlns='jabber:server', ["xmlns:db"]='jabber:server:dialback', + send(st.stanza("stream:stream", { xmlns='jabber:server', ["xmlns:db"]='jabber:server:dialback', ["xmlns:stream"]='http://etherx.jabber.org/streams', id=session.streamid, from=session.to_host, to=session.from_host, version=(session.version > 0 and "1.0" or nil) }):top_tag()); if session.version >= 1.0 then local features = st.stanza("stream:features"); -- cgit v1.2.3 From 5ddde9afe607893a858d7249cb2fbf0b1b022f8f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 23 Feb 2012 23:03:28 +0100 Subject: mod_s2s: Initiate connections --- plugins/s2s/mod_s2s.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 7c0a99de..bb1a6dd7 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -92,6 +92,7 @@ function send_to_host(from_host, to_host, stanza) else log("debug", "opening a new outgoing connection for this stanza"); local host_session = s2s_new_outgoing(from_host, to_host); + s2sout.initiate_connection(host_session); -- Store in buffer host_session.bounce_sendq = bounce_sendq; -- cgit v1.2.3 From 7a3928f68e1bb18f483ce9c58c6f2e1d73204213 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 23 Feb 2012 23:04:59 +0100 Subject: mod_s2s: Attach send function to session --- plugins/s2s/mod_s2s.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index bb1a6dd7..90bedce9 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -192,6 +192,9 @@ function stream_callbacks.streamopened(session, attr) if session.secure and not session.cert_chain_status then check_cert_status(session); end + function session.send(data) + return send_to_host(session.to_host, session.from_host, data); + end send(""); send(st.stanza("stream:stream", { xmlns='jabber:server', ["xmlns:db"]='jabber:server:dialback', ["xmlns:stream"]='http://etherx.jabber.org/streams', id=session.streamid, from=session.to_host, to=session.from_host, version=(session.version > 0 and "1.0" or nil) }):top_tag()); -- cgit v1.2.3 From d30dec6f355008b4b60b7ae7739e5ca6baa48f05 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 23 Feb 2012 23:09:09 +0100 Subject: s2sout.lib: Import various util.* --- plugins/s2s/s2sout.lib.lua | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index 094126e7..d84854a8 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -8,12 +8,18 @@ --- Module containing all the logic for connecting to a remote server +local wrapclient = require "net.server".wrapclient; local initialize_filters = require "util.filters".initialize; local idna_to_ascii = require "util.encodings".idna.to_ascii; local add_task = require "util.timer".add_task; +local new_ip = require "util.ip".new_ip; +local rfc3484_dest = require "util.rfc3484".destination; local socket = require "socket"; +local t_insert, t_sort = table.insert, table.sort; +local st = require "util.stanza"; local s2s_destroy_session = require "core.s2smanager".destroy_session; +local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2sout = {}; -- cgit v1.2.3 From cf1aa003da3524d839effd7c9f7dd5eb1a46510d Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 23 Feb 2012 23:12:08 +0100 Subject: s2sout.lib: Add locals for source interfaces --- plugins/s2s/s2sout.lib.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index d84854a8..04a5c072 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -25,6 +25,9 @@ local s2sout = {}; local s2s_listener; +local cfg_sources = config.get("*", "core", "s2s_interfaces") or {"*"}; +local sources + function s2sout.set_listener(listener) s2s_listener = listener; end -- cgit v1.2.3 From ddef415e167351b9197a06bfd1d401e70dd37e13 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 23 Feb 2012 23:12:24 +0100 Subject: s2sout.lib: Fix wrong variable name --- plugins/s2s/s2sout.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index 04a5c072..64786862 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -45,7 +45,7 @@ end function s2sout.initiate_connection(host_session) initialize_filters(host_session); - session.open_stream = session_open_stream; + host_session.open_stream = session_open_stream; -- Kick the connection attempting machine into life if not s2sout.attempt_connection(host_session) then -- cgit v1.2.3 From 24bfbf5ce26959ffcd466ce43c69a07adaa4c81b Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Fri, 24 Feb 2012 15:20:03 +0000 Subject: mod_dialback: import util.hashes and functionality once in s2smanager. --- plugins/mod_dialback.lua | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index e27f8657..977e58c3 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -6,22 +6,37 @@ -- COPYING file in the source package for more information. -- +local format = string.format; local hosts = _G.hosts; local send_s2s = require "core.s2smanager".send_to_host; local s2s_make_authenticated = require "core.s2smanager".make_authenticated; -local s2s_initiate_dialback = require "core.s2smanager".initiate_dialback; -local s2s_verify_dialback = require "core.s2smanager".verify_dialback; local log = module._log; local st = require "util.stanza"; +local sha256_hash = require "util.hashes".sha256; local xmlns_stream = "http://etherx.jabber.org/streams"; local xmlns_dialback = "jabber:server:dialback"; local dialback_requests = setmetatable({}, { __mode = 'v' }); +function generate_dialback(id, to, from) + return sha256_hash(id..to..from..hosts[from].dialback_secret, true); +end + +function initiate_dialback(session) + -- generate dialback key + session.dialback_key = generate_dialback(session.streamid, session.to_host, session.from_host); + session.sends2s(format("%s", session.from_host, session.to_host, session.dialback_key)); + session.log("info", "sent dialback key on outgoing s2s stream"); +end + +function verify_dialback(id, to, from, key) + return key == generate_dialback(id, to, from); +end + module:hook("stanza/jabber:server:dialback:verify", function(event) local origin, stanza = event.origin, event.stanza; @@ -32,7 +47,7 @@ module:hook("stanza/jabber:server:dialback:verify", function(event) -- COMPAT: Grr, ejabberd breaks this one too?? it is black and white in XEP-220 example 34 --if attr.from ~= origin.to_host then error("invalid-from"); end local type; - if s2s_verify_dialback(attr.id, attr.from, attr.to, stanza[1]) then + if verify_dialback(attr.id, attr.from, attr.to, stanza[1]) then type = "valid" else type = "invalid" @@ -72,8 +87,8 @@ module:hook("stanza/jabber:server:dialback:result", function(event) end origin.log("debug", "asking %s if key %s belongs to them", attr.from, stanza[1]); - send_s2s(attr.to, attr.from, - st.stanza("db:verify", { from = attr.to, to = attr.from, id = origin.streamid }):text(stanza[1])); + --send_s2s(attr.to, attr.from, + origin.send(st.stanza("db:verify", { from = attr.to, to = attr.from, id = origin.streamid }):text(stanza[1])); return true; end end); @@ -84,6 +99,7 @@ module:hook("stanza/jabber:server:dialback:verify", function(event) if origin.type == "s2sout_unauthed" or origin.type == "s2sout" then local attr = stanza.attr; local dialback_verifying = dialback_requests[attr.from.."/"..(attr.id or "")]; + module:log("debug", tostring(dialback_verifying).." "..attr.from.." "..origin.to_host); if dialback_verifying and attr.from == origin.to_host then local valid; if attr.type == "valid" then @@ -134,14 +150,14 @@ end); module:hook_stanza("urn:ietf:params:xml:ns:xmpp-sasl", "failure", function (origin, stanza) if origin.external_auth == "failed" then module:log("debug", "SASL EXTERNAL failed, falling back to dialback"); - s2s_initiate_dialback(origin); + initiate_dialback(origin); return true; end end, 100); module:hook_stanza(xmlns_stream, "features", function (origin, stanza) if not origin.external_auth or origin.external_auth == "failed" then - s2s_initiate_dialback(origin); + initiate_dialback(origin); return true; end end, 100); -- cgit v1.2.3 From eda5f26eb482f9f74949248f0fd9bd60e4f5580d Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Fri, 24 Feb 2012 15:21:21 +0000 Subject: mod_s2s: port functionality once in s2smanager. --- plugins/s2s/mod_s2s.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 5be4d84b..0de821b2 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -14,10 +14,12 @@ local xpcall, traceback = xpcall, debug.traceback; local add_task = require "util.timer".add_task; local st = require "util.stanza"; local initialize_filters = require "util.filters".initialize; +local nameprep = require "util.encodings".stringprep.nameprep; local new_xmpp_stream = require "util.xmppstream".new; local s2s_new_incoming = require "core.s2smanager".new_incoming; local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2s_destroy_session = require "core.s2smanager".destroy_session; +local uuid_gen = require "util.uuid".generate; local s2sout = module:require("s2sout"); @@ -94,6 +96,7 @@ function send_to_host(from_host, to_host, stanza) host_session.bounce_sendq = bounce_sendq; host_session.sendq = { {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)} }; log("debug", "stanza [%s] queued until connection complete", tostring(stanza.name)); + s2sout.initiate_connection(host_session); if (not host_session.connecting) and (not host_session.conn) then log("warn", "Connection to %s failed already, destroying session...", to_host); if not s2s_destroy_session(host_session, "Connection failed") then @@ -102,7 +105,6 @@ function send_to_host(from_host, to_host, stanza) end return false; end - s2sout.initiate_connection(host_session); end return true; end @@ -189,7 +191,7 @@ function stream_callbacks.streamopened(session, attr) if session.secure and not session.cert_chain_status then check_cert_status(session); end send(""); - send(stanza("stream:stream", { xmlns='jabber:server', ["xmlns:db"]='jabber:server:dialback', + send(stanza.stanza("stream:stream", { xmlns='jabber:server', ["xmlns:db"]='jabber:server:dialback', ["xmlns:stream"]='http://etherx.jabber.org/streams', id=session.streamid, from=session.to_host, to=session.from_host, version=(session.version > 0 and "1.0" or nil) }):top_tag()); if session.version >= 1.0 then local features = st.stanza("stream:features"); @@ -235,6 +237,7 @@ function stream_callbacks.streamopened(session, attr) end end session.notopen = nil; + session.send = function(stanza) send_to_host(session.to_host, session.from_host, stanza); end; end function stream_callbacks.streamclosed(session) -- cgit v1.2.3 From 35ddcf0af31198baef0f4ce2e580b041486d5194 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Fri, 24 Feb 2012 15:24:10 +0000 Subject: s2sout.lib: import utils/functionality once in s2smanager. --- plugins/s2s/s2sout.lib.lua | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index 094126e7..12669d97 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -8,13 +8,24 @@ --- Module containing all the logic for connecting to a remote server +local t_insert = table.insert; +local t_sort = table.sort; +local ipairs = ipairs; + +local wrapclient = require "net.server".wrapclient; local initialize_filters = require "util.filters".initialize; local idna_to_ascii = require "util.encodings".idna.to_ascii; local add_task = require "util.timer".add_task; +local st = require "util.stanza"; +local new_ip = require "util.ip".new_ip; +local rfc3484_dest = require "util.rfc3484".destination; local socket = require "socket"; +local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2s_destroy_session = require "core.s2smanager".destroy_session; +local cfg_sources = config.get("*", "core", "s2s_interfaces") or socket.local_addresses(); + local s2sout = {}; local s2s_listener; @@ -36,7 +47,7 @@ end function s2sout.initiate_connection(host_session) initialize_filters(host_session); - session.open_stream = session_open_stream; + host_session.open_stream = session_open_stream; -- Kick the connection attempting machine into life if not s2sout.attempt_connection(host_session) then @@ -147,6 +158,7 @@ function s2sout.try_next_ip(host_session) end function s2sout.try_connect(host_session, connect_host, connect_port, err) + local sources; host_session.connecting = true; if not err then @@ -156,7 +168,7 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) local has_other = false; if not sources then - sources = {}; + sources = {}; for i, source in ipairs(cfg_sources) do if source == "*" then sources[i] = new_ip("0.0.0.0", "IPv4"); -- cgit v1.2.3 From c5f76e99d91e5e0fc2c2b47a7ce7499c46fb57ec Mon Sep 17 00:00:00 2001 From: Marco Cirillo Date: Fri, 24 Feb 2012 15:34:25 +0000 Subject: mod_s2s, s2sout.lib: import cert verify and add another fallback method in case socket.local_addresses isn't there. --- plugins/s2s/mod_s2s.lua | 1 + plugins/s2s/s2sout.lib.lua | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 0de821b2..88e8cded 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -20,6 +20,7 @@ local s2s_new_incoming = require "core.s2smanager".new_incoming; local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2s_destroy_session = require "core.s2smanager".destroy_session; local uuid_gen = require "util.uuid".generate; +local cert_verify_identity = require "util.x509".verify_identity; local s2sout = module:require("s2sout"); diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index 12669d97..2856a15c 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -24,7 +24,7 @@ local socket = require "socket"; local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2s_destroy_session = require "core.s2smanager".destroy_session; -local cfg_sources = config.get("*", "core", "s2s_interfaces") or socket.local_addresses(); +local cfg_sources = config.get("*", "core", "s2s_interfaces") or socket.local_addresses and socket.local_addresses() or { "*" }; local s2sout = {}; -- cgit v1.2.3 From f04b6b3bada77a1888082383b85981fe1ced6784 Mon Sep 17 00:00:00 2001 From: Marco Cirillo Date: Fri, 24 Feb 2012 15:35:04 +0000 Subject: mod_admin_telnet: make service private. --- plugins/mod_admin_telnet.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 9e9065bb..d3f5543e 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -776,4 +776,5 @@ end require "core.portmanager".register_service("console", { listener = console_listener; default_port = 5582; + private = true; }); -- cgit v1.2.3 From 0f9c104f0cb7f20a63bf6f890d0d04a690418a1d Mon Sep 17 00:00:00 2001 From: Marco Cirillo Date: Fri, 24 Feb 2012 15:36:36 +0000 Subject: mod_s2s: prevent attempting to reconnect when the stream is gracefully closed and fix TB by checking session.conn is set (racy racy?) --- plugins/s2s/mod_s2s.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 88e8cded..d1fdedb3 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -247,7 +247,7 @@ function stream_callbacks.streamclosed(session) end function stream_callbacks.streamdisconnected(session, err) - if err and err ~= "closed" then + if err and err ~= "stream closed" then (session.log or log)("debug", "s2s connection attempt failed: %s", err); if s2sout.attempt_connection(session, err) then (session.log or log)("debug", "...so we're going to try another target"); @@ -255,7 +255,7 @@ function stream_callbacks.streamdisconnected(session, err) end end (session.log or log)("info", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "closed")); - sessions[session.conn] = nil; + if session.con then sessions[session.conn] = nil; else (session.log or log)("debug", "stale session's connection already closed"); end s2s_destroy_session(session, err); end -- cgit v1.2.3 From b51c0bea3f88b1bc58ffc83c3ec2b0ef6fc31235 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 24 Feb 2012 16:25:38 +0000 Subject: Backed out changeset aba47e6dff43 --- plugins/s2s/mod_s2s.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index d1fdedb3..88e8cded 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -247,7 +247,7 @@ function stream_callbacks.streamclosed(session) end function stream_callbacks.streamdisconnected(session, err) - if err and err ~= "stream closed" then + if err and err ~= "closed" then (session.log or log)("debug", "s2s connection attempt failed: %s", err); if s2sout.attempt_connection(session, err) then (session.log or log)("debug", "...so we're going to try another target"); @@ -255,7 +255,7 @@ function stream_callbacks.streamdisconnected(session, err) end end (session.log or log)("info", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "closed")); - if session.con then sessions[session.conn] = nil; else (session.log or log)("debug", "stale session's connection already closed"); end + sessions[session.conn] = nil; s2s_destroy_session(session, err); end -- cgit v1.2.3 From 74bff42057bbe1dbf278959cff1ae8cab077ac19 Mon Sep 17 00:00:00 2001 From: Marco Cirillo Date: Fri, 24 Feb 2012 18:03:27 +0000 Subject: s2smanager, mod_s2s: clear up ip_hosts after s2s is marked as established, remove useless space from mod_s2s code --- plugins/s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 2573251f..9f522595 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -255,7 +255,7 @@ function stream_callbacks.streamdisconnected(session, err) end end (session.log or log)("info", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "closed")); - sessions[session.conn] = nil; + sessions[session.conn] = nil; s2s_destroy_session(session, err); end -- cgit v1.2.3 From f1e9bb68bd0f366d060c1834dd4955e5dbb1efc4 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 1 Mar 2012 00:14:53 +0100 Subject: mod_s2s: Add missing local table.insert --- plugins/s2s/mod_s2s.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 9f522595..ec01934d 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -9,6 +9,7 @@ module:set_global(); local tostring, type = tostring, type; +local t_insert = table.insert; local xpcall, traceback = xpcall, debug.traceback; local add_task = require "util.timer".add_task; -- cgit v1.2.3 From 11993525c0a7cae7fe52aba0bafdfca912973499 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 3 Mar 2012 00:01:10 +0100 Subject: mod_dialback: Remove unused import of s2smanager.send_to_host() --- plugins/mod_dialback.lua | 2 -- 1 file changed, 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index 977e58c3..eccfd3d6 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -9,7 +9,6 @@ local format = string.format; local hosts = _G.hosts; -local send_s2s = require "core.s2smanager".send_to_host; local s2s_make_authenticated = require "core.s2smanager".make_authenticated; local log = module._log; @@ -87,7 +86,6 @@ module:hook("stanza/jabber:server:dialback:result", function(event) end origin.log("debug", "asking %s if key %s belongs to them", attr.from, stanza[1]); - --send_s2s(attr.to, attr.from, origin.send(st.stanza("db:verify", { from = attr.to, to = attr.from, id = origin.streamid }):text(stanza[1])); return true; end -- cgit v1.2.3 From 8f72c46ae033d0f57e37fd1c8e44f94304f8afde Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 3 Mar 2012 00:03:06 +0100 Subject: mod_s2s: Split send_to_host() into two route/remote hooks, one for already exsisting sessions and one for non-existent. --- plugins/s2s/mod_s2s.lua | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index ec01934d..c00ff653 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -60,7 +60,8 @@ local function bounce_sendq(session, reason) session.sendq = nil; end -function send_to_host(from_host, to_host, stanza) +module:hook("route/remote", function (event) + local from_host, to_host, stanza = event.from_host, event.to_host, event.stanza; if not hosts[from_host] then log("warn", "Attempt to send stanza from %s - a host we don't serve", from_host); return false; @@ -70,7 +71,7 @@ function send_to_host(from_host, to_host, stanza) -- We have a connection to this host already if host.type == "s2sout_unauthed" and (stanza.name ~= "db:verify" or not host.dialback_key) then (host.log or log)("debug", "trying to send over unauthed s2sout to "..to_host); - + -- Queue stanza until we are able to send it if host.sendq then t_insert(host.sendq, {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)}); else host.sendq = { {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)} }; end @@ -90,30 +91,28 @@ function send_to_host(from_host, to_host, stanza) host.sends2s(stanza); host.log("debug", "stanza sent over "..host.type); end - else - log("debug", "opening a new outgoing connection for this stanza"); - local host_session = s2s_new_outgoing(from_host, to_host); - - -- Store in buffer - host_session.bounce_sendq = bounce_sendq; - host_session.sendq = { {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)} }; - log("debug", "stanza [%s] queued until connection complete", tostring(stanza.name)); - s2sout.initiate_connection(host_session); - if (not host_session.connecting) and (not host_session.conn) then - log("warn", "Connection to %s failed already, destroying session...", to_host); - if not s2s_destroy_session(host_session, "Connection failed") then - -- Already destroyed, we need to bounce our stanza - host_session:bounce_sendq(host_session.destruction_reason); - end - return false; - end end - return true; -end +end, 200); module:hook("route/remote", function (event) - return send_to_host(event.from_host, event.to_host, event.stanza); -end); + local from_host, to_host, stanza = event.from_host, event.to_host, event.stanza; + log("debug", "opening a new outgoing connection for this stanza"); + local host_session = s2s_new_outgoing(from_host, to_host); + + -- Store in buffer + host_session.bounce_sendq = bounce_sendq; + host_session.sendq = { {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)} }; + log("debug", "stanza [%s] queued until connection complete", tostring(stanza.name)); + s2sout.initiate_connection(host_session); + if (not host_session.connecting) and (not host_session.conn) then + log("warn", "Connection to %s failed already, destroying session...", to_host); + if not s2s_destroy_session(host_session, "Connection failed") then + -- Already destroyed, we need to bounce our stanza + host_session:bounce_sendq(host_session.destruction_reason); + end + return false; + end +end, 100); --- Helper to check that a session peer's certificate is valid local function check_cert_status(session) @@ -239,7 +238,7 @@ function stream_callbacks.streamopened(session, attr) end end session.notopen = nil; - session.send = function(stanza) send_to_host(session.to_host, session.from_host, stanza); end; + session.send = function(stanza) prosody.events.fire_event("route/remote", { from_host = session.to_host, to_host = session.from_host, stanza = stanza}) end; end function stream_callbacks.streamclosed(session) -- cgit v1.2.3 From 82925c2003205354bc57d48769eefbc289e825bf Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 3 Mar 2012 00:14:48 +0100 Subject: mod_s2s: return true when we sent the stanza, or initiated a new s2sout --- plugins/s2s/mod_s2s.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index c00ff653..de3ad4e1 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -90,6 +90,7 @@ module:hook("route/remote", function (event) end host.sends2s(stanza); host.log("debug", "stanza sent over "..host.type); + return true; end end end, 200); @@ -112,6 +113,7 @@ module:hook("route/remote", function (event) end return false; end + return true; end, 100); --- Helper to check that a session peer's certificate is valid -- cgit v1.2.3 From 92dbf7e7a2a3ad3139d2a884cf90c740acfa9987 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 3 Mar 2012 00:32:57 +0100 Subject: mod_admin_telnet: Import util.iterators properly --- plugins/mod_admin_telnet.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index d3f5543e..fd72787e 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -15,7 +15,8 @@ local hosts = prosody.hosts; local console_listener = { default_port = 5582; default_mode = "*l"; interface = "127.0.0.1" }; -require "util.iterators"; +local iterators = require "util.iterators"; +local keys, values = iterators.keys, iterators.values; local jid_bare = require "util.jid".bare; local set, array = require "util.set", require "util.array"; local cert_verify_identity = require "util.x509".verify_identity; -- cgit v1.2.3 From 9af8ea363badf58a8d59e475035a4def10dd42c9 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 3 Mar 2012 01:35:39 +0100 Subject: mod_s2s, mod_dialback: Event on pre-XMPP streams, so we can try dialback. --- plugins/mod_dialback.lua | 5 +++++ plugins/s2s/mod_s2s.lua | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index eccfd3d6..5cb59fef 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -160,6 +160,11 @@ module:hook_stanza(xmlns_stream, "features", function (origin, stanza) end end, 100); +module:hook("s2s-no-stream-features", function (event) + initiate_dialback(event.origin); + return true; +end, 100); + -- Offer dialback to incoming hosts module:hook("s2s-stream-features", function (data) data.features:tag("dialback", { xmlns='urn:xmpp:features:dialback' }):up(); diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index de3ad4e1..9ab2ee0a 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -233,7 +233,7 @@ function stream_callbacks.streamopened(session, attr) if session.version < 1.0 then if not session.dialback_verifying then log("debug", "Initiating dialback..."); - initiate_dialback(session); + hosts[session.from_host].events.fire_event("s2s-no-stream-features", { origin = session }); else s2s_mark_connected(session); end -- cgit v1.2.3 From d0424f6f4e316f435f8e4db6f4906964c7d8f31f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 3 Mar 2012 13:28:33 +0100 Subject: mod_s2s, mod_dialback: Rename event to s2s-authenticate-legacy --- plugins/mod_dialback.lua | 2 +- plugins/s2s/mod_s2s.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index 5cb59fef..2c2dc795 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -160,7 +160,7 @@ module:hook_stanza(xmlns_stream, "features", function (origin, stanza) end end, 100); -module:hook("s2s-no-stream-features", function (event) +module:hook("s2s-authenticate-legacy", function (event) initiate_dialback(event.origin); return true; end, 100); diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 9ab2ee0a..bebf1962 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -233,7 +233,7 @@ function stream_callbacks.streamopened(session, attr) if session.version < 1.0 then if not session.dialback_verifying then log("debug", "Initiating dialback..."); - hosts[session.from_host].events.fire_event("s2s-no-stream-features", { origin = session }); + hosts[session.from_host].events.fire_event("s2s-authenticate-legacy", { origin = session }); else s2s_mark_connected(session); end -- cgit v1.2.3 From 58900081f68e8db61675febc4f9c4078e44d384a Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 3 Mar 2012 16:45:34 +0100 Subject: mod_dialback, mod_s2s: Log initiation of dialback in mod_dialback --- plugins/mod_dialback.lua | 2 ++ plugins/s2s/mod_s2s.lua | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index 2c2dc795..e578c412 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -155,12 +155,14 @@ end, 100); module:hook_stanza(xmlns_stream, "features", function (origin, stanza) if not origin.external_auth or origin.external_auth == "failed" then + module:log("debug", "Initiating dialback..."); initiate_dialback(origin); return true; end end, 100); module:hook("s2s-authenticate-legacy", function (event) + module:log("debug", "Initiating dialback..."); initiate_dialback(event.origin); return true; end, 100); diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index bebf1962..407a7e04 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -232,7 +232,6 @@ function stream_callbacks.streamopened(session, attr) -- If server is pre-1.0, don't wait for features, just do dialback if session.version < 1.0 then if not session.dialback_verifying then - log("debug", "Initiating dialback..."); hosts[session.from_host].events.fire_event("s2s-authenticate-legacy", { origin = session }); else s2s_mark_connected(session); -- cgit v1.2.3 From 14a9e3f3c9919642364ea3076fe97cf3adecdd65 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 4 Mar 2012 17:39:19 +0100 Subject: mod_s2s: Log the entire stream header. --- plugins/s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 407a7e04..5e03e896 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -172,7 +172,7 @@ function stream_callbacks.streamopened(session, attr) session.from_host = attr.from and nameprep(attr.from); session.streamid = uuid_gen(); - (session.log or log)("debug", "Incoming s2s received "); + (session.log or log)("debug", "Incoming s2s received %s", st.stanza("stream:stream", attr):top_tag()); if session.to_host then if not hosts[session.to_host] then -- Attempting to connect to a host we don't serve -- cgit v1.2.3 From 5ccc1d34107c59823d859fe77c1b404b817de194 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 5 Mar 2012 11:07:10 +0000 Subject: mod_s2s: streamopened(): Tighter validation around stream 'to' and 'from' attributes, and only set to_host and from_host if they aren't set already and if the session hasn't already been authenticated --- plugins/s2s/mod_s2s.lua | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 407a7e04..fcdd9dd6 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -168,9 +168,33 @@ function stream_callbacks.streamopened(session, attr) if session.direction == "incoming" then -- Send a reply stream header - session.to_host = attr.to and nameprep(attr.to); - session.from_host = attr.from and nameprep(attr.from); - + + -- Validate to/from + local to, from = nameprep(attr.to), nameprep(attr.from); + if not to and attr.to then -- COMPAT: Some servers do not reliably set 'to' (especially on stream restarts) + session:close({ condition = "improper-addressing", text = "Invalid 'to' address" }); + return; + end + if not from and attr.from then -- COMPAT: Some servers do not reliably set 'from' (especially on stream restarts) + session:close({ condition = "improper-addressing", text = "Invalid 'from' address" }); + return; + end + + -- Set session.[from/to]_host if they have not been set already and if + -- this session isn't already authenticated + if session.type == "s2sin_unauthed" and from and not session.from_host then + session.from_host = from; + elseif from ~= session.from_host then + session:close({ condition = "improper-addressing", text = "New stream 'from' attribute does not match original" }); + return; + end + if session.type == "s2sin_unauthed" and to and not session.to_host then + session.to_host = to; + elseif to ~= session.to_host then + session:close({ condition = "improper-addressing", text = "New stream 'to' attribute does not match original" }); + return; + end + session.streamid = uuid_gen(); (session.log or log)("debug", "Incoming s2s received "); if session.to_host then -- cgit v1.2.3 From c779ee4b9a029c14d23b71afe65b9462c097633a Mon Sep 17 00:00:00 2001 From: Marco Cirillo Date: Mon, 5 Mar 2012 16:39:50 +0000 Subject: mod_s2s: remove conn sessions clearing redundancy and leave it only in listener.ondisconnect --- plugins/s2s/mod_s2s.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index fcdd9dd6..ab122f12 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -280,7 +280,6 @@ function stream_callbacks.streamdisconnected(session, err) end end (session.log or log)("info", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "closed")); - sessions[session.conn] = nil; s2s_destroy_session(session, err); end @@ -457,7 +456,7 @@ function listener.ondisconnect(conn, err) return; -- Connection lives, for now end end - sessions[conn] = nil; + sessions[conn] = nil; end function listener.register_outgoing(conn, session) -- cgit v1.2.3 From df4bd370e7ad7bc3807df566d10b3d491e706bb8 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 7 Mar 2012 21:12:04 +0100 Subject: mod_admin_adhoc: Import util.iterators properly --- plugins/mod_admin_adhoc.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_adhoc.lua b/plugins/mod_admin_adhoc.lua index d78c1aee..a594483c 100644 --- a/plugins/mod_admin_adhoc.lua +++ b/plugins/mod_admin_adhoc.lua @@ -10,7 +10,8 @@ local prosody = _G.prosody; local hosts = prosody.hosts; local t_concat = table.concat; -require "util.iterators"; +local iterators = require "util.iterators"; +local keys, values = iterators.keys, iterators.values; local usermanager_user_exists = require "core.usermanager".user_exists; local usermanager_create_user = require "core.usermanager".create_user; local usermanager_get_password = require "core.usermanager".get_password; -- cgit v1.2.3 From d0e26c42f6716298c0cb7f245e25036c4f5d7561 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Wed, 7 Mar 2012 21:14:08 +0100 Subject: mod_admin_adhoc: Use module:depends() --- plugins/mod_admin_adhoc.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/mod_admin_adhoc.lua b/plugins/mod_admin_adhoc.lua index a594483c..6f1357a9 100644 --- a/plugins/mod_admin_adhoc.lua +++ b/plugins/mod_admin_adhoc.lua @@ -24,6 +24,7 @@ local dataforms_new = require "util.dataforms".new; local array = require "util.array"; local modulemanager = require "modulemanager"; +module:depends"adhoc"; local adhoc_new = module:require "adhoc".new; function add_user_command_handler(self, data, state) -- cgit v1.2.3 From 26768f3e54805074211fc0846221acce5765f570 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 11 Mar 2012 19:14:28 +0100 Subject: s2smanager, mod_s2s: Move import of dns_max_depth to mod_s2s --- plugins/s2s/s2sout.lib.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index 808c7e74..4fcb094a 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -23,6 +23,8 @@ local s2s_destroy_session = require "core.s2smanager".destroy_session; local cfg_sources = config.get("*", "core", "s2s_interfaces") or socket.local_addresses and socket.local_addresses() or { "*" }; +local max_dns_depth = module:get_option_number("dns_max_depth", 3); + local s2sout = {}; local s2s_listener; -- cgit v1.2.3 From 7497593c4e0dded060418304f23f709a2d1d664a Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Sun, 11 Mar 2012 20:15:42 +0100 Subject: mod_s2s: Remove obsolete default_interface --- plugins/s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index aa4d5d56..a496af57 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -320,7 +320,7 @@ function stream_callbacks.handlestanza(session, stanza) end end -local listener = { default_port = 5269, default_mode = "*a", default_interface = "*" }; +local listener = { default_port = 5269, default_mode = "*a" }; --- Session methods local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; -- cgit v1.2.3 From eca225365d45123176a348c70f788c4719b43ee1 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Sun, 11 Mar 2012 20:16:57 +0100 Subject: mod_s2s: Collect s2s sources from portmanager and get local address if necessary --- plugins/s2s/s2sout.lib.lua | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index 4fcb094a..f9f9d362 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -8,6 +8,7 @@ --- Module containing all the logic for connecting to a remote server +local portmanager = require "core.portmanager"; local wrapclient = require "net.server".wrapclient; local initialize_filters = require "util.filters".initialize; local idna_to_ascii = require "util.encodings".idna.to_ascii; @@ -21,7 +22,7 @@ local st = require "util.stanza"; local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2s_destroy_session = require "core.s2smanager".destroy_session; -local cfg_sources = config.get("*", "core", "s2s_interfaces") or socket.local_addresses and socket.local_addresses() or { "*" }; +local sources = {}; local max_dns_depth = module:get_option_number("dns_max_depth", 3); @@ -158,7 +159,6 @@ function s2sout.try_next_ip(host_session) end function s2sout.try_connect(host_session, connect_host, connect_port, err) - local sources; host_session.connecting = true; if not err then @@ -167,17 +167,6 @@ function s2sout.try_connect(host_session, connect_host, connect_port, err) local handle4, handle6; local has_other = false; - if not sources then - sources = {}; - for i, source in ipairs(cfg_sources) do - if source == "*" then - sources[i] = new_ip("0.0.0.0", "IPv4"); - else - sources[i] = new_ip(source, (source:find(":") and "IPv6") or "IPv4"); - end - end - end - handle4 = adns.lookup(function (reply, err) handle4 = nil; @@ -323,4 +312,32 @@ function s2sout.make_connect(host_session, connect_host, connect_port) return true; end +module:hook_global("service-added", function (event) + if event.name ~= "s2s" then return end + + local s2s_sources = portmanager.get_active_services():get("s2s"); + + for source, _ in pairs(s2s_sources) do + if source == "*" or source == "0.0.0.0" then + if not socket.local_addresses then + sources[#sources + 1] = new_ip("0.0.0.0", "IPv4"); + else + for _, addr in ipairs(socket.local_addresses("ipv4", true)) do + sources[#sources + 1] = new_ip(addr, "IPv4"); + end + end + elseif source == "::" then + if not socket.local_addresses then + sources[#sources + 1] = new_ip("::", "IPv4"); + else + for _, addr in ipairs(socket.local_addresses("ipv6", true)) do + sources[#sources + 1] = new_ip(addr, "IPv6"); + end + end + else + sources[#sources + 1] = new_ip(source, (source:find(":") and "IPv6") or "IPv4"); + end + end +end); + return s2sout; -- cgit v1.2.3 From c46d5d361b040b984882bb1917bcdc90d094ea94 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sun, 11 Mar 2012 21:37:55 +0100 Subject: mod_s2s: Don't bounce sendq on failed connections since it's handled by s2smanager --- plugins/s2s/mod_s2s.lua | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index a496af57..1fa8ae81 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -107,10 +107,7 @@ module:hook("route/remote", function (event) s2sout.initiate_connection(host_session); if (not host_session.connecting) and (not host_session.conn) then log("warn", "Connection to %s failed already, destroying session...", to_host); - if not s2s_destroy_session(host_session, "Connection failed") then - -- Already destroyed, we need to bounce our stanza - host_session:bounce_sendq(host_session.destruction_reason); - end + s2s_destroy_session(host_session, "Connection failed"); return false; end return true; -- cgit v1.2.3 From afebf2da34488b615692a35a66ae2b9a8584adbe Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 11 Mar 2012 20:56:09 +0000 Subject: mod_auth_internal_{plain,hashed}: Clarify log messages on initialization --- plugins/mod_auth_internal_hashed.lua | 2 +- plugins/mod_auth_internal_plain.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_auth_internal_hashed.lua b/plugins/mod_auth_internal_hashed.lua index ee810426..399044ad 100644 --- a/plugins/mod_auth_internal_hashed.lua +++ b/plugins/mod_auth_internal_hashed.lua @@ -54,7 +54,7 @@ local iteration_count = 4096; function new_hashpass_provider(host) local provider = { name = "internal_hashed" }; - log("debug", "initializing hashpass authentication provider for host '%s'", host); + log("debug", "initializing internal_hashed authentication provider for host '%s'", host); function provider.test_password(username, password) local credentials = datamanager.load(username, host, "accounts") or {}; diff --git a/plugins/mod_auth_internal_plain.lua b/plugins/mod_auth_internal_plain.lua index 784553ea..93b50351 100644 --- a/plugins/mod_auth_internal_plain.lua +++ b/plugins/mod_auth_internal_plain.lua @@ -23,7 +23,7 @@ local prosody = _G.prosody; function new_default_provider(host) local provider = { name = "internal_plain" }; - log("debug", "initializing default authentication provider for host '%s'", host); + log("debug", "initializing internal_plain authentication provider for host '%s'", host); function provider.test_password(username, password) log("debug", "test password '%s' for user %s at host %s", password, username, module.host); -- cgit v1.2.3 From 107458131fbd723e4a0bf486000afd61fdcc9824 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 14 Mar 2012 21:42:08 +0000 Subject: mod_c2s: Use module:add_item() to add the net-provider for portmanager --- plugins/mod_c2s.lua | 6 ++++-- plugins/s2s/mod_s2s.lua | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 682c4e3b..e3557492 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -220,13 +220,15 @@ function listener.associate_session(conn, session) sessions[conn] = session; end -portmanager.register_service("c2s", { +module:add_item("net-provider", { + name = "c2s"; listener = listener; default_port = 5222; encryption = "starttls"; }); -portmanager.register_service("legacy_ssl", { +module:add_item("net-provider", { + name = "legacy_ssl"; listener = listener; encryption = "ssl"; }); diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index a496af57..194364cd 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -467,7 +467,8 @@ end s2sout.set_listener(listener); -require "core.portmanager".register_service("s2s", { +module:add_item("net-provider", { + name = "s2s"; listener = listener; default_port = 5269; encryption = "starttls"; -- cgit v1.2.3 From 437ed35fad3be0ce72b97400dfc765c370e3cf2b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 14 Mar 2012 21:43:46 +0000 Subject: mod_s2s/s2sout.lib: Log message instead of traceback when s2s isn't configured for any ports --- plugins/s2s/s2sout.lib.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index f9f9d362..6ee1ca83 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -316,7 +316,10 @@ module:hook_global("service-added", function (event) if event.name ~= "s2s" then return end local s2s_sources = portmanager.get_active_services():get("s2s"); - + if not s2s_sources then + module:log("warn", "s2s not listening on any ports, outgoing connections may fail"); + return; + end for source, _ in pairs(s2s_sources) do if source == "*" or source == "0.0.0.0" then if not socket.local_addresses then -- cgit v1.2.3 From 46ae4849710de0b5b31d1983c72d6f3d40253ec0 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 15 Mar 2012 03:05:02 +0000 Subject: mod_net_multiplex: Port multiplexing (run multiple different services on a the same port(s))... now pluggable for use with any net plugin --- plugins/mod_net_multiplex.lua | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 plugins/mod_net_multiplex.lua (limited to 'plugins') diff --git a/plugins/mod_net_multiplex.lua b/plugins/mod_net_multiplex.lua new file mode 100644 index 00000000..44e1c1ee --- /dev/null +++ b/plugins/mod_net_multiplex.lua @@ -0,0 +1,70 @@ +module:set_global(); + +local max_buffer_len = module:get_option_number("multiplex_buffer_size", 1024); + +local portmanager = require "core.portmanager"; + +local available_services = {}; + +local function add_service(service) + local multiplex_pattern = service.multiplex and service.multiplex.pattern; + if multiplex_pattern then + module:log("debug", "Adding multiplex service %q with pattern %q", service.name, multiplex_pattern); + available_services[service] = multiplex_pattern; + else + module:log("debug", "Service %q is not multiplex-capable", service.name); + end +end +module:hook("service-added", function (event) add_service(event.service); end); +module:hook("service-removed", function (event) available_services[event.service] = nil; end); + +for service_name, services in pairs(portmanager.get_registered_services()) do + for i, service in ipairs(services) do + add_service(service); + end +end + +local buffers = {}; + +local listener = { default_mode = "*a" }; + +function listener.onconnect() +end + +function listener.onincoming(conn, data) + if not data then return; end + local buf = buffers[conn]; + buffers[conn] = nil; + buf = buf and buf..data or data; + for service, multiplex_pattern in pairs(available_services) do + if buf:match(multiplex_pattern) then + module:log("debug", "Routing incoming connection to %s", service.name); + local listener = service.listener; + conn:setlistener(listener); + local onconnect = listener.onconnect; + if onconnect then onconnect(conn) end + return listener.onincoming(conn, buf); + end + end + if #buf > max_buffer_len then -- Give up + conn:close(); + else + buffers[conn] = buf; + end +end + +function listener.ondisconnect(conn, err) + buffers[conn] = nil; -- warn if no buffer? +end + +module:add_item("net-provider", { + name = "multiplex"; + config_prefix = ""; + listener = listener; +}); + +module:provides("net", { + name = "multiplex_ssl"; + config_prefix = "ssl"; + listener = listener; +}); -- cgit v1.2.3 From 99096dfa23df0d6a7f01d2dcba500cd8330ac086 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 15 Mar 2012 03:05:24 +0000 Subject: mod_c2s, mod_s2s: Add multiplex support --- plugins/mod_c2s.lua | 3 +++ plugins/s2s/mod_s2s.lua | 3 +++ 2 files changed, 6 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index e3557492..67156f55 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -231,6 +231,9 @@ module:add_item("net-provider", { name = "legacy_ssl"; listener = listener; encryption = "ssl"; + multiplex = { + pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:client%1.*>"; + }; }); diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 194364cd..04b8ae04 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -472,5 +472,8 @@ module:add_item("net-provider", { listener = listener; default_port = 5269; encryption = "starttls"; + multiplex = { + pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:server%1.*>"; + }; }); -- cgit v1.2.3 From 3c2e464d58249bad2f19d3fade6e38f5dccea2be Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 15 Mar 2012 14:47:46 +0100 Subject: mod_posix, mod_bosh, mod_admin_telnet: Use module:set_global() --- plugins/mod_admin_telnet.lua | 2 +- plugins/mod_bosh.lua | 2 +- plugins/mod_posix.lua | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index fd72787e..3799efc0 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -6,7 +6,7 @@ -- COPYING file in the source package for more information. -- -module.host = "*"; +module:set_global(); local _G = _G; diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 9de27b4b..20a6fa1f 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -6,7 +6,7 @@ -- COPYING file in the source package for more information. -- -module.host = "*" -- Global module +module:set_global(); -- Global module local hosts = _G.hosts; local new_xmpp_stream = require "util.xmppstream".new; diff --git a/plugins/mod_posix.lua b/plugins/mod_posix.lua index d229c1b8..b388fb9d 100644 --- a/plugins/mod_posix.lua +++ b/plugins/mod_posix.lua @@ -22,7 +22,7 @@ local stat = lfs.attributes; local prosody = _G.prosody; -module.host = "*"; -- we're a global module +module:set_global(); -- we're a global module local umask = module:get_option("umask") or "027"; pposix.umask(umask); -- cgit v1.2.3 From fdd0bb03e8e6b19b7eb68f33594ecace655dc4bc Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 15 Mar 2012 16:31:10 +0000 Subject: mod_c2s, mod_s2s: Drop default_port and default_mode from listener objects (default_port is deprecated, and default_mode already defaults to *a) --- plugins/mod_c2s.lua | 2 +- plugins/s2s/mod_s2s.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 67156f55..12d10b18 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -31,7 +31,7 @@ local opt_keepalives = module:get_option_boolean("tcp_keepalives", false); local sessions = module:shared("sessions"); local stream_callbacks = { default_ns = "jabber:client", handlestanza = core_process_stanza }; -local listener = { default_port = 5222, default_mode = "*a" }; +local listener = {}; --- Stream events handlers local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index ad7f4862..e1102528 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -317,7 +317,7 @@ function stream_callbacks.handlestanza(session, stanza) end end -local listener = { default_port = 5269, default_mode = "*a" }; +local listener = {}; --- Session methods local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; -- cgit v1.2.3 From 8a4a259bde8e94104a5b9ea59290c29d5f835493 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Thu, 15 Mar 2012 17:37:07 +0100 Subject: mod_c2s: Add missing multiplexed service discovery pattern. --- plugins/mod_c2s.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 12d10b18..743fe3d2 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -225,6 +225,9 @@ module:add_item("net-provider", { listener = listener; default_port = 5222; encryption = "starttls"; + multiplex = { + pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:client%1.*>"; + }; }); module:add_item("net-provider", { -- cgit v1.2.3 From eb824294fe75a98771f3397c6a212d270e76550b Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Mon, 26 Mar 2012 18:23:49 +0200 Subject: mod_s2s: Add "::" as a IPv6 interface (thanks darkrain) --- plugins/s2s/s2sout.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index 6ee1ca83..af55b273 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -331,7 +331,7 @@ module:hook_global("service-added", function (event) end elseif source == "::" then if not socket.local_addresses then - sources[#sources + 1] = new_ip("::", "IPv4"); + sources[#sources + 1] = new_ip("::", "IPv6"); else for _, addr in ipairs(socket.local_addresses("ipv6", true)) do sources[#sources + 1] = new_ip(addr, "IPv6"); -- cgit v1.2.3 From dc93045ece17b36f7b9dfcd96837638913ed45f8 Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Mon, 26 Mar 2012 19:17:09 -0700 Subject: mod_s2s: Queuing a stanza constitutes handling it. --- plugins/s2s/mod_s2s.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index e1102528..b0bd5b40 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -76,6 +76,7 @@ module:hook("route/remote", function (event) if host.sendq then t_insert(host.sendq, {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)}); else host.sendq = { {tostring(stanza), stanza.attr.type ~= "error" and stanza.attr.type ~= "result" and st.reply(stanza)} }; end host.log("debug", "stanza [%s] queued ", stanza.name); + return true; elseif host.type == "local" or host.type == "component" then log("error", "Trying to send a stanza to ourselves??") log("error", "Traceback: %s", get_traceback()); -- cgit v1.2.3 From cc13a475a6010a301fb92f14e3120d41dfc45214 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Fri, 13 Apr 2012 00:39:00 +0200 Subject: mod_adhoc: Always allow at least the "complete" action --- plugins/adhoc/adhoc.lib.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/adhoc/adhoc.lib.lua b/plugins/adhoc/adhoc.lib.lua index 0cb4efe1..57059b3f 100644 --- a/plugins/adhoc/adhoc.lib.lua +++ b/plugins/adhoc/adhoc.lib.lua @@ -25,6 +25,7 @@ function _M.new(name, node, handler, permission) end function _M.handle_cmd(command, origin, stanza) + local cmdtag, actions; local sessionid = stanza.tags[1].attr.sessionid or uuid.generate(); local dataIn = {}; dataIn.to = stanza.attr.to; @@ -58,7 +59,7 @@ function _M.handle_cmd(command, origin, stanza) elseif name == "error" then cmdtag:tag("note", {type="error"}):text(content.message):up(); elseif name =="actions" then - local actions = st.stanza("actions"); + actions = st.stanza("actions"); for _, action in ipairs(content) do if (action == "prev") or (action == "next") or (action == "complete") then actions:tag(action):up(); @@ -67,7 +68,6 @@ function _M.handle_cmd(command, origin, stanza) '" at node "'..command.node..'" provided an invalid action "'..action..'"'); end end - cmdtag:add_child(actions); elseif name == "form" then cmdtag:add_child((content.layout or content):form(content.values)); elseif name == "result" then @@ -76,6 +76,13 @@ function _M.handle_cmd(command, origin, stanza) cmdtag:add_child(content); end end + + if not actions then + actions = st.stanza("actions"); + actions:tag("complete"):up(); + end + cmdtag:add_child(actions); + stanza:add_child(cmdtag); origin.send(stanza); -- cgit v1.2.3 From 2634159a4581c1cc264b20e2094174ae921753d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20K=C3=B6tter?= Date: Fri, 13 Apr 2012 21:23:26 +0200 Subject: muc - implement per channel history limits - allow configuration via channel settings - store the settings for permanent channels - honor muc max_history_messages from the config as upper limit - only broadcast_message with historic = true if history_length is > 0 --- plugins/muc/mod_muc.lua | 8 ++++---- plugins/muc/muc.lib.lua | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 7 deletions(-) (limited to 'plugins') diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 8ef7a5b3..43b8423d 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -69,10 +69,10 @@ for jid in pairs(persistent_rooms) do local node = jid_split(jid); local data = datamanager.load(node, muc_host, "config") or {}; local room = muc_new_room(jid, { - history_length = max_history_messages; + max_history_length = max_history_messages; }); room._data = data._data; - room._data.history_length = max_history_messages; --TODO: Need to allow per-room with a global limit + room._data.max_history_length = max_history_messages; -- Overwrite old max_history_length in data with current settings room._affiliations = data._affiliations; room.route_stanza = room_route_stanza; room.save = room_save; @@ -80,7 +80,7 @@ for jid in pairs(persistent_rooms) do end local host_room = muc_new_room(muc_host, { - history_length = max_history_messages; + max_history_length = max_history_messages; }); host_room.route_stanza = room_route_stanza; host_room.save = room_save; @@ -131,7 +131,7 @@ function stanza_handler(event) (restrict_room_creation == "admin" and is_admin(stanza.attr.from)) or (restrict_room_creation == "local" and select(2, jid_split(stanza.attr.from)) == module.host:gsub("^[^%.]+%.", "")) then room = muc_new_room(bare, { - history_length = max_history_messages; + max_history_length = max_history_messages; }); room.route_stanza = room_route_stanza; room.save = room_save; diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 731f9e37..286ad70c 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -138,7 +138,7 @@ function room_mt:broadcast_message(stanza, historic) stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated) local entry = { stanza = stanza, stamp = stamp }; t_insert(history, entry); - while #history > (self._data.history_length or default_history_length) do t_remove(history, 1) end + while #history > self._data.history_length do t_remove(history, 1) end end end function room_mt:broadcast_except_nick(stanza, nick) @@ -339,6 +339,21 @@ end function room_mt:get_changesubject() return self._data.changesubject; end +function room_mt:get_historylength() + return self._data.history_length +end +function room_mt:set_historylength(length) + if tonumber(length) == nil then + return + end + length = tonumber(length); + log("debug", "max_history_length %s", self._data.max_history_length or "nil"); + if self._data.max_history_length and length > self._data.max_history_length then + length = self._data.max_history_length + end + self._data.history_length = length; +end + function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc local from, to = stanza.attr.from, stanza.attr.to; @@ -608,6 +623,12 @@ function room_mt:get_form_layout() type = 'boolean', label = 'Make Room Members-Only?', value = self:is_members_only() + }, + { + name = 'muc#roomconfig_historylength', + type = 'text-single', + label = 'Maximum Number of History Messages Returned by Room', + value = tostring(self:get_historylength()) } }); end @@ -659,6 +680,11 @@ function room_mt:process_form(origin, stanza) dirty = dirty or (self:get_changesubject() ~= (not changesubject and true or nil)) module:log('debug', 'changesubject=%s', changesubject and "true" or "false") + local historylength = fields['muc#roomconfig_historylength']; + dirty = dirty or (self:get_historylength() ~= (historylength and true or nil)) + module:log('debug', 'historylength=%s', historylength) + + local whois = fields['muc#roomconfig_whois']; if not valid_whois[whois] then origin.send(st.error_reply(stanza, 'cancel', 'bad-request', "Invalid value for 'whois'")); @@ -677,6 +703,7 @@ function room_mt:process_form(origin, stanza) self:set_persistent(persistent); self:set_hidden(not public); self:set_changesubject(changesubject); + self:set_historylength(historylength); if self.save then self:save(true); end origin.send(st.reply(stanza)); @@ -848,7 +875,7 @@ function room_mt:handle_to_room(origin, stanza) -- presence changes and groupcha origin.send(st.error_reply(stanza, "cancel", "forbidden")); end else - self:broadcast_message(stanza, true); + self:broadcast_message(stanza, self:get_historylength() > 0); end stanza.attr.from = from; end @@ -1102,7 +1129,8 @@ function _M.new_room(jid, config) _occupants = {}; _data = { whois = 'moderators'; - history_length = (config and config.history_length); + history_length = (config and config.max_history_length) or default_history_length; + max_history_length = (config and config.max_history_length) or default_history_length; }; _affiliations = {}; }, room_mt); -- cgit v1.2.3 From 8d2bb74a6a3e34e09c0361d5f22e6df66c51c74d Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sat, 21 Apr 2012 17:38:48 +0500 Subject: mod_http: Provide HTTP service. --- plugins/mod_http.lua | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 plugins/mod_http.lua (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua new file mode 100644 index 00000000..4713cf13 --- /dev/null +++ b/plugins/mod_http.lua @@ -0,0 +1,69 @@ +-- Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + +module:set_global(); + +--local sessions = module:shared("sessions"); + +--[[function listener.associate_session(conn, session) + sessions[conn] = session; +end]] + +local handlers; + +function build_handlers() + handlers = {}; + for _, item in ipairs(module:get_host_items("http-handler")) do + local previous = handlers[item.path]; + if not previous and item.path then + handlers[item.path] = item; + end + end +end +function clear_handlers() + handlers = nil; +end +module:handle_items("http-handler", clear_handlers, clear_handlers, false); + +function http_handler(event) + local request, response = event.request, event.response; + + if not handlers then build_handlers(); end + local item = handlers[request.path:match("[^?]*")]; + local handler = item and item.handler; + if handler then + handler(request, response); + return true; + end +end + +local server = require "net.http.server"; +local listener = server.listener; +server.add_handler("*", http_handler); +function module.unload() + server.remove_handler("*", http_handler); +end +--require "net.http.server".listen_on(8080); + +module:add_item("net-provider", { + name = "http"; + listener = listener; + default_port = 5280; + multiplex = { + pattern = "^[A-Z]"; + }; +}); + +module:add_item("net-provider", { + name = "https"; + listener = listener; + encryption = "ssl"; + multiplex = { + pattern = "^[A-Z]"; + }; +}); -- cgit v1.2.3 From 4ce0cecfe4dbd9e1bfe71a16c81478c574070645 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sat, 21 Apr 2012 18:23:44 +0500 Subject: mod_http: Include handlers of non-global modules. --- plugins/mod_http.lua | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 4713cf13..24ef8ab3 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -14,28 +14,44 @@ module:set_global(); sessions[conn] = session; end]] -local handlers; +local NULL = {}; +local handlers = {}; -function build_handlers() - handlers = {}; - for _, item in ipairs(module:get_host_items("http-handler")) do - local previous = handlers[item.path]; - if not previous and item.path then - handlers[item.path] = item; +function build_handlers(host) + if not hosts[host] then return; end + local h = {}; + handlers[host] = h; + + for mod_name, module in pairs(modulemanager.get_modules(host)) do + module = module.module; + if module.items then + for _, item in ipairs(module.items["http-handler"] or NULL) do + local previous = handlers[item.path]; + if not previous and item.path then + h[item.path] = item; + end + end end end + + return h; +end +function clear_handlers(event) + handlers[event.source.host] = nil; end -function clear_handlers() - handlers = nil; +function get_handler(host, path) + local h = handlers[host] or build_handlers(host); + if h then + local item = h[path]; + return item and item.handler; + end end module:handle_items("http-handler", clear_handlers, clear_handlers, false); function http_handler(event) local request, response = event.request, event.response; - if not handlers then build_handlers(); end - local item = handlers[request.path:match("[^?]*")]; - local handler = item and item.handler; + local handler = get_handler(request.headers.host:match("[^:]*"):lower(), request.path:match("[^?]*")); if handler then handler(request, response); return true; -- cgit v1.2.3 From 18497219e053d2bc28798b27d6adc23b039cf3ec Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 21 Apr 2012 20:38:27 +0100 Subject: mod_admin_telnet: get_host_set(): Include '*' in the set if no specific hosts are specified and the module is loaded there --- plugins/mod_admin_telnet.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 3799efc0..e60a2245 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -277,8 +277,12 @@ local function get_hosts_set(hosts, module) return set.new { hosts }; elseif hosts == nil then local mm = require "modulemanager"; - return set.new(array.collect(keys(prosody.hosts))) + local hosts_set = set.new(array.collect(keys(prosody.hosts))) / function (host) return prosody.hosts[host].type == "local" or module and mm.is_loaded(host, module); end; + if module and mm.get_module("*", module) then + hosts_set:add("*"); + end + return hosts_set; end end -- cgit v1.2.3 From 726f3804c3ed5b4d0d3e94b3f4c860c30d76a500 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 21 Apr 2012 20:39:21 +0100 Subject: mod_admin_telnet: module:reload(): If module is loaded on *, reload it there first (ensuring shared module code is reloaded before per-host children of that module) --- plugins/mod_admin_telnet.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index e60a2245..2f2e057b 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -334,11 +334,15 @@ end function def_env.module:reload(name, hosts) local mm = require "modulemanager"; - hosts = get_hosts_set(hosts, name); - + hosts = array.collect(get_hosts_set(hosts, name)):sort(function (a, b) + if a == "*" then return true + elseif b == "*" then return false + else return a < b; end + end); + -- Reload the module for each host local ok, err, count = true, nil, 0; - for host in hosts do + for _, host in ipairs(hosts) do if mm.is_loaded(host, name) then ok, err = mm.reload(host, name); if not ok then -- cgit v1.2.3 From 785fcb0ee39111f31aaa0ebd0d00a797108b6c68 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 21 Apr 2012 20:39:52 +0100 Subject: mod_admin_telnet: module:list(): List global modules (part-fixes #228) --- plugins/mod_admin_telnet.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 2f2e057b..412e1e62 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -363,6 +363,7 @@ end function def_env.module:list(hosts) if hosts == nil then hosts = array.collect(keys(prosody.hosts)); + table.insert(hosts, 1, "*"); end if type(hosts) == "string" then hosts = { hosts }; @@ -373,8 +374,8 @@ function def_env.module:list(hosts) local print = self.session.print; for _, host in ipairs(hosts) do - print(host..":"); - local modules = array.collect(keys(prosody.hosts[host] and prosody.hosts[host].modules or {})):sort(); + print((host == "*" and "Global" or host)..":"); + local modules = array.collect(keys(modulemanager.get_modules(host) or {})):sort(); if #modules == 0 then if prosody.hosts[host] then print(" No modules loaded"); -- cgit v1.2.3 From 89fb66dabbceb336e9e78d8f2e13c39f67f14eec Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 21 Apr 2012 20:52:12 +0100 Subject: mod_admin_telnet: module:load(): Fix 'global-module-already-loaded' errors when successfully loading a global module (fixes #228) --- plugins/mod_admin_telnet.lua | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 412e1e62..cb6302c7 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -292,16 +292,22 @@ function def_env.module:load(name, hosts, config) hosts = get_hosts_set(hosts); -- Load the module for each host - local ok, err, count = true, nil, 0; + local ok, err, count, mod = true, nil, 0, nil; for host in hosts do if (not mm.is_loaded(host, name)) then - ok, err = mm.load(host, name, config); - if not ok then + mod, err = mm.load(host, name, config); + if not mod then ok = false; + if err == "global-module-already-loaded" then + if count > 0 then + ok, err, count = true, nil, 1; + end + break; + end self.session.print(err or "Unknown error loading module"); else count = count + 1; - self.session.print("Loaded for "..host); + self.session.print("Loaded for "..mod.module.host); end end end -- cgit v1.2.3 From 615325cf153e6ebb5f07bb92545bfcedf1c2266b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 21 Apr 2012 21:16:53 +0100 Subject: mod_motd: Send only to resource coming online, not the user's bare JID (fixes #282) --- plugins/mod_motd.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_motd.lua b/plugins/mod_motd.lua index d567288b..646bf8cd 100644 --- a/plugins/mod_motd.lua +++ b/plugins/mod_motd.lua @@ -13,15 +13,15 @@ local motd_jid = module:get_option_string("motd_jid", host); if not motd_text then return; end +local jid_join = require "util.jid".join; local st = require "util.stanza"; motd_text = motd_text:gsub("^%s*(.-)%s*$", "%1"):gsub("\n%s+", "\n"); -- Strip indentation from the config -module:hook("resource-bind", - function (event) +module:hook("resource-bind", function (event) local session = event.session; local motd_stanza = - st.message({ to = session.username..'@'..session.host, from = motd_jid }) + st.message({ to = jid_join(session.username, session.host, session.resource), from = motd_jid }) :tag("body"):text(motd_text); core_route_stanza(hosts[host], motd_stanza); module:log("debug", "MOTD send to user %s@%s", session.username, session.host); -- cgit v1.2.3 From 9d478011222d360bb8d7bdaccd94da0e9e331621 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 21 Apr 2012 22:50:57 +0100 Subject: mod_component: Make a shared module, and move the xmppcomponent_listener into it ('port'ing over to portmanager). Ha ha. --- plugins/mod_component.lua | 333 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 268 insertions(+), 65 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index f7d09930..96d55e40 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -6,95 +6,298 @@ -- COPYING file in the source package for more information. -- -if module:get_host_type() ~= "component" then - error("Don't load mod_component manually, it should be for a component, please see http://prosody.im/doc/components", 0); -end +module:set_global(); local t_concat = table.concat; +local logger = require "util.logger"; local sha1 = require "util.hashes".sha1; local st = require "util.stanza"; +local jid_split = require "util.jid".split; +local new_xmpp_stream = require "util.xmppstream".new; +local uuid_gen = require "util.uuid".generate; + + local log = module._log; -local main_session, send; +local sessions = module:shared("sessions"); -local function on_destroy(session, err) - if main_session == session then - connected = false; - main_session = nil; +function module.add_host(module) + if module:get_host_type() ~= "component" then + error("Don't load mod_component manually, it should be for a component, please see http://prosody.im/doc/components", 0); + end + + local env = module.environment; + env.connected = false; + + local send; + + local function on_destroy(session, err) + env.connected = false; send = nil; session.on_destroy = nil; end + + -- Handle authentication attempts by component + local function handle_component_auth(event) + local session, stanza = event.origin, event.stanza; + + if session.type ~= "component" then return; end + + if (not session.host) or #stanza.tags > 0 then + (session.log or log)("warn", "Invalid component handshake for host: %s", session.host); + session:close("not-authorized"); + return true; + end + + local secret = module:get_option("component_secret"); + if not secret then + (session.log or log)("warn", "Component attempted to identify as %s, but component_secret is not set", session.host); + session:close("not-authorized"); + return true; + end + + local supplied_token = t_concat(stanza); + local calculated_token = sha1(session.streamid..secret, true); + if supplied_token:lower() ~= calculated_token:lower() then + module:log("info", "Component authentication failed for %s", session.host); + session:close{ condition = "not-authorized", text = "Given token does not match calculated token" }; + return true; + end + + if env.connected then + module:log("error", "Second component attempted to connect, denying connection"); + session:close{ condition = "conflict", text = "Component already connected" }; + end + + env.connected = true; + send = session.send; + session.on_destroy = on_destroy; + session.component_validate_from = module:get_option_boolean("validate_from_addresses", true); + module:log("info", "External component successfully authenticated"); + session.send(st.stanza("handshake")); + + return true; + end + module:hook("stanza/jabber:component:accept:handshake", handle_component_auth); + + -- Handle stanzas addressed to this component + local function handle_stanza(event) + local stanza = event.stanza; + if send then + stanza.attr.xmlns = nil; + send(stanza); + else + module:log("warn", "Component not connected, bouncing error for: %s", stanza:top_tag()); + if stanza.attr.type ~= "error" and stanza.attr.type ~= "result" then + event.origin.send(st.error_reply(stanza, "wait", "service-unavailable", "Component unavailable")); + end + end + return true; + end + + module:hook("iq/bare", handle_stanza, -1); + module:hook("message/bare", handle_stanza, -1); + module:hook("presence/bare", handle_stanza, -1); + module:hook("iq/full", handle_stanza, -1); + module:hook("message/full", handle_stanza, -1); + module:hook("presence/full", handle_stanza, -1); + module:hook("iq/host", handle_stanza, -1); + module:hook("message/host", handle_stanza, -1); + module:hook("presence/host", handle_stanza, -1); end -local function handle_stanza(event) - local stanza = event.stanza; - if send then - stanza.attr.xmlns = nil; - send(stanza); - else - log("warn", "Component not connected, bouncing error for: %s", stanza:top_tag()); - if stanza.attr.type ~= "error" and stanza.attr.type ~= "result" then - event.origin.send(st.error_reply(stanza, "wait", "service-unavailable", "Component unavailable")); +--- Network and stream part --- + +local xmlns_component = 'jabber:component:accept'; + +local listener = {}; + +--- Callbacks/data for xmppstream to handle streams for us --- + +local stream_callbacks = { default_ns = xmlns_component }; + +local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; + +function stream_callbacks.error(session, error, data, data2) + if session.destroyed then return; end + module:log("warn", "Error processing component stream: "..tostring(error)); + if error == "no-stream" then + session:close("invalid-namespace"); + elseif error == "parse-error" then + session.log("warn", "External component %s XML parse error: %s", tostring(session.host), tostring(data)); + session:close("not-well-formed"); + elseif error == "stream-error" then + local condition, text = "undefined-condition"; + for child in data:children() do + if child.attr.xmlns == xmlns_xmpp_streams then + if child.name ~= "text" then + condition = child.name; + else + text = child:get_text(); + end + if condition ~= "undefined-condition" and text then + break; + end + end end + text = condition .. (text and (" ("..text..")") or ""); + session.log("info", "Session closed by remote with error: %s", text); + session:close(nil, text); end - return true; end -module:hook("iq/bare", handle_stanza, -1); -module:hook("message/bare", handle_stanza, -1); -module:hook("presence/bare", handle_stanza, -1); -module:hook("iq/full", handle_stanza, -1); -module:hook("message/full", handle_stanza, -1); -module:hook("presence/full", handle_stanza, -1); -module:hook("iq/host", handle_stanza, -1); -module:hook("message/host", handle_stanza, -1); -module:hook("presence/host", handle_stanza, -1); - ---- Handle authentication attempts by components -function handle_component_auth(event) - local session, stanza = event.origin, event.stanza; - - if session.type ~= "component" then return; end - if main_session == session then return; end +function stream_callbacks.streamopened(session, attr) + if not hosts[attr.to].modules.component then + session:close{ condition = "host-unknown", text = tostring(attr.to).." does not match any configured external components" }; + return; + end + session.host = attr.to; + session.streamid = uuid_gen(); + session.notopen = nil; + -- Return stream header + session.send(st.stanza("stream:stream", { xmlns=xmlns_component, + ["xmlns:stream"]='http://etherx.jabber.org/streams', id=session.streamid, from=session.host }):top_tag()); +end - if (not session.host) or #stanza.tags > 0 then - (session.log or log)("warn", "Invalid component handshake for host: %s", session.host); - session:close("not-authorized"); - return true; +function stream_callbacks.streamclosed(session) + session.log("debug", "Received "); + session:close(); +end + +local core_process_stanza = core_process_stanza; + +function stream_callbacks.handlestanza(session, stanza) + -- Namespaces are icky. + if not stanza.attr.xmlns and stanza.name == "handshake" then + stanza.attr.xmlns = xmlns_component; end - - local secret = module:get_option("component_secret"); - if not secret then - (session.log or log)("warn", "Component attempted to identify as %s, but component_secret is not set", session.host); - session:close("not-authorized"); - return true; + if not stanza.attr.xmlns or stanza.attr.xmlns == "jabber:client" then + local from = stanza.attr.from; + if from then + if session.component_validate_from then + local _, domain = jid_split(stanza.attr.from); + if domain ~= session.host then + -- Return error + session.log("warn", "Component sent stanza with missing or invalid 'from' address"); + session:close{ + condition = "invalid-from"; + text = "Component tried to send from address <"..tostring(from) + .."> which is not in domain <"..tostring(session.host)..">"; + }; + return; + end + end + else + stanza.attr.from = session.host; -- COMPAT: Strictly we shouldn't allow this + end + if not stanza.attr.to then + session.log("warn", "Rejecting stanza with no 'to' address"); + session.send(st.error_reply(stanza, "modify", "bad-request", "Components MUST specify a 'to' address on stanzas")); + return; + end end - - local supplied_token = t_concat(stanza); - local calculated_token = sha1(session.streamid..secret, true); - if supplied_token:lower() ~= calculated_token:lower() then - log("info", "Component authentication failed for %s", session.host); - session:close{ condition = "not-authorized", text = "Given token does not match calculated token" }; - return true; + return core_process_stanza(session, stanza); +end + +--- Closing a component connection +local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; +local default_stream_attr = { ["xmlns:stream"] = "http://etherx.jabber.org/streams", xmlns = stream_callbacks.default_ns, version = "1.0", id = "" }; +local function session_close(session, reason) + if session.destroyed then return; end + local log = session.log or log; + if session.conn then + if session.notopen then + session.send(""); + session.send(st.stanza("stream:stream", default_stream_attr):top_tag()); + end + if reason then + if type(reason) == "string" then -- assume stream error + module:log("info", "Disconnecting component, is: %s", reason); + session.send(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' })); + elseif type(reason) == "table" then + if reason.condition then + local stanza = st.stanza("stream:error"):tag(reason.condition, stream_xmlns_attr):up(); + if reason.text then + stanza:tag("text", stream_xmlns_attr):text(reason.text):up(); + end + if reason.extra then + stanza:add_child(reason.extra); + end + module:log("info", "Disconnecting component, is: %s", tostring(stanza)); + session.send(stanza); + elseif reason.name then -- a stanza + module:log("info", "Disconnecting component, is: %s", tostring(reason)); + session.send(reason); + end + end + end + session.send(""); + session.conn:close(); + listener.ondisconnect(session.conn, "stream error"); end +end + +--- Component connlistener + +function listener.onconnect(conn) + local _send = conn.write; + local session = { type = "component", conn = conn, send = function (data) return _send(conn, tostring(data)); end }; + + -- Logging functions -- + local conn_name = "jcp"..tostring(conn):match("[a-f0-9]+$"); + session.log = logger.init(conn_name); + session.close = session_close; - -- If component not already created for this host, create one now - if not main_session then - connected = true; - send = session.send; - main_session = session; - session.on_destroy = on_destroy; - session.component_validate_from = module:get_option_boolean("validate_from_addresses", true); - log("info", "Component successfully authenticated: %s", session.host); - session.send(st.stanza("handshake")); - else -- TODO: Implement stanza distribution - log("error", "Multiple components bound to the same address, first one wins: %s", session.host); - session:close{ condition = "conflict", text = "Component already connected" }; + session.log("info", "Incoming Jabber component connection"); + + local stream = new_xmpp_stream(session, stream_callbacks); + session.stream = stream; + + session.notopen = true; + + function session.reset_stream() + session.notopen = true; + session.stream:reset(); + end + + function session.data(conn, data) + local ok, err = stream:feed(data); + if ok then return; end + module: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"); end - return true; + session.dispatch_stanza = stream_callbacks.handlestanza; + + sessions[conn] = session; +end +function listener.onincoming(conn, data) + local session = sessions[conn]; + session.data(conn, data); +end +function listener.ondisconnect(conn, err) + local session = sessions[conn]; + if session then + (session.log or log)("info", "component disconnected: %s (%s)", tostring(session.host), tostring(err)); + if session.on_destroy then session:on_destroy(err); end + sessions[conn] = nil; + for k in pairs(session) do + if k ~= "log" and k ~= "close" then + session[k] = nil; + end + end + session.destroyed = true; + session = nil; + end end -module:hook("stanza/jabber:component:accept:handshake", handle_component_auth); +module:add_item("net-provider", { + name = "component"; + listener = listener; + default_port = 5347; + multiplex = { + pattern = "^<.*:stream.*%sxmlns%s*=%s*(['\"])jabber:component%1.*>"; + }; +}); -- cgit v1.2.3 From 51ab962e5540b1af96170b7801135f768f4c75cf Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 22 Apr 2012 14:54:36 +0100 Subject: mod_motd: Use presence/bare to catch a client's initial presence and send the MOTD then (fixes #282) --- plugins/mod_motd.lua | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_motd.lua b/plugins/mod_motd.lua index 646bf8cd..39b74de9 100644 --- a/plugins/mod_motd.lua +++ b/plugins/mod_motd.lua @@ -18,12 +18,13 @@ local st = require "util.stanza"; motd_text = motd_text:gsub("^%s*(.-)%s*$", "%1"):gsub("\n%s+", "\n"); -- Strip indentation from the config -module:hook("resource-bind", function (event) - local session = event.session; - local motd_stanza = - st.message({ to = jid_join(session.username, session.host, session.resource), from = motd_jid }) - :tag("body"):text(motd_text); - core_route_stanza(hosts[host], motd_stanza); - module:log("debug", "MOTD send to user %s@%s", session.username, session.host); - -end); +module:hook("presence/bare", function (event) + local session, stanza = event.origin, event.stanza; + if not session.presence and not stanza.attr.type then + local motd_stanza = + st.message({ to = session.full_jid, from = motd_jid }) + :tag("body"):text(motd_text); + core_route_stanza(hosts[host], motd_stanza); + module:log("debug", "MOTD send to user %s", session.full_jid); + end +end, 1); -- cgit v1.2.3 From c1e2674fd4b5dd08abe07e9f3bbf92d34c096c56 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 22 Apr 2012 16:35:26 +0100 Subject: mod_component: Handle component connecting to non-existent host --- plugins/mod_component.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index 96d55e40..5b1eefc7 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -149,7 +149,7 @@ function stream_callbacks.error(session, error, data, data2) end function stream_callbacks.streamopened(session, attr) - if not hosts[attr.to].modules.component then + if not hosts[attr.to] or not hosts[attr.to].modules.component then session:close{ condition = "host-unknown", text = tostring(attr.to).." does not match any configured external components" }; return; end -- cgit v1.2.3 From c51dcd332fe2e74486fffa2cb3e7b9851813b544 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Apr 2012 14:16:59 +0100 Subject: mod_http: Revamp module for new API and config --- plugins/mod_http.lua | 106 ++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 52 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 24ef8ab3..d8e1e10a 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2010 Matthew Wild --- Copyright (C) 2008-2010 Waqas Hussain +-- Copyright (C) 2008-2012 Matthew Wild +-- Copyright (C) 2008-2012 Waqas Hussain -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. @@ -8,67 +8,68 @@ module:set_global(); ---local sessions = module:shared("sessions"); +local parse_url = require "socket.url".parse; +local server = require "net.http.server"; ---[[function listener.associate_session(conn, session) - sessions[conn] = session; -end]] +local function normalize_path(path) + if path:sub(1,1) ~= "/" then path = "/"..path; end + if path:sub(-1,-1) == "/" then path = path:sub(1, -2); end + return path; +end -local NULL = {}; -local handlers = {}; +local function get_http_event(http_module, app_name, key) + local method, path = key:match("^(%S+)%s+(.+)$"); + if not method and key:sub(1,1) == "/" then + method, path = "GET", key; + else + return nil; + end + path = normalize_path(path); + local app_path = normalize_path(http_module:get_option_string(app_name.."_http_path", "/"..app_name)); + return method:upper().." "..http_module.host..app_path..path; +end -function build_handlers(host) - if not hosts[host] then return; end - local h = {}; - handlers[host] = h; - - for mod_name, module in pairs(modulemanager.get_modules(host)) do - module = module.module; - if module.items then - for _, item in ipairs(module.items["http-handler"] or NULL) do - local previous = handlers[item.path]; - if not previous and item.path then - h[item.path] = item; +function module.add_host(module) + local apps = {}; + module.environment.apps = apps; + local function http_app_added(event) + local app_name = event.item.name; + if not app_name then + -- TODO: Link to docs + module:log("error", "HTTP app has no 'name', add one or use module:provides('http', app)"); + return; + end + apps[app_name] = apps[app_name] or {}; + local app_handlers = apps[app_name]; + for key, handler in pairs(event.item.route or {}) do + local event_name = get_http_event(module, app_name, key); + if event_name then + if not app_handlers[event_name] then + app_handlers[event_name] = handler; + server.add_handler(event_name, handler); + else + module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); end + else + module:log("error", "Invalid route in %s: %q", app_name, key); end end end - - return h; -end -function clear_handlers(event) - handlers[event.source.host] = nil; -end -function get_handler(host, path) - local h = handlers[host] or build_handlers(host); - if h then - local item = h[path]; - return item and item.handler; - end -end -module:handle_items("http-handler", clear_handlers, clear_handlers, false); - -function http_handler(event) - local request, response = event.request, event.response; - - local handler = get_handler(request.headers.host:match("[^:]*"):lower(), request.path:match("[^?]*")); - if handler then - handler(request, response); - return true; + + local function http_app_removed(event) + local app_handlers = apps[event.item.name]; + apps[event.item.name] = nil; + for event, handler in pairs(app_handlers) do + server.remove_handler(event, handler); + end end + + module:handle_items("http-provider", http_app_added, http_app_removed); end -local server = require "net.http.server"; -local listener = server.listener; -server.add_handler("*", http_handler); -function module.unload() - server.remove_handler("*", http_handler); -end ---require "net.http.server".listen_on(8080); - module:add_item("net-provider", { name = "http"; - listener = listener; + listener = server.listener; default_port = 5280; multiplex = { pattern = "^[A-Z]"; @@ -77,7 +78,8 @@ module:add_item("net-provider", { module:add_item("net-provider", { name = "https"; - listener = listener; + listener = server.listener; + default_port = 5281; encryption = "ssl"; multiplex = { pattern = "^[A-Z]"; -- cgit v1.2.3 From f28df31a1bdc6546b271c67f2b11185f9fc39583 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Apr 2012 18:23:49 +0100 Subject: mod_http: Support for default_path in apps --- plugins/mod_http.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index d8e1e10a..cd1984c0 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -17,7 +17,7 @@ local function normalize_path(path) return path; end -local function get_http_event(http_module, app_name, key) +local function get_http_event(host, app_path, key) local method, path = key:match("^(%S+)%s+(.+)$"); if not method and key:sub(1,1) == "/" then method, path = "GET", key; @@ -25,15 +25,17 @@ local function get_http_event(http_module, app_name, key) return nil; end path = normalize_path(path); - local app_path = normalize_path(http_module:get_option_string(app_name.."_http_path", "/"..app_name)); - return method:upper().." "..http_module.host..app_path..path; + return method:upper().." "..host..app_path..path; end function module.add_host(module) + local host = module.host; local apps = {}; module.environment.apps = apps; local function http_app_added(event) local app_name = event.item.name; + local default_app_path = event.item.default_path or "/"..app_name; + local app_path = normalize_path(module:get_option_string(app_name.."_http_path", default_app_path)); if not app_name then -- TODO: Link to docs module:log("error", "HTTP app has no 'name', add one or use module:provides('http', app)"); @@ -42,7 +44,7 @@ function module.add_host(module) apps[app_name] = apps[app_name] or {}; local app_handlers = apps[app_name]; for key, handler in pairs(event.item.route or {}) do - local event_name = get_http_event(module, app_name, key); + local event_name = get_http_event(host, app_path, key); if event_name then if not app_handlers[event_name] then app_handlers[event_name] = handler; -- cgit v1.2.3 From a3ceb27baef9490381162c206e89b7d2f67ef3c7 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 23 Apr 2012 21:34:05 +0100 Subject: mod_http: Pass portion of path that matched wildcard to wildcard handlers, as a second parameter --- plugins/mod_http.lua | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index cd1984c0..3dcb14d7 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -46,6 +46,14 @@ function module.add_host(module) for key, handler in pairs(event.item.route or {}) do local event_name = get_http_event(host, app_path, key); if event_name then + if event_name:sub(-2, -1) == "/*" then + local base_path = event_name:match("/(.+)/*$"); + local _handler = handler; + handler = function (event) + local path = event.request.path:sub(#base_path+1); + return _handler(event, path); + end; + end if not app_handlers[event_name] then app_handlers[event_name] = handler; server.add_handler(event_name, handler); -- cgit v1.2.3 From 148a2fd256c8236cf0e2c0b2f98c17c116bc1e6f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Apr 2012 23:36:50 +0200 Subject: mod_httpserver: Adapt to use the new HTTP API --- plugins/mod_httpserver.lua | 67 +++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 39 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_httpserver.lua b/plugins/mod_httpserver.lua index 654aff06..bc9cbcd3 100644 --- a/plugins/mod_httpserver.lua +++ b/plugins/mod_httpserver.lua @@ -6,19 +6,17 @@ -- COPYING file in the source package for more information. -- - -local httpserver = require "net.httpserver"; +module:depends("http"); local lfs = require "lfs"; local open = io.open; -local t_concat = table.concat; local stat = lfs.attributes; -local http_base = config.get("*", "core", "http_path") or "www_files"; +local http_base = module:get_option_string("http_path", "www_files"); -local response_400 = { status = "400 Bad Request", body = "

Bad Request

Sorry, we didn't understand your request :(" }; -local response_403 = { status = "403 Forbidden", body = "

Forbidden

You don't have permission to view the contents of this directory :(" }; -local response_404 = { status = "404 Not Found", body = "

Page Not Found

Sorry, we couldn't find what you were looking for :(" }; +local response_400 = "

Bad Request

Sorry, we didn't understand your request :("; +local response_403 = "

Forbidden

You don't have permission to view the contents of this directory :("; +local response_404 = "

Page Not Found

Sorry, we couldn't find what you were looking for :("; -- TODO: Should we read this from /etc/mime.types if it exists? (startup time...?) local mime_map = { @@ -49,49 +47,40 @@ local function preprocess_path(path) return path; end -function serve_file(path) +function serve_file(request, path) + local response = request.response; + path = path and preprocess_path(path); + if not path then + response.status = 400; + return response:send(response_400); + end local full_path = http_base..path; if stat(full_path, "mode") == "directory" then if stat(full_path.."/index.html", "mode") == "file" then - return serve_file(path.."/index.html"); + return serve_file(request, path.."/index.html"); end - return response_403; + response.status = 403; + return response:send(response_403); end local f, err = open(full_path, "rb"); - if not f then return response_404; end + if not f then + response.status = 404; + return response:send(response_404.."
"..tostring(err)); + end local data = f:read("*a"); f:close(); if not data then - return response_403; + response.status = 403; + return response:send(response_403); end local ext = path:match("%.([^.]*)$"); - local mime = mime_map[ext]; -- Content-Type should be nil when not known - return { - headers = { ["Content-Type"] = mime; }; - body = data; - }; -end - -local function handle_file_request(method, body, request) - local path = preprocess_path(request.url.path); - if not path then return response_400; end - path = path:gsub("^/[^/]+", ""); -- Strip /files/ - return serve_file(path); + response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known + return response:send(data); end -local function handle_default_request(method, body, request) - local path = preprocess_path(request.url.path); - if not path then return response_400; end - return serve_file(path); -end +module:provides("http", { + route = { + ["/*"] = serve_file; + }; +}); -local function setup() - local ports = config.get(module.host, "core", "http_ports") or { 5280 }; - httpserver.set_default_handler(handle_default_request); - httpserver.new_from_config(ports, handle_file_request, { base = "files" }); -end -if prosody.start_time then -- already started - setup(); -else - prosody.events.add_handler("server-started", setup); -end -- cgit v1.2.3 From b12b795d37a1be763c870886faad75abfe7a2228 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Mon, 23 Apr 2012 23:37:43 +0200 Subject: mod_httpserver: Rename to mod_http_files --- plugins/mod_http_files.lua | 86 ++++++++++++++++++++++++++++++++++++++++++++++ plugins/mod_httpserver.lua | 86 ---------------------------------------------- 2 files changed, 86 insertions(+), 86 deletions(-) create mode 100644 plugins/mod_http_files.lua delete mode 100644 plugins/mod_httpserver.lua (limited to 'plugins') diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua new file mode 100644 index 00000000..bc9cbcd3 --- /dev/null +++ b/plugins/mod_http_files.lua @@ -0,0 +1,86 @@ +-- Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + +module:depends("http"); +local lfs = require "lfs"; + +local open = io.open; +local stat = lfs.attributes; + +local http_base = module:get_option_string("http_path", "www_files"); + +local response_400 = "

Bad Request

Sorry, we didn't understand your request :("; +local response_403 = "

Forbidden

You don't have permission to view the contents of this directory :("; +local response_404 = "

Page Not Found

Sorry, we couldn't find what you were looking for :("; + +-- TODO: Should we read this from /etc/mime.types if it exists? (startup time...?) +local mime_map = { + html = "text/html"; + htm = "text/html"; + xml = "text/xml"; + xsl = "text/xml"; + txt = "text/plain; charset=utf-8"; + js = "text/javascript"; + css = "text/css"; +}; + +local function preprocess_path(path) + if path:sub(1,1) ~= "/" then + path = "/"..path; + end + local level = 0; + for component in path:gmatch("([^/]+)/") do + if component == ".." then + level = level - 1; + elseif component ~= "." then + level = level + 1; + end + if level < 0 then + return nil; + end + end + return path; +end + +function serve_file(request, path) + local response = request.response; + path = path and preprocess_path(path); + if not path then + response.status = 400; + return response:send(response_400); + end + local full_path = http_base..path; + if stat(full_path, "mode") == "directory" then + if stat(full_path.."/index.html", "mode") == "file" then + return serve_file(request, path.."/index.html"); + end + response.status = 403; + return response:send(response_403); + end + local f, err = open(full_path, "rb"); + if not f then + response.status = 404; + return response:send(response_404.."
"..tostring(err)); + end + local data = f:read("*a"); + f:close(); + if not data then + response.status = 403; + return response:send(response_403); + end + local ext = path:match("%.([^.]*)$"); + response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known + return response:send(data); +end + +module:provides("http", { + route = { + ["/*"] = serve_file; + }; +}); + diff --git a/plugins/mod_httpserver.lua b/plugins/mod_httpserver.lua deleted file mode 100644 index bc9cbcd3..00000000 --- a/plugins/mod_httpserver.lua +++ /dev/null @@ -1,86 +0,0 @@ --- Prosody IM --- Copyright (C) 2008-2010 Matthew Wild --- Copyright (C) 2008-2010 Waqas Hussain --- --- This project is MIT/X11 licensed. Please see the --- COPYING file in the source package for more information. --- - -module:depends("http"); -local lfs = require "lfs"; - -local open = io.open; -local stat = lfs.attributes; - -local http_base = module:get_option_string("http_path", "www_files"); - -local response_400 = "

Bad Request

Sorry, we didn't understand your request :("; -local response_403 = "

Forbidden

You don't have permission to view the contents of this directory :("; -local response_404 = "

Page Not Found

Sorry, we couldn't find what you were looking for :("; - --- TODO: Should we read this from /etc/mime.types if it exists? (startup time...?) -local mime_map = { - html = "text/html"; - htm = "text/html"; - xml = "text/xml"; - xsl = "text/xml"; - txt = "text/plain; charset=utf-8"; - js = "text/javascript"; - css = "text/css"; -}; - -local function preprocess_path(path) - if path:sub(1,1) ~= "/" then - path = "/"..path; - end - local level = 0; - for component in path:gmatch("([^/]+)/") do - if component == ".." then - level = level - 1; - elseif component ~= "." then - level = level + 1; - end - if level < 0 then - return nil; - end - end - return path; -end - -function serve_file(request, path) - local response = request.response; - path = path and preprocess_path(path); - if not path then - response.status = 400; - return response:send(response_400); - end - local full_path = http_base..path; - if stat(full_path, "mode") == "directory" then - if stat(full_path.."/index.html", "mode") == "file" then - return serve_file(request, path.."/index.html"); - end - response.status = 403; - return response:send(response_403); - end - local f, err = open(full_path, "rb"); - if not f then - response.status = 404; - return response:send(response_404.."
"..tostring(err)); - end - local data = f:read("*a"); - f:close(); - if not data then - response.status = 403; - return response:send(response_403); - end - local ext = path:match("%.([^.]*)$"); - response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known - return response:send(data); -end - -module:provides("http", { - route = { - ["/*"] = serve_file; - }; -}); - -- cgit v1.2.3 From 84e65b574580b2b8101f61c440cb29a85ea31f0f Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 24 Apr 2012 00:17:15 +0200 Subject: mod_http_files: Rename argument to reflect what it actually is --- plugins/mod_http_files.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index bc9cbcd3..437633e7 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -47,8 +47,8 @@ local function preprocess_path(path) return path; end -function serve_file(request, path) - local response = request.response; +function serve_file(event, path) + local response = event.response; path = path and preprocess_path(path); if not path then response.status = 400; @@ -57,7 +57,7 @@ function serve_file(request, path) local full_path = http_base..path; if stat(full_path, "mode") == "directory" then if stat(full_path.."/index.html", "mode") == "file" then - return serve_file(request, path.."/index.html"); + return serve_file(event, path.."/index.html"); end response.status = 403; return response:send(response_403); -- cgit v1.2.3 From 44654c1b36a82889cc5d25cabccad88b6d6b1590 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 24 Apr 2012 15:40:00 +0100 Subject: mod_admin_telnet: Add initial port:list() and port:close() commands --- plugins/mod_admin_telnet.lua | 48 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index cb6302c7..aa65b05b 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -759,6 +759,51 @@ function def_env.host:list() return true, i.." hosts"; end +def_env.port = {}; + +function def_env.port:list() + local print = self.session.print; + local services = portmanager.get_active_services().data; + local ordered_services, n_ports = {}, 0; + for service, interfaces in pairs(services) do + table.insert(ordered_services, service); + end + table.sort(ordered_services); + for _, service in ipairs(ordered_services) do + local ports_list = {}; + for interface, ports in pairs(services[service]) do + for port in pairs(ports) do + table.insert(ports_list, "["..interface.."]:"..port); + end + end + n_ports = n_ports + #ports_list; + print(service..": "..table.concat(ports_list, ", ")); + end + return true, #ordered_services.." services listening on "..n_ports.." ports"; +end + +function def_env.port:close(close_port, close_interface) + close_port = assert(tonumber(close_port), "Invalid port number"); + local n_closed = 0; + local services = portmanager.get_active_services().data; + for service, interfaces in pairs(services) do + for interface, ports in pairs(interfaces) do + if not close_interface or close_interface == interface then + if ports[close_port] then + self.session.print("Closing ["..interface.."]:"..close_port.."..."); + local ok, err = portmanager.close(interface, close_port) + if not ok then + self.session.print("Failed to close "..interface.." "..port..": "..err); + else + n_closed = n_closed + 1; + end + end + end + end + end + return true, "Closed "..n_closed.." ports"; +end + ------------- function printbanner(session) @@ -789,7 +834,8 @@ if option and option ~= "short" and option ~= "full" and option ~= "graphic" the end end -require "core.portmanager".register_service("console", { +module:add_item("net-provider", { + name = "console"; listener = console_listener; default_port = 5582; private = true; -- cgit v1.2.3 From 904d33cce45285aeb581b4b22cea418204ccbbed Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 24 Apr 2012 16:02:30 +0100 Subject: mod_http: Fix specifying method in app route keys --- plugins/mod_http.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 3dcb14d7..6da4db24 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -19,10 +19,11 @@ end local function get_http_event(host, app_path, key) local method, path = key:match("^(%S+)%s+(.+)$"); - if not method and key:sub(1,1) == "/" then + if not method then + if key:sub(1,1) ~= "/" then + return nil; + end method, path = "GET", key; - else - return nil; end path = normalize_path(path); return method:upper().." "..host..app_path..path; -- cgit v1.2.3 From 6f6e05cf7436075c999eee0e5165795311a25406 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Tue, 24 Apr 2012 18:50:22 +0100 Subject: mod_proxy65: Port to portmanager, make a shared module --- plugins/mod_proxy65.lua | 184 ++++++++++++++++++++++-------------------------- 1 file changed, 86 insertions(+), 98 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_proxy65.lua b/plugins/mod_proxy65.lua index d02f3b58..155cb60d 100644 --- a/plugins/mod_proxy65.lua +++ b/plugins/mod_proxy65.lua @@ -6,35 +6,21 @@ -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- ---[[ -* to restart the proxy in the console: e.g. -module:unload("proxy65"); -> server.removeserver(); -module:load("proxy65", ); -]]-- +module:set_global(); -local module = module; -local tostring = tostring; local jid_compare, jid_prep = require "util.jid".compare, require "util.jid".prep; local st = require "util.stanza"; -local connlisteners = require "net.connlisteners"; local sha1 = require "util.hashes".sha1; -local server = require "net.server"; local b64 = require "util.encodings".base64.encode; +local server = require "net.server"; -local host, name = module:get_host(), "SOCKS5 Bytestreams Service"; -local sessions, transfers = {}, {}; - -local proxy_port = module:get_option("proxy65_port") or 5000; -local proxy_interface = module:get_option("proxy65_interface") or "*"; -local proxy_address = module:get_option("proxy65_address") or (proxy_interface ~= "*" and proxy_interface) or host; -local proxy_acl = module:get_option("proxy65_acl"); +local sessions, transfers = module:shared("sessions", "transfers"); local max_buffer_size = 4096; -local connlistener = { default_port = proxy_port, default_interface = proxy_interface, default_mode = "*a" }; +local listener = {}; -function connlistener.onincoming(conn, data) +function listener.onincoming(conn, data) local session = sessions[conn] or {}; local transfer = transfers[session.sha]; @@ -84,7 +70,7 @@ function connlistener.onincoming(conn, data) end end -function connlistener.ondisconnect(conn, err) +function listener.ondisconnect(conn, err) local session = sessions[conn]; if session then if transfers[session.sha] then @@ -101,88 +87,90 @@ function connlistener.ondisconnect(conn, err) end end -module:add_identity("proxy", "bytestreams", name); -module:add_feature("http://jabber.org/protocol/bytestreams"); - -module:hook("iq-get/host/http://jabber.org/protocol/disco#info:query", function(event) - local origin, stanza = event.origin, event.stanza; - origin.send(st.reply(stanza):query("http://jabber.org/protocol/disco#info") - :tag("identity", {category='proxy', type='bytestreams', name=name}):up() - :tag("feature", {var="http://jabber.org/protocol/bytestreams"}) ); - return true; -end, -1); - -module:hook("iq-get/host/http://jabber.org/protocol/disco#items:query", function(event) - local origin, stanza = event.origin, event.stanza; - origin.send(st.reply(stanza):query("http://jabber.org/protocol/disco#items")); - return true; -end, -1); +function module.add_host(module) + local host, name = module:get_host(), module:get_option_string("name", "SOCKS5 Bytestreams Service"); + + local proxy_address = module:get_option("proxy65_address", host); + local proxy_port = module:get_option_number("proxy65_port", next(portmanager.get_active_services():search("proxy65", nil)[1])); + local proxy_acl = module:get_option("proxy65_acl"); -module:hook("iq-get/host/http://jabber.org/protocol/bytestreams:query", function(event) - local origin, stanza = event.origin, event.stanza; + module:add_identity("proxy", "bytestreams", name); + module:add_feature("http://jabber.org/protocol/bytestreams"); + + module:hook("iq-get/host/http://jabber.org/protocol/disco#info:query", function(event) + local origin, stanza = event.origin, event.stanza; + origin.send(st.reply(stanza):query("http://jabber.org/protocol/disco#info") + :tag("identity", {category='proxy', type='bytestreams', name=name}):up() + :tag("feature", {var="http://jabber.org/protocol/bytestreams"}) ); + return true; + end, -1); + + module:hook("iq-get/host/http://jabber.org/protocol/disco#items:query", function(event) + local origin, stanza = event.origin, event.stanza; + origin.send(st.reply(stanza):query("http://jabber.org/protocol/disco#items")); + return true; + end, -1); - -- check ACL - while proxy_acl and #proxy_acl > 0 do -- using 'while' instead of 'if' so we can break out of it - local jid = stanza.attr.from; - for _, acl in ipairs(proxy_acl) do - if jid_compare(jid, acl) then break; end + module:hook("iq-get/host/http://jabber.org/protocol/bytestreams:query", function(event) + local origin, stanza = event.origin, event.stanza; + + -- check ACL + while proxy_acl and #proxy_acl > 0 do -- using 'while' instead of 'if' so we can break out of it + local jid = stanza.attr.from; + for _, acl in ipairs(proxy_acl) do + if jid_compare(jid, acl) then break; end + end + module:log("warn", "Denying use of proxy for %s", tostring(stanza.attr.from)); + origin.send(st.error_reply(stanza, "auth", "forbidden")); + return true; end - module:log("warn", "Denying use of proxy for %s", tostring(stanza.attr.from)); - origin.send(st.error_reply(stanza, "auth", "forbidden")); + + local sid = stanza.tags[1].attr.sid; + origin.send(st.reply(stanza):tag("query", {xmlns="http://jabber.org/protocol/bytestreams", sid=sid}) + :tag("streamhost", {jid=host, host=proxy_address, port=proxy_port})); return true; - end - - local sid = stanza.tags[1].attr.sid; - origin.send(st.reply(stanza):tag("query", {xmlns="http://jabber.org/protocol/bytestreams", sid=sid}) - :tag("streamhost", {jid=host, host=proxy_address, port=proxy_port})); - return true; -end); - -module.unload = function() - connlisteners.deregister(module.host .. ':proxy65'); -end - -module:hook("iq-set/host/http://jabber.org/protocol/bytestreams:query", function(event) - local origin, stanza = event.origin, event.stanza; - - local query = stanza.tags[1]; - local sid = query.attr.sid; - local from = stanza.attr.from; - local to = query:get_child_text("activate"); - local prepped_to = jid_prep(to); - - local info = "sid: "..tostring(sid)..", initiator: "..tostring(from)..", target: "..tostring(prepped_to or to); - if prepped_to and sid then - local sha = sha1(sid .. from .. prepped_to, true); - if not transfers[sha] then - module:log("debug", "Activation request has unknown session id; activation failed (%s)", info); - origin.send(st.error_reply(stanza, "modify", "item-not-found")); - elseif not transfers[sha].initiator then - module:log("debug", "The sender was not connected to the proxy; activation failed (%s)", info); - origin.send(st.error_reply(stanza, "cancel", "not-allowed", "The sender (you) is not connected to the proxy")); - --elseif not transfers[sha].target then -- can't happen, as target is set when a transfer object is created - -- module:log("debug", "The recipient was not connected to the proxy; activation failed (%s)", info); - -- origin.send(st.error_reply(stanza, "cancel", "not-allowed", "The recipient is not connected to the proxy")); - else -- if transfers[sha].initiator ~= nil and transfers[sha].target ~= nil then - module:log("debug", "Transfer activated (%s)", info); - transfers[sha].activated = true; - transfers[sha].target:resume(); - transfers[sha].initiator:resume(); - origin.send(st.reply(stanza)); + end); + + module:hook("iq-set/host/http://jabber.org/protocol/bytestreams:query", function(event) + local origin, stanza = event.origin, event.stanza; + + local query = stanza.tags[1]; + local sid = query.attr.sid; + local from = stanza.attr.from; + local to = query:get_child_text("activate"); + local prepped_to = jid_prep(to); + + local info = "sid: "..tostring(sid)..", initiator: "..tostring(from)..", target: "..tostring(prepped_to or to); + if prepped_to and sid then + local sha = sha1(sid .. from .. prepped_to, true); + if not transfers[sha] then + module:log("debug", "Activation request has unknown session id; activation failed (%s)", info); + origin.send(st.error_reply(stanza, "modify", "item-not-found")); + elseif not transfers[sha].initiator then + module:log("debug", "The sender was not connected to the proxy; activation failed (%s)", info); + origin.send(st.error_reply(stanza, "cancel", "not-allowed", "The sender (you) is not connected to the proxy")); + --elseif not transfers[sha].target then -- can't happen, as target is set when a transfer object is created + -- module:log("debug", "The recipient was not connected to the proxy; activation failed (%s)", info); + -- origin.send(st.error_reply(stanza, "cancel", "not-allowed", "The recipient is not connected to the proxy")); + else -- if transfers[sha].initiator ~= nil and transfers[sha].target ~= nil then + module:log("debug", "Transfer activated (%s)", info); + transfers[sha].activated = true; + transfers[sha].target:resume(); + transfers[sha].initiator:resume(); + origin.send(st.reply(stanza)); + end + elseif to and sid then + module:log("debug", "Malformed activation jid; activation failed (%s)", info); + origin.send(st.error_reply(stanza, "modify", "jid-malformed")); + else + module:log("debug", "Bad request; activation failed (%s)", info); + origin.send(st.error_reply(stanza, "modify", "bad-request")); end - elseif to and sid then - module:log("debug", "Malformed activation jid; activation failed (%s)", info); - origin.send(st.error_reply(stanza, "modify", "jid-malformed")); - else - module:log("debug", "Bad request; activation failed (%s)", info); - origin.send(st.error_reply(stanza, "modify", "bad-request")); - end - return true; -end); - -if not connlisteners.register(module.host .. ':proxy65', connlistener) then - module:log("error", "mod_proxy65: Could not establish a connection listener. Check your configuration please."); - module:log("error", "Possibly two proxy65 components are configured to share the same port."); + return true; + end); end -connlisteners.start(module.host .. ':proxy65'); +module:provides("net", { + default_port = 5000; + listener = listener; +}); -- cgit v1.2.3 From abcb8d02e513d01c2ec1039cd1a623e3e23bac80 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Wed, 25 Apr 2012 07:55:13 +0500 Subject: mod_proxy65: Add multiplex pattern. --- plugins/mod_proxy65.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_proxy65.lua b/plugins/mod_proxy65.lua index 155cb60d..a0dd7233 100644 --- a/plugins/mod_proxy65.lua +++ b/plugins/mod_proxy65.lua @@ -173,4 +173,7 @@ end module:provides("net", { default_port = 5000; listener = listener; + multiplex = { + pattern = "^\5"; + }; }); -- cgit v1.2.3 From 7510803cceed24bb3a14c90f7c6065168c4aaada Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 25 Apr 2012 19:57:46 +0100 Subject: mod_bosh: Optimisation, store reply_before value as waiting_requests value (saves a lookup) --- plugins/mod_bosh.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index c5576004..599e4522 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -165,8 +165,7 @@ function handle_request(method, body, request) -- We're keeping this request open, to respond later log("debug", "Have nothing to say, so leaving request unanswered for now"); if session.bosh_wait then - request.reply_before = os_time() + session.bosh_wait; - waiting_requests[request] = true; + waiting_requests[request] = os_time() + session.bosh_wait; end end @@ -399,8 +398,8 @@ function on_timer() -- log("debug", "Checking for requests soon to timeout..."); -- Identify requests timing out within the next few seconds local now = os_time() + 3; - for request in pairs(waiting_requests) do - if request.reply_before <= now then + for request, reply_before in pairs(waiting_requests) do + if reply_before <= now then log("debug", "%s was soon to timeout, sending empty response", request.id); -- Send empty response to let the -- client know we're still here -- cgit v1.2.3 From 7a7b03129d175b7742ce432b834c6430ba908b5b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 25 Apr 2012 23:10:32 +0100 Subject: mod_bosh: Large commit to update to mod_http/net.http.server APIs. Becomes a shared module. --- plugins/mod_bosh.lua | 168 +++++++++++++++++++++++++-------------------------- 1 file changed, 83 insertions(+), 85 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 599e4522..4432bd03 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -79,11 +79,12 @@ local inactive_sessions = {}; -- Sessions which have no open requests -- Used to respond to idle sessions (those with waiting requests) local waiting_requests = {}; function on_destroy_request(request) + log("debug", "Request destroyed: %s", tostring(request)); waiting_requests[request] = nil; - local session = sessions[request.sid]; + local session = sessions[request.context.sid]; if session then local requests = session.requests; - for i,r in ipairs(requests) do + for i, r in ipairs(requests) do if r == request then t_remove(requests, i); break; @@ -99,39 +100,39 @@ function on_destroy_request(request) end end -function handle_request(method, body, request) - if (not body) or request.method ~= "POST" then - if request.method == "OPTIONS" then - local headers = {}; - for k,v in pairs(default_headers) do headers[k] = v; end - headers["Content-Type"] = nil; - return { headers = headers, body = "" }; - else - return "You really don't look like a BOSH client to me... what do you want?"; - end - end - if not method then - log("debug", "Request %s suffered error %s", tostring(request.id), body); - return; - end - --log("debug", "Handling new request %s: %s\n----------", request.id, tostring(body)); - request.notopen = true; - request.log = log; - request.on_destroy = on_destroy_request; - - local stream = new_xmpp_stream(request, stream_callbacks); +local function handle_GET(request) + return "You really don't look like a BOSH client to me... what do you want?"; +end + +function handle_OPTIONS(request) + local headers = {}; + for k,v in pairs(default_headers) do headers[k] = v; end + headers["Content-Type"] = nil; + return { headers = headers, body = "" }; +end + +function handle_POST(event) + log("debug", "Handling new request %s: %s\n----------", tostring(event.request), tostring(event.request.body)); + + local request, response = event.request, event.response; + response.on_destroy = on_destroy_request; + local body = request.body; + + local context = { request = request, response = response, notopen = true }; + local stream = new_xmpp_stream(context, stream_callbacks); + response.context = context; -- stream:feed() calls the stream_callbacks, so all stanzas in -- the body are processed in this next line before it returns. - local ok, err = stream:feed(body); - if not ok then - log("error", "Failed to parse BOSH payload: %s", err); - end + -- In particular, the streamopened() stream callback is where + -- much of the session logic happens, because it's where we first + -- get to see the 'sid' of this request. + stream:feed(body); -- Stanzas (if any) in the request have now been processed, and -- we take care of the high-level BOSH logic here, including -- giving a response or putting the request "on hold". - local session = sessions[request.sid]; + local session = sessions[context.sid]; if session then -- Session was marked as inactive, since we have -- a request open now, unmark it @@ -140,8 +141,11 @@ function handle_request(method, body, request) end local r = session.requests; - log("debug", "Session %s has %d out of %d requests open", request.sid, #r, session.bosh_hold); - log("debug", "and there are %d things in the send_buffer", #session.send_buffer); + log("debug", "Session %s has %d out of %d requests open", context.sid, #r, session.bosh_hold); + log("debug", "and there are %d things in the send_buffer:", #session.send_buffer); + for i, thing in ipairs(session.send_buffer) do + log("debug", " %s", tostring(thing)); + end if #r > session.bosh_hold then -- We are holding too many requests, send what's in the buffer, log("debug", "We are holding too many requests, so..."); @@ -161,11 +165,11 @@ function handle_request(method, body, request) session.send(resp); end - if not request.destroyed then + if not response.finished then -- We're keeping this request open, to respond later log("debug", "Have nothing to say, so leaving request unanswered for now"); if session.bosh_wait then - waiting_requests[request] = os_time() + session.bosh_wait; + waiting_requests[response] = os_time() + session.bosh_wait; end end @@ -213,11 +217,10 @@ local function bosh_close_stream(session, reason) log("info", "Disconnecting client, is: %s", tostring(close_reply)); end - local session_close_response = { headers = default_headers, body = tostring(close_reply) }; - + local response_body = tostring(close_reply); for _, held_request in ipairs(session.requests) do - held_request:send(session_close_response); - held_request:destroy(); + held_request.headers = default_headers; + held_request:send(response_body); end sessions[session.sid] = nil; inactive_sessions[session] = nil; @@ -225,12 +228,13 @@ local function bosh_close_stream(session, reason) end -- Handle the tag in the request payload. -function stream_callbacks.streamopened(request, attr) +function stream_callbacks.streamopened(context, attr) + local request, response = context.request, context.response; local sid = attr.sid; log("debug", "BOSH body open (sid: %s)", sid or ""); if not sid then -- New session request - request.notopen = nil; -- Signals that we accept this opening tag + context.notopen = nil; -- Signals that we accept this opening tag -- TODO: Sanity checks here (rid, to, known host, etc.) if not hosts[attr.to] then @@ -238,7 +242,7 @@ function stream_callbacks.streamopened(request, attr) log("debug", "BOSH client tried to connect to unknown host: %s", tostring(attr.to)); local close_reply = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", ["xmlns:stream"] = xmlns_streams, condition = "host-unknown" }); - request:send(tostring(close_reply)); + response:send(tostring(close_reply)); return; end @@ -258,7 +262,6 @@ function stream_callbacks.streamopened(request, attr) session.log("debug", "BOSH session created for request from %s", session.ip); log("info", "New BOSH session, assigned it sid '%s'", sid); local r, send_buffer = session.requests, session.send_buffer; - local response = { headers = default_headers } function session.send(s) -- We need to ensure that outgoing stanzas have the jabber:client xmlns if s.attr and not s.attr.xmlns then @@ -269,25 +272,14 @@ function stream_callbacks.streamopened(request, attr) local oldest_request = r[1]; if oldest_request and (not(auto_cork) or waiting_requests[oldest_request]) then log("debug", "We have an open request, so sending on that"); - response.body = t_concat({ + oldest_request.headers = default_headers; + oldest_request:send(t_concat({ "", tostring(s), "" - }); - oldest_request:send(response); - --log("debug", "Sent"); - if oldest_request.stayopen then - if #r>1 then - -- Move front request to back - t_insert(r, oldest_request); - t_remove(r, 1); - end - else - log("debug", "Destroying the request now..."); - oldest_request:destroy(); - end + })); elseif s ~= "" then log("debug", "Saved to send buffer because there are %d open requests", #r); -- Hmm, no requests are open :( @@ -303,7 +295,7 @@ function stream_callbacks.streamopened(request, attr) hosts[session.host].events.fire_event("stream-features", { origin = session, features = features }); fire_event("stream-features", session, features); --xmpp:version='1.0' xmlns:xmpp='urn:xmpp:xbosh' - local response = st.stanza("body", { xmlns = xmlns_bosh, + local body = st.stanza("body", { xmlns = xmlns_bosh, wait = attr.wait, inactivity = tostring(BOSH_DEFAULT_INACTIVITY), polling = tostring(BOSH_DEFAULT_POLLING), @@ -315,7 +307,8 @@ function stream_callbacks.streamopened(request, attr) ["xmlns:xmpp"] = "urn:xmpp:xbosh", ["xmlns:stream"] = "http://etherx.jabber.org/streams" }):add_child(features); - request:send{ headers = default_headers, body = tostring(response) }; + response.headers = default_headers; + response:send(tostring(body)); request.sid = sid; return; @@ -325,8 +318,9 @@ function stream_callbacks.streamopened(request, attr) if not session then -- Unknown sid log("info", "Client tried to use sid '%s' which we don't know about", sid); - request:send{ headers = default_headers, body = tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" })) }; - request.notopen = nil; + response.headers = default_headers; + response:send(tostring(st.stanza("body", { xmlns = xmlns_bosh, type = "terminate", condition = "item-not-found" }))); + context.notopen = nil; return; end @@ -338,10 +332,10 @@ function stream_callbacks.streamopened(request, attr) elseif diff <= 0 then -- Repeated, ignore session.log("debug", "rid repeated (on request %s), ignoring: %s (diff %d)", request.id, session.rid, diff); - request.notopen = nil; - request.ignore = true; - request.sid = sid; - t_insert(session.requests, request); + context.notopen = nil; + context.ignore = true; + context.sid = sid; + t_insert(session.requests, response); return; end session.rid = rid; @@ -353,9 +347,9 @@ function stream_callbacks.streamopened(request, attr) session.bosh_terminate = true; end - request.notopen = nil; -- Signals that we accept this opening tag - t_insert(session.requests, request); - request.sid = sid; + context.notopen = nil; -- Signals that we accept this opening tag + t_insert(session.requests, response); + context.sid = sid; if session.notopen then local features = st.stanza("stream:features"); @@ -366,10 +360,10 @@ function stream_callbacks.streamopened(request, attr) end end -function stream_callbacks.handlestanza(request, stanza) - if request.ignore then return; end +function stream_callbacks.handlestanza(context, stanza) + if context.ignore then return; end log("debug", "BOSH stanza received: %s\n", stanza:top_tag()); - local session = sessions[request.sid]; + local session = sessions[context.sid]; if session then if stanza.attr.xmlns == xmlns_bosh then stanza.attr.xmlns = nil; @@ -378,14 +372,17 @@ function stream_callbacks.handlestanza(request, stanza) end end -function stream_callbacks.error(request, error) +function stream_callbacks.error(context, error) log("debug", "Error parsing BOSH request payload; %s", error); - if not request.sid then - request:send({ headers = default_headers, status = "400 Bad Request" }); + if not context.sid then + local response = context.response; + response.headers = default_headers; + response.status_code = 400; + request:send(); return; end - local session = sessions[request.sid]; + local session = sessions[context.sid]; if error == "stream-error" then -- Remote stream error, we close normally session:close(); else @@ -400,11 +397,11 @@ function on_timer() local now = os_time() + 3; for request, reply_before in pairs(waiting_requests) do if reply_before <= now then - log("debug", "%s was soon to timeout, sending empty response", request.id); + log("debug", "%s was soon to timeout (at %d, now %d), sending empty response", tostring(request), reply_before, now); -- Send empty response to let the -- client know we're still here if request.conn then - sessions[request.sid].send(""); + sessions[request.context.sid].send(""); end end end @@ -428,15 +425,16 @@ function on_timer() end return 1; end - - -local function setup() - local ports = module:get_option_array("bosh_ports") or { 5280 }; - httpserver.new_from_config(ports, handle_request, { base = "http-bind" }); - timer.add_task(1, on_timer); -end -if prosody.start_time then -- already started - setup(); -else - prosody.events.add_handler("server-started", setup); +module:add_timer(1, on_timer); + +function module.add_host(module) + module:depends("http"); + module:provides("http", { + default_path = "/http-bind"; + route = { + ["GET /"] = handle_GET; + ["OPTIONS /"] = handle_OPTIONS; + ["POST /"] = handle_POST; + }; + }); end -- cgit v1.2.3 From 355eb83a4a8956be8cf6ffacb94c73d67ed54336 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 26 Apr 2012 05:40:04 +0100 Subject: mod_http: Use module:hook/unhook_event_object() so that handlers get unregistered if mod_http is unloaded --- plugins/mod_http.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 6da4db24..2ba69cb5 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -57,7 +57,7 @@ function module.add_host(module) end if not app_handlers[event_name] then app_handlers[event_name] = handler; - server.add_handler(event_name, handler); + module:hook_object_event(server, event_name, handler); else module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); end @@ -71,7 +71,7 @@ function module.add_host(module) local app_handlers = apps[event.item.name]; apps[event.item.name] = nil; for event, handler in pairs(app_handlers) do - server.remove_handler(event, handler); + module:unhook_object_event(server, event, handler); end end -- cgit v1.2.3 From fbbc658469cf539bc1118bdf1e9b1c86fcba0497 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 26 Apr 2012 05:56:24 +0100 Subject: mod_bosh: Update informational message on GET --- plugins/mod_bosh.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 4432bd03..13cea911 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -101,7 +101,10 @@ function on_destroy_request(request) end local function handle_GET(request) - return "You really don't look like a BOSH client to me... what do you want?"; + return [[ +

It works! Now point your BOSH client to this URL to connect to Prosody.

+

For more information see Prosody: Setting up BOSH.

+]]; end function handle_OPTIONS(request) -- cgit v1.2.3 From 23e05cc038ce41fb538d3e9c2d096f1cf914af51 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 26 Apr 2012 06:10:14 +0100 Subject: mod_http_files: Return numeric error codes instead of custom error responses --- plugins/mod_http_files.lua | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 437633e7..c5859283 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -14,10 +14,6 @@ local stat = lfs.attributes; local http_base = module:get_option_string("http_path", "www_files"); -local response_400 = "

Bad Request

Sorry, we didn't understand your request :("; -local response_403 = "

Forbidden

You don't have permission to view the contents of this directory :("; -local response_404 = "

Page Not Found

Sorry, we couldn't find what you were looking for :("; - -- TODO: Should we read this from /etc/mime.types if it exists? (startup time...?) local mime_map = { html = "text/html"; @@ -51,27 +47,23 @@ function serve_file(event, path) local response = event.response; path = path and preprocess_path(path); if not path then - response.status = 400; - return response:send(response_400); + return 400; end local full_path = http_base..path; if stat(full_path, "mode") == "directory" then if stat(full_path.."/index.html", "mode") == "file" then return serve_file(event, path.."/index.html"); end - response.status = 403; - return response:send(response_403); + return 403; end local f, err = open(full_path, "rb"); if not f then - response.status = 404; - return response:send(response_404.."
"..tostring(err)); + return 404; end local data = f:read("*a"); f:close(); if not data then - response.status = 403; - return response:send(response_403); + return 403; end local ext = path:match("%.([^.]*)$"); response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known -- cgit v1.2.3 From 19f0eb98bf99be6d07504a5436e935d4c6b1d189 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 26 Apr 2012 06:30:29 +0100 Subject: mod_http_files: Log 404 failure reason --- plugins/mod_http_files.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index c5859283..9d5aa252 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -58,6 +58,7 @@ function serve_file(event, path) end local f, err = open(full_path, "rb"); if not f then + module:log("warn", "Failed to open file: %s", err); return 404; end local data = f:read("*a"); -- cgit v1.2.3 From 6c6566bacef8de2a8d98f2f9640c7a713f2371d2 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 26 Apr 2012 06:41:11 +0100 Subject: mod_http: Switch to single option for specifying HTTP app bases, http_paths. Keys are app/module names, values are base paths. --- plugins/mod_http.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 2ba69cb5..8b8d9c47 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -29,6 +29,12 @@ local function get_http_event(host, app_path, key) return method:upper().." "..host..app_path..path; end +local function get_base_path(host_module, app_name, default_app_path) + return host_module:get_option("http_paths", {})[app_name] -- Host + or module:get_option("http_paths", {})[app_name] -- Global + or default_app_path; -- Default +end + function module.add_host(module) local host = module.host; local apps = {}; @@ -36,7 +42,7 @@ function module.add_host(module) local function http_app_added(event) local app_name = event.item.name; local default_app_path = event.item.default_path or "/"..app_name; - local app_path = normalize_path(module:get_option_string(app_name.."_http_path", default_app_path)); + local app_path = normalize_path(get_base_path(module, app_name, default_app_path)); if not app_name then -- TODO: Link to docs module:log("error", "HTTP app has no 'name', add one or use module:provides('http', app)"); -- cgit v1.2.3 From 0c686d4e7ae8fff6e71af4f5099c12720b352372 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 26 Apr 2012 06:42:02 +0100 Subject: mod_http_files: Change option name from http_path to http_files_dir --- plugins/mod_http_files.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 9d5aa252..932d2547 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -12,7 +12,7 @@ local lfs = require "lfs"; local open = io.open; local stat = lfs.attributes; -local http_base = module:get_option_string("http_path", "www_files"); +local http_base = module:get_option_string("http_files_dir", module:get_option_string("http_path", "www_files")); -- TODO: Should we read this from /etc/mime.types if it exists? (startup time...?) local mime_map = { -- cgit v1.2.3 From 84cfab103067b8cebb98b049250eff74bf353eaf Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 26 Apr 2012 15:16:29 +0100 Subject: mod_http_errors: Module to handle HTTP errors with a HTML page --- plugins/mod_http_errors.lua | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 plugins/mod_http_errors.lua (limited to 'plugins') diff --git a/plugins/mod_http_errors.lua b/plugins/mod_http_errors.lua new file mode 100644 index 00000000..820bcc2f --- /dev/null +++ b/plugins/mod_http_errors.lua @@ -0,0 +1,75 @@ +module:set_global(); +module:depends("http"); + +local server = require "net.http.server"; +local codes = require "net.http.codes"; +local termcolours = require "util.termcolours"; + +local show_private = module:get_option_boolean("http_errors_detailed", false); + +local default_messages = { + [400] = { "What kind of request do you call that??" }; + [403] = { "You're not allowed to do that." }; + [404] = { "Whatever you were looking for is not here. %"; + "Where did you put it?", "It's behind you.", "Keep looking." }; + [500] = { "% Check your error log for more info."; + "Gremlins.", "It broke.", "Don't look at me." }; +}; + +local messages = setmetatable(module:get_option("http_errors_messages", {}), { __index = default_messages }); + +local html = [[ + + + + + + + +

$title

+

$message

+

$extra

+ +]]; +html = html:gsub("%s%s+", ""); + +local entities = { + ["<"] = "<", [">"] = ">", ["&"] = "&", + ["'"] = "'", ["\""] = """, ["\n"] = "
", +}; + +local function tohtml(plain) + return (plain:gsub("[<>&'\"\n]", entities)); + +end + +local function get_page(code, extra) + local message = messages[code]; + if message then + return (html:gsub("$(%a+)", { + title = rawget(codes, code) or ("Code "..tostring(code)); + message = message[1]:gsub("%%", function () + return message[math.random(2, math.max(#message,2))]; + end); + extra = tohtml(extra or ""); + })); + end +end + +module:hook_object_event(server, "http-error", function (event) + return get_page(event.code, (show_private and event.private_message) or event.message); +end); -- cgit v1.2.3 From 7c5c2aea2ca88a0112c51c5eaf74209271d780c9 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 26 Apr 2012 16:48:16 +0100 Subject: mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit --- plugins/mod_http_files.lua | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 932d2547..9be735b7 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -25,31 +25,9 @@ local mime_map = { css = "text/css"; }; -local function preprocess_path(path) - if path:sub(1,1) ~= "/" then - path = "/"..path; - end - local level = 0; - for component in path:gmatch("([^/]+)/") do - if component == ".." then - level = level - 1; - elseif component ~= "." then - level = level + 1; - end - if level < 0 then - return nil; - end - end - return path; -end - function serve_file(event, path) local response = event.response; - path = path and preprocess_path(path); - if not path then - return 400; - end - local full_path = http_base..path; + local full_path = http_base.."/"..path; if stat(full_path, "mode") == "directory" then if stat(full_path.."/index.html", "mode") == "file" then return serve_file(event, path.."/index.html"); -- cgit v1.2.3 From fad0359e7520355813c6775c788c2ac952db434f Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 26 Apr 2012 16:53:32 +0100 Subject: mod_http: Remove unused import of url.parse --- plugins/mod_http.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 8b8d9c47..7b962457 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -8,7 +8,6 @@ module:set_global(); -local parse_url = require "socket.url".parse; local server = require "net.http.server"; local function normalize_path(path) -- cgit v1.2.3 From d4e44895770446226c22513ac9bf1d7b12396f47 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 27 Apr 2012 18:36:27 +0100 Subject: mod_http: Link to docs on routes in error message --- plugins/mod_http.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 7b962457..93d58439 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -67,7 +67,7 @@ function module.add_host(module) module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name); end else - module:log("error", "Invalid route in %s: %q", app_name, key); + module:log("error", "Invalid route in %s, %q. See http://prosody.im/doc/developers/http#routes", app_name, key); end end end -- cgit v1.2.3 From c06a35c238fc6e27e3b034a4cfe5c26f783692fb Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 27 Apr 2012 18:37:40 +0100 Subject: mod_http: Routes now require a method to be specified, but the path has become optional (defaults to the base path with no trailing '/' --- plugins/mod_http.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 93d58439..4c6c1299 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -18,13 +18,12 @@ end local function get_http_event(host, app_path, key) local method, path = key:match("^(%S+)%s+(.+)$"); - if not method then - if key:sub(1,1) ~= "/" then - return nil; - end - method, path = "GET", key; + if not method then -- No path specified, default to "" (base path) + method, path = key, ""; + end + if method:sub(1,1) == "/" then + return nil; end - path = normalize_path(path); return method:upper().." "..host..app_path..path; end -- cgit v1.2.3 From e9de5a1a10930ab3a6e722221affdd0fe18f9121 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 27 Apr 2012 18:40:44 +0100 Subject: mod_http_files: Specify method in HTTP route --- plugins/mod_http_files.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_http_files.lua b/plugins/mod_http_files.lua index 9be735b7..dc58ff5d 100644 --- a/plugins/mod_http_files.lua +++ b/plugins/mod_http_files.lua @@ -51,7 +51,7 @@ end module:provides("http", { route = { - ["/*"] = serve_file; + ["GET /*"] = serve_file; }; }); -- cgit v1.2.3 From af906903993b13bbdd304015ef8fb07355c0b984 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 27 Apr 2012 19:02:36 +0100 Subject: mod_http: Allow a route value to be static data rather than a handler function --- plugins/mod_http.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index 4c6c1299..ef3f0271 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -51,7 +51,10 @@ function module.add_host(module) for key, handler in pairs(event.item.route or {}) do local event_name = get_http_event(host, app_path, key); if event_name then - if event_name:sub(-2, -1) == "/*" then + if type(handler) ~= "function" then + local data = handler; + handler = function () return data; end + elseif event_name:sub(-2, -1) == "/*" then local base_path = event_name:match("/(.+)/*$"); local _handler = handler; handler = function (event) -- cgit v1.2.3 From ff9ffc23510278c9c7e7d04789a0d4e529211484 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 27 Apr 2012 19:05:03 +0100 Subject: mod_bosh: Add routes without trailing-'/', so that both /http-bind and /http-bind/ work again --- plugins/mod_bosh.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 13cea911..84adb369 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -435,8 +435,11 @@ function module.add_host(module) module:provides("http", { default_path = "/http-bind"; route = { + ["GET"] = handle_GET; ["GET /"] = handle_GET; + ["OPTIONS"] = handle_OPTIONS; ["OPTIONS /"] = handle_OPTIONS; + ["POST"] = handle_POST; ["POST /"] = handle_POST; }; }); -- cgit v1.2.3 From 5542ce387f2a180278d17193e159fdd6d6ac8238 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 27 Apr 2012 22:18:20 +0100 Subject: mod_proxy65: Fix traceback when proxy65 service fails to bind a port --- plugins/mod_proxy65.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_proxy65.lua b/plugins/mod_proxy65.lua index a0dd7233..b2f6f703 100644 --- a/plugins/mod_proxy65.lua +++ b/plugins/mod_proxy65.lua @@ -91,7 +91,7 @@ function module.add_host(module) local host, name = module:get_host(), module:get_option_string("name", "SOCKS5 Bytestreams Service"); local proxy_address = module:get_option("proxy65_address", host); - local proxy_port = module:get_option_number("proxy65_port", next(portmanager.get_active_services():search("proxy65", nil)[1])); + local proxy_port = module:get_option_number("proxy65_port", next(portmanager.get_active_services():search("proxy65", nil)[1] or {})); local proxy_acl = module:get_option("proxy65_acl"); module:add_identity("proxy", "bytestreams", name); -- cgit v1.2.3 From 9857260297140238992608256dcd0104a7170a17 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 27 Apr 2012 22:37:24 +0100 Subject: mod_component: Return true after denying a second component connection for a host (thanks xnyhps) --- plugins/mod_component.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index 5b1eefc7..98eaa6de 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -69,6 +69,7 @@ function module.add_host(module) if env.connected then module:log("error", "Second component attempted to connect, denying connection"); session:close{ condition = "conflict", text = "Component already connected" }; + return true; end env.connected = true; -- cgit v1.2.3 From e865b1b3fe06dd681f121fd0147608f47a8bfc34 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 27 Apr 2012 23:11:23 +0100 Subject: net.http.server, mod_http: Support http_default_host config option to specify where to direct requests for unknown HTTP vhosts --- plugins/mod_http.lua | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index ef3f0271..c379a562 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -10,6 +10,8 @@ module:set_global(); local server = require "net.http.server"; +server.set_default_host(module:get_option_string("http_default_host")); + local function normalize_path(path) if path:sub(1,1) ~= "/" then path = "/"..path; end if path:sub(-1,-1) == "/" then path = path:sub(1, -2); end @@ -83,6 +85,11 @@ function module.add_host(module) end module:handle_items("http-provider", http_app_added, http_app_removed); + + server.add_host(host); + function module.unload() + server.remove_host(host); + end end module:add_item("net-provider", { -- cgit v1.2.3 From 97bead16ac519052bbcfb3792fbc547fe0c423cb Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Fri, 27 Apr 2012 23:12:30 +0100 Subject: mod_http_errors: Add two new config options, http_errors_always_show (show even for unknown errors) and http_errors_default_message (message for unknown errors) --- plugins/mod_http_errors.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_http_errors.lua b/plugins/mod_http_errors.lua index 820bcc2f..c7bcbbc1 100644 --- a/plugins/mod_http_errors.lua +++ b/plugins/mod_http_errors.lua @@ -6,7 +6,8 @@ local codes = require "net.http.codes"; local termcolours = require "util.termcolours"; local show_private = module:get_option_boolean("http_errors_detailed", false); - +local always_serve = module:get_option_boolean("http_errors_always_show", true); +local default_message = { module:get_option_string("http_errors_default_message", "That's all I know.") }; local default_messages = { [400] = { "What kind of request do you call that??" }; [403] = { "You're not allowed to do that." }; @@ -59,7 +60,8 @@ end local function get_page(code, extra) local message = messages[code]; - if message then + if always_serve or message then + message = message or default_message; return (html:gsub("$(%a+)", { title = rawget(codes, code) or ("Code "..tostring(code)); message = message[1]:gsub("%%", function () -- cgit v1.2.3 From 568e94ab15866f79ca494e033954829732e75ed2 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 00:45:33 +0100 Subject: mod_bosh: Remove unused import of net.httpserver --- plugins/mod_bosh.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 84adb369..1fe52dda 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -10,7 +10,6 @@ module:set_global(); -- Global module local hosts = _G.hosts; local new_xmpp_stream = require "util.xmppstream".new; -local httpserver = require "net.httpserver"; local sm = require "core.sessionmanager"; local sm_destroy_session = sm.destroy_session; local new_uuid = require "util.uuid".generate; @@ -181,7 +180,7 @@ function handle_POST(event) session:close(); return nil; else - return true; -- Inform httpserver we shall reply later + return true; -- Inform http server we shall reply later end end end -- cgit v1.2.3 From f754aca9f2c4b168049b12ddda0b3334009f3740 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 02:56:10 +0100 Subject: mod_s2s: Add log() import --- plugins/s2s/mod_s2s.lua | 2 ++ 1 file changed, 2 insertions(+) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index b0bd5b40..478ed558 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -29,6 +29,8 @@ local connect_timeout = module:get_option_number("s2s_timeout", 60); local sessions = module:shared("sessions"); +local log = module._log; + --- Handle stanzas to remote domains local bouncy_stanzas = { message = true, presence = true, iq = true }; -- cgit v1.2.3 From 246e8535c13c600b9b1aba47fa87f676cae0d398 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:05:03 +0100 Subject: mod_c2s: Remove unused import of portmanager --- plugins/mod_c2s.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua index 743fe3d2..69f2298f 100644 --- a/plugins/mod_c2s.lua +++ b/plugins/mod_c2s.lua @@ -11,7 +11,6 @@ module:set_global(); local add_task = require "util.timer".add_task; local new_xmpp_stream = require "util.xmppstream".new; local nameprep = require "util.encodings".stringprep.nameprep; -local portmanager = require "core.portmanager"; local sessionmanager = require "core.sessionmanager"; local st = require "util.stanza"; local sm_new_session, sm_destroy_session = sessionmanager.new_session, sessionmanager.destroy_session; -- cgit v1.2.3 From ddf88f4b38e6d760764c547407715380a55e511a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:05:35 +0100 Subject: mod_saslauth: Remove unused declaration of xmlns_stanzas --- plugins/mod_saslauth.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index 7708572a..804db5f9 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -26,7 +26,6 @@ local log = module._log; local xmlns_sasl ='urn:ietf:params:xml:ns:xmpp-sasl'; local xmlns_bind ='urn:ietf:params:xml:ns:xmpp-bind'; -local xmlns_stanzas ='urn:ietf:params:xml:ns:xmpp-stanzas'; local function build_reply(status, ret, err_msg) local reply = st.stanza(status, {xmlns = xmlns_sasl}); -- cgit v1.2.3 From 561bbc3a2ebe967de780c3a6c7cbf203b89f226a Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:06:14 +0100 Subject: mod_s2s: Fix imports and remove some unused variables --- plugins/s2s/mod_s2s.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index 478ed558..e40f35bd 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -8,6 +8,10 @@ module:set_global(); +local prosody = prosody; +local hosts = prosody.hosts; +local core_process_stanza = prosody.core_process_stanza; + local tostring, type = tostring, type; local t_insert = table.insert; local xpcall, traceback = xpcall, debug.traceback; @@ -20,6 +24,7 @@ local new_xmpp_stream = require "util.xmppstream".new; local s2s_new_incoming = require "core.s2smanager".new_incoming; local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2s_destroy_session = require "core.s2smanager".destroy_session; +local s2s_mark_connected = require "core.s2smanager".mark_connected; local uuid_gen = require "util.uuid".generate; local cert_verify_identity = require "util.x509".verify_identity; @@ -41,7 +46,7 @@ local function bounce_sendq(session, reason) local dummy = { type = "s2sin"; send = function(s) - (session.log or log)("error", "Replying to to an s2s error reply, please report this! Traceback: %s", get_traceback()); + (session.log or log)("error", "Replying to to an s2s error reply, please report this! Traceback: %s", traceback()); end; dummy = true; }; @@ -81,7 +86,7 @@ module:hook("route/remote", function (event) return true; elseif host.type == "local" or host.type == "component" then log("error", "Trying to send a stanza to ourselves??") - log("error", "Traceback: %s", get_traceback()); + log("error", "Traceback: %s", traceback()); log("error", "Stanza: %s", tostring(stanza)); return false; else @@ -442,7 +447,6 @@ function listener.onstatus(conn, status) if status == "ssl-handshake-complete" then local session = sessions[conn]; if session and session.direction == "outgoing" then - local to_host, from_host = session.to_host, session.from_host; session.log("debug", "Sending stream header..."); session:open_stream(session.from_host, session.to_host); end -- cgit v1.2.3 From 5d28dc3276c0da0803adff0252db00440ac44a5b Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:11:45 +0100 Subject: mod_s2s/s2sout.lib: Fix imports and some undefined variables --- plugins/s2s/s2sout.lib.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index af55b273..011c864f 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -12,16 +12,18 @@ local portmanager = require "core.portmanager"; local wrapclient = require "net.server".wrapclient; local initialize_filters = require "util.filters".initialize; local idna_to_ascii = require "util.encodings".idna.to_ascii; -local add_task = require "util.timer".add_task; local new_ip = require "util.ip".new_ip; local rfc3484_dest = require "util.rfc3484".destination; local socket = require "socket"; +local adns = require "net.adns"; +local dns = require "net.dns"; local t_insert, t_sort, ipairs = table.insert, table.sort, ipairs; local st = require "util.stanza"; -local s2s_new_outgoing = require "core.s2smanager".new_outgoing; local s2s_destroy_session = require "core.s2smanager".destroy_session; +local log = module._log; + local sources = {}; local max_dns_depth = module:get_option_number("dns_max_depth", 3); @@ -67,7 +69,7 @@ function s2sout.initiate_connection(host_session) buffer = {}; host_session.send_buffer = buffer; end - log("debug", "Buffering data on unconnected s2sout to %s", to_host); + log("debug", "Buffering data on unconnected s2sout to %s", tostring(host_session.to_host)); buffer[#buffer+1] = data; log("debug", "Buffered item %d: %s", #buffer, tostring(data)); end -- cgit v1.2.3 From 844026b0eaa192cc595a5f4a909259b158fc898e Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:13:59 +0100 Subject: mod_component: Remove unused variable --- plugins/mod_component.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua index 98eaa6de..6be68e39 100644 --- a/plugins/mod_component.lua +++ b/plugins/mod_component.lua @@ -207,7 +207,6 @@ local stream_xmlns_attr = {xmlns='urn:ietf:params:xml:ns:xmpp-streams'}; local default_stream_attr = { ["xmlns:stream"] = "http://etherx.jabber.org/streams", xmlns = stream_callbacks.default_ns, version = "1.0", id = "" }; local function session_close(session, reason) if session.destroyed then return; end - local log = session.log or log; if session.conn then if session.notopen then session.send(""); -- cgit v1.2.3 From d37a37fb960a96c24de3cc7afd82034c6d1d47c8 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:34:58 +0100 Subject: mod_message: Remove unused import of table.insert --- plugins/mod_message.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_message.lua b/plugins/mod_message.lua index df317532..ebff2fe7 100644 --- a/plugins/mod_message.lua +++ b/plugins/mod_message.lua @@ -14,7 +14,6 @@ local st = require "util.stanza"; local jid_bare = require "util.jid".bare; local jid_split = require "util.jid".split; local user_exists = require "core.usermanager".user_exists; -local t_insert = table.insert; local function process_to_bare(bare, origin, stanza) local user = bare_sessions[bare]; -- cgit v1.2.3 From a468c4f40f219ded6675bae73b246be278a70585 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:39:12 +0100 Subject: mod_iq: Remove unused import of jid.split, bare_sessions and don't unpack event.origin when it isn't used. Waqas. --- plugins/mod_iq.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_iq.lua b/plugins/mod_iq.lua index 484a1f8f..55bf59c3 100644 --- a/plugins/mod_iq.lua +++ b/plugins/mod_iq.lua @@ -8,10 +8,8 @@ local st = require "util.stanza"; -local jid_split = require "util.jid".split; local full_sessions = full_sessions; -local bare_sessions = bare_sessions; if module:get_host_type() == "local" then module:hook("iq/full", function(data) @@ -33,7 +31,7 @@ end module:hook("iq/bare", function(data) -- IQ to bare JID recieved - local origin, stanza = data.origin, data.stanza; + local stanza = data.stanza; local type = stanza.attr.type; -- TODO fire post processing events @@ -49,7 +47,7 @@ end); module:hook("iq/self", function(data) -- IQ to self JID recieved - local origin, stanza = data.origin, data.stanza; + local stanza = data.stanza; local type = stanza.attr.type; if type == "get" or type == "set" then @@ -64,7 +62,7 @@ end); module:hook("iq/host", function(data) -- IQ to a local host recieved - local origin, stanza = data.origin, data.stanza; + local stanza = data.stanza; local type = stanza.attr.type; if type == "get" or type == "set" then -- cgit v1.2.3 From 15f19658873274eb0712a8785f393e2ccfbeabb0 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:43:27 +0100 Subject: mod_dialback: Remove unused declaration of xmlns_dialback --- plugins/mod_dialback.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index e578c412..35186c5e 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -17,7 +17,6 @@ local st = require "util.stanza"; local sha256_hash = require "util.hashes".sha256; local xmlns_stream = "http://etherx.jabber.org/streams"; -local xmlns_dialback = "jabber:server:dialback"; local dialback_requests = setmetatable({}, { __mode = 'v' }); -- cgit v1.2.3 From 5abd2aa3e78aabaeb8a2c7543a751c85a1979742 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:49:13 +0100 Subject: mod_auth_internal_plain: Remove unused imports --- plugins/mod_auth_internal_plain.lua | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_auth_internal_plain.lua b/plugins/mod_auth_internal_plain.lua index 93b50351..89dd7f1b 100644 --- a/plugins/mod_auth_internal_plain.lua +++ b/plugins/mod_auth_internal_plain.lua @@ -7,19 +7,11 @@ -- local datamanager = require "util.datamanager"; -local log = require "util.logger".init("auth_internal_plain"); -local type = type; -local error = error; -local ipairs = ipairs; -local hashes = require "util.hashes"; -local jid_bare = require "util.jid".bare; -local config = require "core.configmanager"; local usermanager = require "core.usermanager"; local new_sasl = require "util.sasl".new; local nodeprep = require "util.encodings".stringprep.nodeprep; -local hosts = hosts; -local prosody = _G.prosody; +local log = module._log; function new_default_provider(host) local provider = { name = "internal_plain" }; -- cgit v1.2.3 From a4d38eb601ccc0d6eae0396f47e9a27becfc12a4 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:55:25 +0100 Subject: mod_auth_internal_hashed: Remove unused imports --- plugins/mod_auth_internal_hashed.lua | 9 --------- 1 file changed, 9 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_auth_internal_hashed.lua b/plugins/mod_auth_internal_hashed.lua index 399044ad..65cc8143 100644 --- a/plugins/mod_auth_internal_hashed.lua +++ b/plugins/mod_auth_internal_hashed.lua @@ -9,18 +9,11 @@ local datamanager = require "util.datamanager"; local log = require "util.logger".init("auth_internal_hashed"); -local type = type; -local error = error; -local ipairs = ipairs; -local hashes = require "util.hashes"; -local jid_bare = require "util.jid".bare; local getAuthenticationDatabaseSHA1 = require "util.sasl.scram".getAuthenticationDatabaseSHA1; -local config = require "core.configmanager"; local usermanager = require "core.usermanager"; local generate_uuid = require "util.uuid".generate; local new_sasl = require "util.sasl".new; local nodeprep = require "util.encodings".stringprep.nodeprep; -local hosts = hosts; -- COMPAT w/old trunk: remove these two lines before 0.8 release local hmac_sha1 = require "util.hmac".sha1; @@ -47,8 +40,6 @@ do end -local prosody = _G.prosody; - -- Default; can be set per-user local iteration_count = 4096; -- cgit v1.2.3 From 90342aaf3c7f3bd76fe38b8af63947448159fe10 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 03:59:31 +0100 Subject: mod_auth_internal_hashed: Remove COMPAT code (upgrading old hashed storage format from pre-0.8) --- plugins/mod_auth_internal_hashed.lua | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_auth_internal_hashed.lua b/plugins/mod_auth_internal_hashed.lua index 65cc8143..607ecab4 100644 --- a/plugins/mod_auth_internal_hashed.lua +++ b/plugins/mod_auth_internal_hashed.lua @@ -15,10 +15,6 @@ local generate_uuid = require "util.uuid".generate; local new_sasl = require "util.sasl".new; local nodeprep = require "util.encodings".stringprep.nodeprep; --- COMPAT w/old trunk: remove these two lines before 0.8 release -local hmac_sha1 = require "util.hmac".sha1; -local sha1 = require "util.hashes".sha1; - local to_hex; do local function replace_byte_with_hex(byte) @@ -66,16 +62,6 @@ function new_hashpass_provider(host) return nil, "Auth failed. Stored salt and iteration count information is not complete."; end - -- convert hexpass to stored_key and server_key - -- COMPAT w/old trunk: remove before 0.8 release - if credentials.hashpass then - local salted_password = from_hex(credentials.hashpass); - credentials.stored_key = sha1(hmac_sha1(salted_password, "Client Key"), true); - credentials.server_key = to_hex(hmac_sha1(salted_password, "Server Key")); - credentials.hashpass = nil - datamanager.store(username, host, "accounts", credentials); - end - local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, credentials.salt, credentials.iteration_count); local stored_key_hex = to_hex(stored_key); @@ -149,16 +135,6 @@ function new_hashpass_provider(host) if not credentials then return; end end - -- convert hexpass to stored_key and server_key - -- COMPAT w/old trunk: remove before 0.8 release - if credentials.hashpass then - local salted_password = from_hex(credentials.hashpass); - credentials.stored_key = sha1(hmac_sha1(salted_password, "Client Key"), true); - credentials.server_key = to_hex(hmac_sha1(salted_password, "Server Key")); - credentials.hashpass = nil - datamanager.store(username, host, "accounts", credentials); - end - local stored_key, server_key, iteration_count, salt = credentials.stored_key, credentials.server_key, credentials.iteration_count, credentials.salt; stored_key = stored_key and from_hex(stored_key); server_key = server_key and from_hex(server_key); -- cgit v1.2.3 From 837f0451dadc105381a7fb02684ccdd82b3142f2 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 04:01:59 +0100 Subject: mod_auth_anonymous: Remove unused logger init --- plugins/mod_auth_anonymous.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_auth_anonymous.lua b/plugins/mod_auth_anonymous.lua index 8d790508..056d7e6b 100644 --- a/plugins/mod_auth_anonymous.lua +++ b/plugins/mod_auth_anonymous.lua @@ -6,7 +6,6 @@ -- COPYING file in the source package for more information. -- -local log = require "util.logger".init("auth_anonymous"); local new_sasl = require "util.sasl".new; local datamanager = require "util.datamanager"; -- cgit v1.2.3 From 6bd5b3b2eaf7a2d7265495a1abb6fc88c5f9f4fa Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 04:12:34 +0100 Subject: mod_muc/muc.lib.lua: Remove unused imports and variables --- plugins/muc/muc.lib.lua | 5 ----- 1 file changed, 5 deletions(-) (limited to 'plugins') diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 286ad70c..5170c94a 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -9,7 +9,6 @@ local select = select; local pairs, ipairs = pairs, ipairs; -local datamanager = require "util.datamanager"; local datetime = require "util.datetime"; local dataform = require "util.dataforms"; @@ -19,7 +18,6 @@ local jid_bare = require "util.jid".bare; local jid_prep = require "util.jid".prep; local st = require "util.stanza"; local log = require "util.logger".init("mod_muc"); -local multitable_new = require "util.multitable".new; local t_insert, t_remove = table.insert, table.remove; local setmetatable = setmetatable; local base64 = require "util.encodings".base64; @@ -133,7 +131,6 @@ function room_mt:broadcast_message(stanza, historic) stanza = st.clone(stanza); stanza.attr.to = ""; local stamp = datetime.datetime(); - local chars = #tostring(stanza); stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = muc_domain, stamp = stamp}):up(); -- XEP-0203 stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated) local entry = { stanza = stanza, stamp = stamp }; @@ -185,7 +182,6 @@ function room_mt:send_history(to, stanza) local n = 0; local charcount = 0; - local stanzacount = 0; for i=#history,1,-1 do local entry = history[i]; @@ -855,7 +851,6 @@ function room_mt:handle_to_room(origin, stanza) -- presence changes and groupcha end elseif stanza.name == "message" and type == "groupchat" then local from, to = stanza.attr.from, stanza.attr.to; - local room = jid_bare(to); local current_nick = self._jid_nick[from]; local occupant = self._occupants[current_nick]; if not occupant then -- not in room -- cgit v1.2.3 From 1c5625ca7d81c86a218ba3144f0216da516802be Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 13:58:13 +0100 Subject: mod_bosh: Remove unused import of util.timer --- plugins/mod_bosh.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 1fe52dda..3b5e3e1e 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -18,7 +18,6 @@ local core_process_stanza = core_process_stanza; local st = require "util.stanza"; local logger = require "util.logger"; local log = logger.init("mod_bosh"); -local timer = require "util.timer"; local xmlns_streams = "http://etherx.jabber.org/streams"; local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; -- cgit v1.2.3 From 5f2142959cb9fefda450efce5b90bfb184d89fa5 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 13:58:37 +0100 Subject: mod_bosh: Fix request/response mixup --- plugins/mod_bosh.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 3b5e3e1e..5b7a24ab 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -379,7 +379,7 @@ function stream_callbacks.error(context, error) local response = context.response; response.headers = default_headers; response.status_code = 400; - request:send(); + response:send(); return; end -- cgit v1.2.3 From 5b1691012fd47880d5285fe3092d4a48e3616791 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 14:03:39 +0100 Subject: mod_bosh: Remove unused send_buffer variable --- plugins/mod_bosh.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_bosh.lua b/plugins/mod_bosh.lua index 5b7a24ab..24dc3755 100644 --- a/plugins/mod_bosh.lua +++ b/plugins/mod_bosh.lua @@ -262,7 +262,7 @@ function stream_callbacks.streamopened(context, attr) session.log("debug", "BOSH session created for request from %s", session.ip); log("info", "New BOSH session, assigned it sid '%s'", sid); - local r, send_buffer = session.requests, session.send_buffer; + local r = session.requests; function session.send(s) -- We need to ensure that outgoing stanzas have the jabber:client xmlns if s.attr and not s.attr.xmlns then -- cgit v1.2.3 From ce88b45b6f633b8712bea6d02282c8bd1e496e1d Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 14:46:36 +0100 Subject: mod_http: Depend on mod_http_errors --- plugins/mod_http.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins') diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua index c379a562..b7376831 100644 --- a/plugins/mod_http.lua +++ b/plugins/mod_http.lua @@ -7,6 +7,7 @@ -- module:set_global(); +module:depends("http_errors"); local server = require "net.http.server"; -- cgit v1.2.3 From ad6b4cd46567245baf4d280e9e3f9dfbdf7fee23 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Sat, 28 Apr 2012 17:18:03 +0200 Subject: mod_admin_telnet: Add c2s:count() which shows number of connected users. --- plugins/mod_admin_telnet.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'plugins') diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 202170ba..544ea161 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -440,6 +440,16 @@ local function show_c2s(callback) end end +function def_env.c2s:count(match_jid) + local count = 0; + show_c2s(function (jid, session) + if (not match_jid) or jid:match(match_jid) then + count = count + 1; + end + end); + return true, "Total: "..count.." clients"; +end + function def_env.c2s:show(match_jid) local print, count = self.session.print, 0; local curr_host; -- cgit v1.2.3 From 5b639b3f2c245455e1e6a2194379c85ebd5de814 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 16:21:57 +0100 Subject: mod_admin_adhoc: Small style fix --- plugins/mod_admin_adhoc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_admin_adhoc.lua b/plugins/mod_admin_adhoc.lua index 6f1357a9..4d2c60d7 100644 --- a/plugins/mod_admin_adhoc.lua +++ b/plugins/mod_admin_adhoc.lua @@ -24,7 +24,7 @@ local dataforms_new = require "util.dataforms".new; local array = require "util.array"; local modulemanager = require "modulemanager"; -module:depends"adhoc"; +module:depends("adhoc"); local adhoc_new = module:require "adhoc".new; function add_user_command_handler(self, data, state) -- cgit v1.2.3 From 21fc89249c3d2683cb09b7440d6a78a3503ef529 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 16:29:00 +0100 Subject: mod_s2s: Fix import of core_process_stanza. I don't know why I thought it was there (thanks Zash) --- plugins/s2s/mod_s2s.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index e40f35bd..f44ab43d 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -10,7 +10,7 @@ module:set_global(); local prosody = prosody; local hosts = prosody.hosts; -local core_process_stanza = prosody.core_process_stanza; +local core_process_stanza = core_process_stanza; local tostring, type = tostring, type; local t_insert = table.insert; -- cgit v1.2.3 From 449813a79ee6aeb2f0a3c239b3e9c09df0634f0d Mon Sep 17 00:00:00 2001 From: Paul Aurich Date: Sat, 28 Apr 2012 08:35:34 -0700 Subject: mod_s2s: Log certificate errors, for troubleshooting goodness --- plugins/s2s/mod_s2s.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'plugins') diff --git a/plugins/s2s/mod_s2s.lua b/plugins/s2s/mod_s2s.lua index f44ab43d..cee7d6f6 100644 --- a/plugins/s2s/mod_s2s.lua +++ b/plugins/s2s/mod_s2s.lua @@ -134,6 +134,9 @@ local function check_cert_status(session) -- Is there any interest in printing out all/the number of errors here? if not chain_valid then (session.log or log)("debug", "certificate chain validation result: invalid"); + for depth, t in ipairs(errors) do + (session.log or log)("debug", "certificate error(s) at depth %d: %s", depth-1, table.concat(t, ", ")) + end session.cert_chain_status = "invalid"; else (session.log or log)("debug", "certificate chain validation result: valid"); -- cgit v1.2.3 From 9570749b05e6306177708a3dfafa63cb49a499df Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sat, 28 Apr 2012 18:36:03 +0100 Subject: mod_muc/muc.lib: Fall back to default_history_length if no length in config --- plugins/muc/muc.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 5170c94a..9be1736f 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -336,7 +336,7 @@ function room_mt:get_changesubject() return self._data.changesubject; end function room_mt:get_historylength() - return self._data.history_length + return self._data.history_length or default_history_length; end function room_mt:set_historylength(length) if tonumber(length) == nil then -- cgit v1.2.3 From 005331cb75eeee3e13d35bcc8187d70eb409e48d Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Sat, 28 Apr 2012 22:34:05 +0200 Subject: s2sout.lib: Check whether lua-socket supports IPv6 --- plugins/s2s/s2sout.lib.lua | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'plugins') diff --git a/plugins/s2s/s2sout.lib.lua b/plugins/s2s/s2sout.lib.lua index 011c864f..f3496597 100644 --- a/plugins/s2s/s2sout.lib.lua +++ b/plugins/s2s/s2sout.lib.lua @@ -271,6 +271,10 @@ function s2sout.make_connect(host_session, connect_host, connect_port) if connect_host.proto == "IPv4" then conn, handler = socket.tcp(); else + if not socket.tcp6 then + log("warn", "Could not connect to "..to_host..". Your version of lua-socket does not support IPv6"); + return false, "no-ipv6"; + end conn, handler = socket.tcp6(); end -- cgit v1.2.3