aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/configmanager.lua13
-rw-r--r--core/hostmanager.lua7
-rw-r--r--core/modulemanager.lua9
-rw-r--r--core/s2smanager.lua3
-rw-r--r--core/sessionmanager.lua8
-rw-r--r--core/stanza_router.lua14
6 files changed, 44 insertions, 10 deletions
diff --git a/core/configmanager.lua b/core/configmanager.lua
index 1fbe83b8..a7c7c4be 100644
--- a/core/configmanager.lua
+++ b/core/configmanager.lua
@@ -9,8 +9,9 @@
local _G = _G;
-local setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type =
- setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type;
+local setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table, format =
+ setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table, string.format;
+
local eventmanager = require "core.eventmanager";
@@ -115,6 +116,10 @@ do
rawset(env, "__currenthost", "*") -- Default is global
function env.Host(name)
+ if rawget(config, name) and rawget(config[name].core, "component_module") then
+ error(format("Host %q clashes with previously defined %s Component %q, for services use a sub-domain like conference.%s",
+ name, config[name].core.component_module:gsub("^%a+$", { component = "external", muc = "MUC"}), name, name), 0);
+ end
rawset(env, "__currenthost", name);
-- Needs at least one setting to logically exist :)
set(name or "*", "core", "defined", true);
@@ -122,6 +127,10 @@ do
env.host = env.Host;
function env.Component(name)
+ if rawget(config, name) and rawget(config[name].core, "defined") and not rawget(config[name].core, "component_module") then
+ error(format("Component %q clashes with previously defined Host %q, for services use a sub-domain like conference.%s",
+ name, name, name), 0);
+ end
set(name, "core", "component_module", "component");
-- Don't load the global modules by default
set(name, "core", "load_global_modules", false);
diff --git a/core/hostmanager.lua b/core/hostmanager.lua
index 713788dd..125e71ba 100644
--- a/core/hostmanager.lua
+++ b/core/hostmanager.lua
@@ -33,12 +33,19 @@ local hosts_loaded_once;
local function load_enabled_hosts(config)
local defined_hosts = config or configmanager.getconfig();
+ local activated_any_host;
for host, host_config in pairs(defined_hosts) do
if host ~= "*" and (host_config.core.enabled == nil or host_config.core.enabled) and not host_config.core.component_module then
+ activated_any_host = true;
activate(host, host_config);
end
end
+
+ if not activated_any_host then
+ log("error", "No hosts defined in the config file. This may cause unexpected behaviour as no modules will be loaded.");
+ end
+
eventmanager.fire_event("hosts-activated", defined_hosts);
hosts_loaded_once = true;
end
diff --git a/core/modulemanager.lua b/core/modulemanager.lua
index 9cd56187..ecb1bc6c 100644
--- a/core/modulemanager.lua
+++ b/core/modulemanager.lua
@@ -197,6 +197,15 @@ function unload(host, name, ...)
end
end
hooks:remove(host, name);
+ if mod.module.items then -- remove items
+ for key,t in pairs(mod.module.items) do
+ for i = #t,1,-1 do
+ local value = t[i];
+ t[i] = nil;
+ hosts[host].events.fire_event("item-removed/"..key, {source = self, item = value});
+ end
+ end
+ end
modulemap[host][name] = nil;
return true;
end
diff --git a/core/s2smanager.lua b/core/s2smanager.lua
index aabfddd6..92f07354 100644
--- a/core/s2smanager.lua
+++ b/core/s2smanager.lua
@@ -504,6 +504,8 @@ function mark_connected(session)
end
end
+local function null_data_handler(conn, data) log("debug", "Discarding data from destroyed s2s session: %s", data); end
+
function destroy_session(session, reason)
(session.log or log)("info", "Destroying "..tostring(session.direction).." session "..tostring(session.from_host).."->"..tostring(session.to_host));
@@ -519,6 +521,7 @@ function destroy_session(session, reason)
session[k] = nil;
end
end
+ session.data = null_data_handler;
end
return _M;
diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua
index 5e7fe06d..2dd0070b 100644
--- a/core/sessionmanager.lua
+++ b/core/sessionmanager.lua
@@ -10,7 +10,6 @@
local tonumber, tostring = tonumber, tostring;
local ipairs, pairs, print, next= ipairs, pairs, print, next;
-local collectgarbage = collectgarbage;
local format = import("string", "format");
local hosts = hosts;
@@ -25,6 +24,7 @@ local uuid_generate = require "util.uuid".generate;
local rm_load_roster = require "core.rostermanager".load_roster;
local config_get = require "core.configmanager".get;
local nameprep = require "util.encodings".stringprep.nameprep;
+local resourceprep = require "util.encodings".stringprep.resourceprep;
local fire_event = require "core.eventmanager".fire_event;
local add_task = require "util.timer".add_task;
@@ -66,6 +66,8 @@ function new_session(conn)
return session;
end
+local function null_data_handler(conn, data) log("debug", "Discarding data from destroyed c2s session: %s", data); end
+
function destroy_session(session, err)
(session.log or log)("info", "Destroying session for %s (%s@%s)", session.full_jid or "(unknown)", session.username or "(unknown)", session.host or "(unknown)");
@@ -88,6 +90,7 @@ function destroy_session(session, err)
session[k] = nil;
end
end
+ session.data = null_data_handler;
end
function make_authenticated(session, username)
@@ -106,7 +109,8 @@ function bind_resource(session, resource)
if session.resource then return nil, "cancel", "already-bound", "Cannot bind multiple resources on a single connection"; end
-- We don't support binding multiple resources
- resource = resource or uuid_generate();
+ resource = resourceprep(resource);
+ resource = resource ~= "" and resource or uuid_generate();
--FIXME: Randomly-generated resources must be unique per-user, and never conflict with existing
if not hosts[session.host].sessions[session.username] then
diff --git a/core/stanza_router.lua b/core/stanza_router.lua
index 00c37ed7..b5b1b45f 100644
--- a/core/stanza_router.lua
+++ b/core/stanza_router.lua
@@ -36,12 +36,14 @@ function core_process_stanza(origin, stanza)
end
end
- if origin.type == "c2s" then
+ if origin.type == "c2s" and stanza.attr.xmlns == "jabber:client" then
if not origin.full_jid
and not(stanza.name == "iq" and stanza.attr.type == "set" and stanza.tags[1] and stanza.tags[1].name == "bind"
and stanza.tags[1].attr.xmlns == "urn:ietf:params:xml:ns:xmpp-bind") then
-- authenticated client isn't bound and current stanza is not a bind request
- origin.send(st.error_reply(stanza, "auth", "not-authorized")); -- FIXME maybe allow stanzas to account or server
+ if stanza.attr.type ~= "result" and stanza.attr.type ~= "error" then
+ origin.send(st.error_reply(stanza, "auth", "not-authorized")); -- FIXME maybe allow stanzas to account or server
+ end
return;
end
@@ -98,7 +100,7 @@ function core_process_stanza(origin, stanza)
return; -- FIXME what should we do here? does this work with subdomains?
end
end
- core_post_stanza(origin, stanza);
+ core_post_stanza(origin, stanza, origin.full_jid);
else
local h = hosts[stanza.attr.to or origin.host or origin.to_host];
if h then
@@ -119,7 +121,7 @@ function core_process_stanza(origin, stanza)
end
end
-function core_post_stanza(origin, stanza)
+function core_post_stanza(origin, stanza, preevents)
local to = stanza.attr.to;
local node, host, resource = jid_split(to);
local to_bare = node and (node.."@"..host) or host; -- bare JID
@@ -143,7 +145,7 @@ function core_post_stanza(origin, stanza)
end
local event_data = {origin=origin, stanza=stanza};
- if origin.full_jid == stanza.attr.from then -- c2s connection
+ if preevents then -- c2s connection
if hosts[origin.host].events.fire_event('pre-'..stanza.name..to_type, event_data) then return; end -- do preprocessing
end
local h = hosts[to_bare] or hosts[host or origin.host];
@@ -191,6 +193,6 @@ function core_route_stanza(origin, stanza)
log("debug", "Routing outgoing stanza for %s to %s", from_host, host);
send_s2s(from_host, host, stanza);
else
- log("warn", "received stanza from unhandled connection type: %s", origin.type);
+ log("warn", "received %s stanza from unhandled connection type: %s", tostring(stanza.name), tostring(origin.type));
end
end