diff options
-rw-r--r-- | core/componentmanager.lua | 14 | ||||
-rw-r--r-- | core/discomanager.lua | 66 | ||||
-rw-r--r-- | core/modulemanager.lua | 84 | ||||
-rw-r--r-- | plugins/mod_disco.lua | 45 | ||||
-rw-r--r-- | plugins/mod_legacyauth.lua | 17 | ||||
-rw-r--r-- | plugins/mod_pep.lua | 2 | ||||
-rw-r--r-- | plugins/mod_posix.lua | 13 | ||||
-rw-r--r-- | plugins/mod_register.lua | 11 | ||||
-rw-r--r-- | util/discohelper.lua | 89 |
9 files changed, 93 insertions, 248 deletions
diff --git a/core/componentmanager.lua b/core/componentmanager.lua index 08868236..536d1633 100644 --- a/core/componentmanager.lua +++ b/core/componentmanager.lua @@ -6,8 +6,6 @@ -- COPYING file in the source package for more information. -- - - local prosody = prosody; local log = require "util.logger".init("componentmanager"); local configmanager = require "core.configmanager"; @@ -25,14 +23,6 @@ local components = {}; local disco_items = require "util.multitable".new(); local NULL = {}; -require "core.discomanager".addDiscoItemsHandler("*host", function(reply, to, from, node) - if #node == 0 and hosts[to] then - for jid in pairs(disco_items:get(to) or NULL) do - reply:tag("item", {jid = jid}):up(); - end - return true; - end -end); prosody.events.add_handler("server-starting", function () core_route_stanza = _G.core_route_stanza; end); @@ -138,4 +128,8 @@ function set_component_handler(host, handler) components[host] = handler; end +function get_children(host) + return disco_items:get(host) or NULL; +end + return _M; diff --git a/core/discomanager.lua b/core/discomanager.lua deleted file mode 100644 index 742907dd..00000000 --- a/core/discomanager.lua +++ /dev/null @@ -1,66 +0,0 @@ --- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain --- --- This project is MIT/X11 licensed. Please see the --- COPYING file in the source package for more information. --- - - - -local helper = require "util.discohelper".new(); -local hosts = hosts; -local jid_split = require "util.jid".split; -local jid_bare = require "util.jid".bare; -local usermanager_user_exists = require "core.usermanager".user_exists; -local rostermanager_is_contact_subscribed = require "core.rostermanager".is_contact_subscribed; -local print = print; - -do - helper:addDiscoInfoHandler("*host", function(reply, to, from, node) - if hosts[to] then - reply:tag("identity", {category="server", type="im", name="Prosody"}):up(); - return true; - end - end); - helper:addDiscoInfoHandler("*node", function(reply, to, from, node) - local node, host = jid_split(to); - if hosts[host] and rostermanager_is_contact_subscribed(node, host, jid_bare(from)) then - reply:tag("identity", {category="account", type="registered"}):up(); - return true; - end - end); - helper:addDiscoItemsHandler("*host", function(reply, to, from, node) - if hosts[to] and hosts[to].type == "local" then - return true; - end - end); -end - -module "discomanager" - -function handle(stanza) - return helper:handle(stanza); -end - -function addDiscoItemsHandler(jid, func) - return helper:addDiscoItemsHandler(jid, func); -end - -function addDiscoInfoHandler(jid, func) - return helper:addDiscoInfoHandler(jid, func); -end - -function set(plugin, var, origin) - -- TODO handle origin and host based on plugin. - local handler = function(reply, to, from, node) -- service discovery - if #node == 0 then - reply:tag("feature", {var = var}):up(); - return true; - end - end - addDiscoInfoHandler("*node", handler); - addDiscoInfoHandler("*host", handler); -end - -return _M; diff --git a/core/modulemanager.lua b/core/modulemanager.lua index c2e6e68e..7037fc90 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -6,13 +6,10 @@ -- COPYING file in the source package for more information. -- - - local plugin_dir = CFG_PLUGINDIR or "./plugins/"; local logger = require "util.logger"; local log = logger.init("modulemanager"); -local addDiscoInfoHandler = require "core.discomanager".addDiscoInfoHandler; local eventmanager = require "core.eventmanager"; local config = require "core.configmanager"; local multitable_new = require "util.multitable".new; @@ -50,8 +47,6 @@ local handler_info = {}; local modulehelpers = setmetatable({}, { __index = _G }); -local features_table = multitable_new(); -local identities_table = multitable_new(); local handler_table = multitable_new(); local hooked = multitable_new(); local hooks = multitable_new(); @@ -171,8 +166,6 @@ function unload(host, name, ...) end end modulemap[host][name] = nil; - features_table:remove(host, name); - identities_table:remove(host, name); local params = handler_table:get(host, name); -- , {module.host, origin_type, tag, xmlns} for _, param in pairs(params or NULL) do local handlers = stanza_handlers:get(param[1], param[2], param[3], param[4]); @@ -328,50 +321,11 @@ function api:add_iq_handler(origin_type, xmlns, handler) self:add_handler(origin_type, "iq", xmlns, handler); end -addDiscoInfoHandler("*host", function(reply, to, from, node) - if #node == 0 then - local done = {}; - for module, identities in pairs(identities_table:get(to) or NULL) do -- for each module - for identity, attr in pairs(identities) do - if not done[identity] then - reply:tag("identity", attr):up(); -- TODO cache - done[identity] = true; - end - end - end - for module, identities in pairs(identities_table:get("*") or NULL) do -- for each module - for identity, attr in pairs(identities) do - if not done[identity] then - reply:tag("identity", attr):up(); -- TODO cache - done[identity] = true; - end - end - end - for module, features in pairs(features_table:get(to) or NULL) do -- for each module - for feature in pairs(features) do - if not done[feature] then - reply:tag("feature", {var = feature}):up(); -- TODO cache - done[feature] = true; - end - end - end - for module, features in pairs(features_table:get("*") or NULL) do -- for each module - for feature in pairs(features) do - if not done[feature] then - reply:tag("feature", {var = feature}):up(); -- TODO cache - done[feature] = true; - end - end - end - return next(done) ~= nil; - end -end); - function api:add_feature(xmlns) - features_table:set(self.host, self.name, xmlns, true); + self:add_item("feature", xmlns); end -function api:add_identity(category, type) - identities_table:set(self.host, self.name, category.."\0"..type, {category = category, type = type}); +function api:add_identity(category, type, name) + self:add_item("identity", {category = category, type = type, name = name}); end local event_hook = function(host, mod_name, event_name, ...) @@ -422,6 +376,38 @@ function api:get_option(name, default_value) return config.get(self.host, self.name, name) or config.get(self.host, "core", name) or default_value; end +local t_remove = _G.table.remove; +local module_items = multitable_new(); +function api:add_item(key, value) + self.items = self.items or {}; + self.items[key] = self.items[key] or {}; + t_insert(self.items[key], value); + self:fire_event("item-added/"..key, {source = self, item = value}); +end +function api:remove_item(key, value) + local t = self.items and self.items[key] or NULL; + for i = #t,1,-1 do + if t[i] == value then + t_remove(self.items[key], i); + self:fire_event("item-removed/"..key, {source = self, item = value}); + return value; + end + end +end + +function api:get_host_items(key) + local result = {}; + for mod_name, module in pairs(modulemap[self.host]) do + module = module.module; + if module.items then + for _, item in ipairs(module.items[key] or NULL) do + t_insert(result, item); + end + end + end + return result; +end + -------------------------------------------------------------------- local actions = {}; diff --git a/plugins/mod_disco.lua b/plugins/mod_disco.lua index 00ea01d8..06b29f0e 100644 --- a/plugins/mod_disco.lua +++ b/plugins/mod_disco.lua @@ -6,16 +6,47 @@ -- COPYING file in the source package for more information. -- +local componentmanager_get_children = require "core.componentmanager".get_children; +local st = require "util.stanza" - -local discomanager_handle = require "core.discomanager".handle; - +module:add_identity("server", "im", "Prosody"); -- FIXME should be in the non-existing mod_router module:add_feature("http://jabber.org/protocol/disco#info"); module:add_feature("http://jabber.org/protocol/disco#items"); -module:add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#info", function (session, stanza) - session.send(discomanager_handle(stanza)); +module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event) + local origin, stanza = event.origin, event.stanza; + if stanza.attr.type ~= "get" then return; end + local node = stanza.tags[1].attr.node; + if node and node ~= "" then return; end -- TODO fire event? + + local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#info"); + local done = {}; + for _,identity in ipairs(module:get_host_items("identity")) do + local identity_s = identity.category.."\0"..identity.type; + if not done[identity_s] then + reply:tag("identity", identity):up(); + done[identity_s] = true; + end + end + for _,feature in ipairs(module:get_host_items("feature")) do + if not done[feature] then + reply:tag("feature", {var=feature}):up(); + done[feature] = true; + end + end + origin.send(reply); + return true; end); -module:add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#items", function (session, stanza) - session.send(discomanager_handle(stanza)); +module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event) + local origin, stanza = event.origin, event.stanza; + if stanza.attr.type ~= "get" then return; end + local node = stanza.tags[1].attr.node; + if node and node ~= "" then return; end -- TODO fire event? + + local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#items"); + for jid in pairs(componentmanager_get_children(module.host)) do + reply:tag("item", {jid = jid}):up(); + end + origin.send(reply); + return true; end); diff --git a/plugins/mod_legacyauth.lua b/plugins/mod_legacyauth.lua index de94411e..9a9c3902 100644 --- a/plugins/mod_legacyauth.lua +++ b/plugins/mod_legacyauth.lua @@ -11,8 +11,7 @@ local st = require "util.stanza"; local t_concat = table.concat; -local config = require "core.configmanager"; -local secure_auth_only = config.get(module:get_host(), "core", "require_encryption"); +local secure_auth_only = module:get_option("require_encryption"); local sessionmanager = require "core.sessionmanager"; local usermanager = require "core.usermanager"; @@ -43,11 +42,9 @@ module:add_iq_handler("c2s_unauthed", "jabber:iq:auth", :tag("username"):up() :tag("password"):up() :tag("resource"):up()); - return true; else username, password, resource = t_concat(username), t_concat(password), t_concat(resource); local reply = st.reply(stanza); - require "core.usermanager" if usermanager.validate_credentials(session.host, username, password) then -- Authentication successful! local success, err = sessionmanager.make_authenticated(session, username); @@ -56,19 +53,13 @@ module:add_iq_handler("c2s_unauthed", "jabber:iq:auth", success, err_type, err, err_msg = sessionmanager.bind_resource(session, resource); if not success then session.send(st.error_reply(stanza, err_type, err, err_msg)); - return true; + return true; -- FIXME need to unauthenticate here end end session.send(st.reply(stanza)); - return true; else - local reply = st.reply(stanza); - reply.attr.type = "error"; - reply:tag("error", { code = "401", type = "auth" }) - :tag("not-authorized", { xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas" }); - session.send(reply); - return true; + session.send(st.error_reply(stanza, "auth", "not-authorized")); end end - + return true; end); diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua index e07759f0..842f1fce 100644 --- a/plugins/mod_pep.lua +++ b/plugins/mod_pep.lua @@ -25,7 +25,7 @@ local data = {}; local recipients = {}; local hash_map = {}; -module:add_identity("pubsub", "pep"); +module:add_identity("pubsub", "pep", "Prosody"); module:add_feature("http://jabber.org/protocol/pubsub#publish"); local function publish(session, node, item) diff --git a/plugins/mod_posix.lua b/plugins/mod_posix.lua index af4cdb16..5f7dfc5b 100644 --- a/plugins/mod_posix.lua +++ b/plugins/mod_posix.lua @@ -17,7 +17,6 @@ if type(signal) == "string" then module:log("warn", "Couldn't load signal library, won't respond to SIGTERM"); end -local config_get = require "core.configmanager".get; local logger_set = require "util.logger".setwriter; local prosody = _G.prosody; @@ -26,8 +25,8 @@ module.host = "*"; -- we're a global module -- Allow switching away from root, some people like strange ports. module:add_event_hook("server-started", function () - local uid = config_get("*", "core", "setuid"); - local gid = config_get("*", "core", "setgid"); + local uid = module:get_option("setuid"); + local gid = module:get_option("setgid"); if gid then local success, msg = pposix.setgid(gid); if success then @@ -50,9 +49,9 @@ module:add_event_hook("server-started", function () -- Don't even think about it! module:add_event_hook("server-starting", function () - local suid = config_get("*", "core", "setuid"); + local suid = module:get_option("setuid"); if not suid or suid == 0 or suid == "root" then - if pposix.getuid() == 0 and not config_get("*", "core", "run_as_root") then + if pposix.getuid() == 0 and not module:get_option("run_as_root") then module:log("error", "Danger, Will Robinson! Prosody doesn't need to be run as root, so don't do it!"); module:log("error", "For more information on running Prosody as root, see http://prosody.im/doc/root"); prosody.shutdown("Refusing to run as root"); @@ -73,7 +72,7 @@ local function write_pidfile() if pidfile_written then remove_pidfile(); end - local pidfile = config_get("*", "core", "pidfile"); + local pidfile = module:get_option("pidfile"); if pidfile then local pf, err = io.open(pidfile, "w+"); if not pf then @@ -103,7 +102,7 @@ function syslog_sink_maker(config) end require "core.loggingmanager".register_sink_type("syslog", syslog_sink_maker); -if not config_get("*", "core", "no_daemonize") then +if not module:get_option("no_daemonize") then local function daemonize_server() local ok, ret = pposix.daemonize(); if not ok then diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index 383ab811..0cb8d771 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -9,7 +9,6 @@ local hosts = _G.hosts; local st = require "util.stanza"; -local config = require "core.configmanager"; local datamanager = require "util.datamanager"; local usermanager_user_exists = require "core.usermanager".user_exists; local usermanager_create_user = require "core.usermanager".create_user; @@ -90,16 +89,16 @@ module:add_iq_handler("c2s", "jabber:iq:register", function (session, stanza) end); local recent_ips = {}; -local min_seconds_between_registrations = config.get(module.host, "core", "min_seconds_between_registrations"); -local whitelist_only = config.get(module.host, "core", "whitelist_registration_only"); -local whitelisted_ips = config.get(module.host, "core", "registration_whitelist") or { "127.0.0.1" }; -local blacklisted_ips = config.get(module.host, "core", "registration_blacklist") or {}; +local min_seconds_between_registrations = module:get_option("min_seconds_between_registrations"); +local whitelist_only = module:get_option("whitelist_registration_only"); +local whitelisted_ips = module:get_option("registration_whitelist") or { "127.0.0.1" }; +local blacklisted_ips = module:get_option("registration_blacklist") or {}; for _, ip in ipairs(whitelisted_ips) do whitelisted_ips[ip] = true; end for _, ip in ipairs(blacklisted_ips) do blacklisted_ips[ip] = true; end module:add_iq_handler("c2s_unauthed", "jabber:iq:register", function (session, stanza) - if config.get(module.host, "core", "allow_registration") == false then + if module:get_option("allow_registration") == false then session.send(st.error_reply(stanza, "cancel", "service-unavailable")); elseif stanza.tags[1].name == "query" then local query = stanza.tags[1]; diff --git a/util/discohelper.lua b/util/discohelper.lua deleted file mode 100644 index 5d9bf287..00000000 --- a/util/discohelper.lua +++ /dev/null @@ -1,89 +0,0 @@ --- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain --- --- This project is MIT/X11 licensed. Please see the --- COPYING file in the source package for more information. --- - - - -local t_insert = table.insert; -local jid_split = require "util.jid".split; -local ipairs = ipairs; -local st = require "util.stanza"; - -module "discohelper"; - -local function addDiscoItemsHandler(self, jid, func) - if self.item_handlers[jid] then - t_insert(self.item_handlers[jid], func); - else - self.item_handlers[jid] = {func}; - end -end - -local function addDiscoInfoHandler(self, jid, func) - if self.info_handlers[jid] then - t_insert(self.info_handlers[jid], func); - else - self.info_handlers[jid] = {func}; - end -end - -local function handle(self, stanza) - if stanza.name == "iq" and stanza.tags[1].name == "query" then - local query = stanza.tags[1]; - local to = stanza.attr.to; - local from = stanza.attr.from - local node = query.attr.node or ""; - local to_node, to_host = jid_split(to); - - local reply = st.reply(stanza):query(query.attr.xmlns); - local handlers; - if query.attr.xmlns == "http://jabber.org/protocol/disco#info" then -- select handler set - handlers = self.info_handlers; - elseif query.attr.xmlns == "http://jabber.org/protocol/disco#items" then - handlers = self.item_handlers; - end - local handler; - local found; -- to keep track of any handlers found - if to_node then -- handlers which get called always - handler = handlers["*node"]; - else - handler = handlers["*host"]; - end - if handler then -- call always called handler - for _, h in ipairs(handler) do - if h(reply, to, from, node) then found = true; end - end - end - handler = handlers[to]; -- get the handler - if not handler then -- if not found then use default handler - if to_node then - handler = handlers["*defaultnode"]; - else - handler = handlers["*defaulthost"]; - end - end - if handler then - for _, h in ipairs(handler) do - if h(reply, to, from, node) then found = true; end - end - end - if found then return reply; end -- return the reply if there was one - return st.error_reply(stanza, "cancel", "service-unavailable"); - end -end - -function new() - return { - item_handlers = {}; - info_handlers = {}; - addDiscoItemsHandler = addDiscoItemsHandler; - addDiscoInfoHandler = addDiscoInfoHandler; - handle = handle; - }; -end - -return _M; |