Software /
code /
prosody
Changeset
3083:cb15fa9242f9
Merge with backout
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 21 May 2010 19:45:33 +0100 |
parents | 3071:39a870ae75d9 (diff) 3082:920cd9667c7b (current diff) |
children | 3084:9b17449fb5f4 |
files | plugins/mod_presence.lua |
diffstat | 119 files changed, 1135 insertions(+), 1033 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Fri May 21 19:44:31 2010 +0100 +++ b/.hgignore Fri May 21 19:45:33 2010 +0100 @@ -6,6 +6,7 @@ html/* prosody.lua prosody.cfg.lua +prosody.version config.unix *.patch *.orig
--- a/.hgtags Fri May 21 19:44:31 2010 +0100 +++ b/.hgtags Fri May 21 19:45:33 2010 +0100 @@ -36,3 +36,4 @@ 5ae3209fefa2c8dc1c53d08c2c1caa340b8ec542 0.5.2 1a99a3bf3ce6dbdfb362b7fd101d761fb3cc10af 0.6.0 81b4e738e4d321b78274132f63a9aec7007e64eb 0.6.1 +0395f2f34bd55a01ec7276884fb9a4e0051b0e7a 0.6.2
--- a/HACKERS Fri May 21 19:44:31 2010 +0100 +++ b/HACKERS Fri May 21 19:45:33 2010 +0100 @@ -5,6 +5,8 @@ information on these at http://prosody.im/discuss Patches are welcome, though before sending we would appreciate if you read -docs/coding_style.txt for guidelines on how to format your code, and are -comfortable with copyright of contributions being assigned to the core -developers. +docs/coding_style.txt for guidelines on how to format your code, and other tips. + +Documentation for developers can be found at http://prosody.im/doc/developers + +Have fun :)
--- a/Makefile Fri May 21 19:44:31 2010 +0100 +++ b/Makefile Fri May 21 19:45:33 2010 +0100 @@ -21,7 +21,7 @@ install -m750 -d $(DATA) install -d $(MAN)/man1 install -d $(CONFIG)/certs - install -d $(SOURCE)/core $(SOURCE)/net $(SOURCE)/util $(SOURCE)/fallbacks + install -d $(SOURCE)/core $(SOURCE)/net $(SOURCE)/util install -m755 ./prosody.install $(BIN)/prosody install -m755 ./prosodyctl.install $(BIN)/prosodyctl install -m644 core/* $(SOURCE)/core @@ -30,7 +30,6 @@ install -m644 util/*.so $(SOURCE)/util install -d $(SOURCE)/util/sasl install -m644 util/sasl/* $(SOURCE)/util/sasl - install -m644 fallbacks/* $(SOURCE)/fallbacks install -m644 plugins/*.lua $(MODULES) install -d $(MODULES)/muc install -m644 plugins/muc/* $(MODULES)/muc
--- a/README Fri May 21 19:44:31 2010 +0100 +++ b/README Fri May 21 19:45:33 2010 +0100 @@ -32,6 +32,6 @@ ## Installation See the accompanying INSTALL file for help on building Prosody from source. Alternatively -see our guide at http://prosody.im/install +see our guide at http://prosody.im/doc/install
--- a/TODO Fri May 21 19:44:31 2010 +0100 +++ b/TODO Fri May 21 19:45:33 2010 +0100 @@ -1,5 +1,16 @@ -- Ad-hoc commands -- Clustering +== 0.8 == +- Ad-hoc commands: + http://code.google.com/p/prosody-modules/wiki/mod_adhoc + http://code.google.com/p/prosody-modules/wiki/mod_adhoc_cmd_admin + http://code.google.com/p/prosody-modules/wiki/mod_adhoc_cmd_ping + http://code.google.com/p/prosody-modules/wiki/mod_adhoc_cmd_uptime + - Pubsub +- Data storage backend abstraction +== 0.9 == +- Clustering +== 1.0 == +- Web interface? +- World domination
--- a/configure Fri May 21 19:44:31 2010 +0100 +++ b/configure Fri May 21 19:45:33 2010 +0100 @@ -61,7 +61,7 @@ while [ "$1" ] do - value="`echo $1 | sed 's/.*=\(.*\)/\1/'`" + value="`echo $1 | sed 's/[^=]*=\(.*\)/\1/'`" if echo "$value" | grep -q "~" then echo
--- a/core/certmanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/certmanager.lua Fri May 21 19:45:33 2010 +0100 @@ -3,7 +3,7 @@ local ssl = ssl; local ssl_newcontext = ssl and ssl.newcontext; -local setmetatable = setmetatable; +local setmetatable, tostring = setmetatable, tostring; local prosody = prosody; @@ -39,8 +39,10 @@ reason = "Check that the path is correct, and the file exists."; elseif reason == "system lib" then reason = "Previous error (see logs), or other system error."; + elseif reason == "(null)" or not reason then + reason = "Check that the file exists and the permissions are correct"; else - reason = "Reason: "..tostring(reason or "unknown"):lower(); + reason = "Reason: "..tostring(reason):lower(); end log("error", "SSL/TLS: Failed to load %s: %s", file, reason); else @@ -54,7 +56,7 @@ end function reload_ssl_config() - default_ssl_config = config.get("*", "core", "ssl"); + default_ssl_config = configmanager.get("*", "core", "ssl"); end prosody.events.add_handler("config-reloaded", reload_ssl_config);
--- a/core/componentmanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/componentmanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/core/configmanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/configmanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -112,7 +112,7 @@ function parsers.lua.load(data, filename) local env; -- The ' = true' are needed so as not to set off __newindex when we assign the functions below - env = setmetatable({ Host = true; host = true; Component = true, component = true, + env = setmetatable({ Host = true, host = true, VirtualHost = true, Component = true, component = true, Include = true, include = true, RunScript = dofile }, { __index = function (t, k) return rawget(_G, k) or function (settings_table) @@ -124,7 +124,7 @@ end}); rawset(env, "__currenthost", "*") -- Default is global - function env.Host(name) + function env.VirtualHost(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); @@ -133,7 +133,7 @@ -- Needs at least one setting to logically exist :) set(name or "*", "core", "defined", true); end - env.host = env.Host; + env.Host, env.host = env.VirtualHost, env.VirtualHost; function env.Component(name) if rawget(config, name) and rawget(config[name].core, "defined") and not rawget(config[name].core, "component_module") then
--- a/core/eventmanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/eventmanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/core/hostmanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/hostmanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -42,7 +42,7 @@ 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."); + log("error", "No active VirtualHost entries in the config file. This may cause unexpected behaviour as no modules will be loaded."); end eventmanager.fire_event("hosts-activated", defined_hosts); @@ -60,8 +60,8 @@ dialback_secret = configmanager.get(host, "core", "dialback_secret") or uuid_gen(); }; for option_name in pairs(host_config.core) do - if option_name:match("_ports$") then - log("warn", "%s: Option '%s' has no effect for virtual hosts - put it in global Host \"*\" instead", host, option_name); + if option_name:match("_ports$") or option_name:match("_interface$") then + log("warn", "%s: Option '%s' has no effect for virtual hosts - put it in the server-wide section instead", host, option_name); end end
--- a/core/loggingmanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/loggingmanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -33,9 +33,9 @@ module "loggingmanager" -- The log config used if none specified in the config file -local default_logging = { { to = "console" } }; +local default_logging = { { to = "console" , levels = { min = (debug_mode and "debug") or "info" } } }; local default_file_logging = { { to = "file", levels = { min = (debug_mode and "debug") or "info" }, timestamps = true } }; -local default_timestamp = "%b %d %T"; +local default_timestamp = "%b %d %H:%M:%S"; -- The actual config loggingmanager is using local logging_config = config.get("*", "core", "log") or default_logging;
--- a/core/modulemanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/modulemanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -19,7 +19,7 @@ local hosts = hosts; local prosody = prosody; -local loadfile, pcall = loadfile, pcall; +local loadfile, pcall, xpcall = loadfile, pcall, xpcall; local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv; local pairs, ipairs = pairs, ipairs; local t_insert, t_concat = table.insert, table.concat; @@ -29,6 +29,14 @@ local error = error; local tostring, tonumber = tostring, tonumber; +local debug_traceback = debug.traceback; +local unpack, select = unpack, select; +pcall = function(f, ...) + local n = select("#", ...); + local params = {...}; + return xpcall(function() f(unpack(params, 1, n)) end, function(e) return tostring(e).."\n"..debug_traceback(); end); +end + local array, set = require "util.array", require "util.set"; local autoload_modules = {"presence", "message", "iq"}; @@ -158,7 +166,7 @@ log("error", "Error initializing module '%s' on '%s': %s", module_name, host, err or "nil"); end if success then - hosts[host].events.fire_event("module-loaded", { module = module_name, host = host }); + (hosts[api_instance.host] or prosody).events.fire_event("module-loaded", { module = module_name, host = host }); return true; else -- load failed, unloading unload(api_instance.host, module_name); @@ -210,7 +218,7 @@ end end modulemap[host][name] = nil; - hosts[host].events.fire_event("module-unloaded", { module = name, host = host }); + (hosts[host] or prosody).events.fire_event("module-unloaded", { module = name, host = host }); return true; end @@ -274,7 +282,7 @@ (handlers[1])(origin, stanza); return true; else - if stanza.attr.xmlns == "jabber:client" then + if stanza.attr.xmlns == nil then log("debug", "Unhandled %s stanza: %s; xmlns=%s", origin.type, stanza.name, xmlns); -- we didn't handle it if stanza.attr.type ~= "error" and stanza.attr.type ~= "result" then origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
--- a/core/offlinemanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/offlinemanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/core/rostermanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/rostermanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -114,8 +114,14 @@ --end end if roster then - if not roster[false] then roster[false] = {}; end - roster[false].version = (roster[false].version or 0) + 1; + local metadata = roster[false]; + if not metadata then + metadata = {}; + roster[false] = metadata; + end + if metadata.version ~= true then + metadata.version = (metadata.version or 0) + 1; + end return datamanager.store(username, host, "roster", roster); end log("warn", "save_roster: user had no roster to save");
--- a/core/s2smanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/s2smanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -16,8 +16,10 @@ local format = string.format; local t_insert, t_sort = table.insert, table.sort; local get_traceback = debug.traceback; -local tostring, pairs, ipairs, getmetatable, newproxy, error, tonumber - = tostring, pairs, ipairs, getmetatable, newproxy, error, tonumber; +local tostring, pairs, ipairs, getmetatable, newproxy, error, tonumber, + setmetatable + = tostring, pairs, ipairs, getmetatable, newproxy, error, tonumber, + setmetatable; local idna_to_ascii = require "util.encodings".idna.to_ascii; local connlisteners_get = require "net.connlisteners".get; @@ -48,7 +50,9 @@ module "s2smanager" -local function compare_srv_priorities(a,b) return a.priority < b.priority or a.weight < b.weight; end +function compare_srv_priorities(a,b) + return a.priority < b.priority or (a.priority == b.priority and a.weight > b.weight); +end local function bounce_sendq(session, reason) local sendq = session.sendq; @@ -64,7 +68,7 @@ for i, data in ipairs(sendq) do local reply = data[2]; local xmlns = reply.attr.xmlns; - if not xmlns or xmlns == "jabber:client" or xmlns == "jabber:server" then + if not xmlns then reply.attr.type = "error"; reply:tag("error", {type = "cancel"}) :tag("remote-server-not-found", {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"}):up(); @@ -87,7 +91,7 @@ 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 (data.name ~= "db:verify" or not host.dialback_key) and ((not data.xmlns) or data.xmlns == "jabber:client" or data.xmlns == "jabber:server") then + if host.type == "s2sout_unauthed" and (data.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 @@ -301,7 +305,7 @@ end function make_connect(host_session, connect_host, connect_port) - host_session.log("info", "Beginning new connection attempt to %s (%s:%d)", host_session.to_host, connect_host, connect_port); + (host_session.log or log)("info", "Beginning new connection attempt to %s (%s:%d)", host_session.to_host, connect_host, connect_port); -- Ok, we're going to try to connect local from_host, to_host = host_session.from_host, host_session.to_host; @@ -365,11 +369,6 @@ session.secure = true; end - if session.version >= 1.0 and not (attr.to and attr.from) then - (session.log or log)("warn", "Remote of stream "..(session.from_host or "(unknown)").."->"..(session.to_host or "(unknown)") - .." failed to specify to (%s) and/or from (%s) hostname as per RFC", tostring(attr.to), tostring(attr.from)); - end - if session.direction == "incoming" then -- Send a reply stream header session.to_host = attr.to and nameprep(attr.to); @@ -430,11 +429,8 @@ end function streamclosed(session) - (session.log or log)("debug", "</stream:stream>"); - if session.sends2s then - session.sends2s("</stream:stream>"); - end - session.notopen = true; + (session.log or log)("debug", "Received </stream:stream>"); + session:close(); end function initiate_dialback(session) @@ -508,9 +504,32 @@ end end -local function null_data_handler(conn, data) log("debug", "Discarding data from destroyed s2s session: %s", data); end +local resting_session = { -- Resting, not dead + destroyed = true; + type = "s2s_destroyed"; + open_stream = function (session) + session.log("debug", "Attempt to open stream on resting session"); + end; + close = function (session) + session.log("debug", "Attempt to close already-closed session"); + end; + }; resting_session.__index = resting_session; + +function retire_session(session) + local log = session.log or log; + for k in pairs(session) do + if k ~= "trace" and k ~= "log" and k ~= "id" then + session[k] = nil; + end + end + + function session.send(data) log("debug", "Discarding data sent to resting session: %s", tostring(data)); end + function session.data(data) log("debug", "Discarding data received from resting session: %s", tostring(data)); end + return setmetatable(session, resting_session); +end function destroy_session(session, reason) + if session.destroyed then return; end (session.log or log)("info", "Destroying "..tostring(session.direction).." session "..tostring(session.from_host).."->"..tostring(session.to_host)); if session.direction == "outgoing" then @@ -520,12 +539,7 @@ incoming_s2s[session] = nil; end - for k in pairs(session) do - if k ~= "trace" then - session[k] = nil; - end - end - session.data = null_data_handler; + retire_session(session); -- Clean session until it is GC'd end return _M;
--- a/core/sessionmanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/sessionmanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -8,7 +8,7 @@ -local tonumber, tostring = tonumber, tostring; +local tonumber, tostring, setmetatable = tonumber, tostring, setmetatable; local ipairs, pairs, print, next= ipairs, pairs, print, next; local format = import("string", "format"); @@ -66,10 +66,30 @@ return session; end -local function null_data_handler(conn, data) log("debug", "Discarding data from destroyed c2s session: %s", data); end +local resting_session = { -- Resting, not dead + destroyed = true; + type = "c2s_destroyed"; + close = function (session) + session.log("debug", "Attempt to close already-closed session"); + end; + }; resting_session.__index = resting_session; + +function retire_session(session) + local log = session.log or log; + for k in pairs(session) do + if k ~= "trace" and k ~= "log" and k ~= "id" then + session[k] = nil; + end + end + + function session.send(data) log("debug", "Discarding data sent to resting session: %s", tostring(data)); end + function session.data(data) log("debug", "Discarding data received from resting session: %s", tostring(data)); end + return setmetatable(session, resting_session); +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)"); + if session.destroyed then return; end -- Remove session/resource from user's session list if session.full_jid then @@ -85,12 +105,7 @@ hosts[session.host].events.fire_event("resource-unbind", {session=session, error=err}); end - for k in pairs(session) do - if k ~= "trace" then - session[k] = nil; - end - end - session.data = null_data_handler; + retire_session(session); end function make_authenticated(session, username) @@ -168,7 +183,12 @@ function streamopened(session, attr) local send = session.send; - session.host = attr.to or error("Client failed to specify destination hostname"); + 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(); @@ -201,8 +221,8 @@ end function streamclosed(session) - session.send("</stream:stream>"); - session.notopen = true; + session.log("debug", "Received </stream:stream>"); + session:close(); end function send_to_available_resources(user, host, stanza)
--- a/core/stanza_router.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/stanza_router.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -23,9 +23,6 @@ function core_process_stanza(origin, stanza) (origin.log or log)("debug", "Received[%s]: %s", origin.type, stanza:top_tag()) - -- Currently we guarantee every stanza to have an xmlns, should we keep this rule? - if not stanza.attr.xmlns then stanza.attr.xmlns = "jabber:client"; end - -- TODO verify validity of stanza (as well as JID validity) if stanza.attr.type == "error" and #stanza.tags == 0 then return; end -- TODO invalid stanza, log if stanza.name == "iq" then @@ -36,12 +33,14 @@ end end - if origin.type == "c2s" then + if origin.type == "c2s" and not stanza.attr.xmlns then if not origin.full_jid and not(stanza.name == "iq" and stanza.attr.type == "set" and stanza.tags[1] and stanza.tags[1].name == "bind" and 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 @@ -90,7 +89,7 @@ return; -- FIXME what should we do here? end]] -- FIXME - if (origin.type == "s2sin" or origin.type == "c2s" or origin.type == "component") and xmlns == "jabber:client" then + if (origin.type == "s2sin" or origin.type == "c2s" or origin.type == "component") and xmlns == nil then if origin.type == "s2sin" and not origin.dummy then local host_status = origin.hosts[from_host]; if not host_status or not host_status.authed then -- remote server trying to impersonate some other server? @@ -103,14 +102,14 @@ local h = hosts[stanza.attr.to or origin.host or origin.to_host]; if h then local event; - if stanza.attr.xmlns == "jabber:client" then + if xmlns == nil then if stanza.name == "iq" and (stanza.attr.type == "set" or stanza.attr.type == "get") then event = "stanza/iq/"..stanza.tags[1].attr.xmlns..":"..stanza.tags[1].name; else event = "stanza/"..stanza.name; end else - event = "stanza/"..stanza.attr.xmlns..":"..stanza.name; + event = "stanza/"..xmlns..":"..stanza.name; end if h.events.fire_event(event, {origin = origin, stanza = stanza}) then return; end end @@ -140,6 +139,7 @@ to_type = '/host'; else to_type = '/bare'; + to_self = true; end end
--- a/core/usermanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/usermanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -14,11 +14,17 @@ local hashes = require "util.hashes"; local jid_bare = require "util.jid".bare; local config = require "core.configmanager"; +local hosts = hosts; + +local require_provisioning = config.get("*", "core", "cyrus_require_provisioning") or false; module "usermanager" +local function is_cyrus(host) return config.get(host, "core", "sasl_backend") == "cyrus"; end + function validate_credentials(host, username, password, method) log("debug", "User '%s' is being validated", username); + if is_cyrus(host) then return nil, "Legacy auth not supported with Cyrus SASL."; end local credentials = datamanager.load(username, host, "accounts") or {}; if method == nil then method = "PLAIN"; end @@ -48,14 +54,26 @@ end function get_password(username, host) - return (datamanager.load(username, host, "accounts") or {}).password + if is_cyrus(host) then return nil, "Passwords unavailable for Cyrus SASL."; end + return (datamanager.load(username, host, "accounts") or {}).password +end +function set_password(username, host, password) + if is_cyrus(host) then return nil, "Passwords unavailable for Cyrus SASL."; end + local account = datamanager.load(username, host, "accounts"); + if account then + account.password = password; + return datamanager.store(username, host, "accounts", account); + end + return nil, "Account not available."; end function user_exists(username, host) + if not(require_provisioning) and is_cyrus(host) then return true; end return datamanager.load(username, host, "accounts") ~= nil; -- FIXME also check for empty credentials end function create_user(username, password, host) + if not(require_provisioning) and is_cyrus(host) then return nil, "Account creation/modification not available with Cyrus SASL."; end return datamanager.store(username, host, "accounts", {password = password}); end
--- a/core/xmlhandlers.lua Fri May 21 19:44:31 2010 +0100 +++ b/core/xmlhandlers.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/fallbacks/bit.lua Fri May 21 19:44:31 2010 +0100 +++ b/fallbacks/bit.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/man/prosodyctl.man Fri May 21 19:44:31 2010 +0100 +++ b/man/prosodyctl.man Fri May 21 19:45:33 2010 +0100 @@ -49,6 +49,10 @@ Stops the \fBprosody\fP server daemon. This operation will block for up to five seconds to wait for the server to stop executing. +.IP \fBrestart\fP +Restarts the \fBprosody\fP server daemon. Equivalent to running \fBprosodyctl +stop\fP followed by \fBprosodyctl start\fP. + .IP \fBstatus\fP Prints the current execution status of the \fBprosody\fP server daemon. @@ -76,4 +80,4 @@ More information may be found online at: \fIhttp://prosody.im/\fP .SH AUTHORS -Dwayne Bent <dbb.0@liqd.org> +Dwayne Bent <dbb.1@liqd.org>
--- a/net/adns.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/adns.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -49,16 +49,20 @@ local listener = {}; local handler = {}; function listener.onincoming(conn, data) - dns.feed(handler, data); + if data then + dns.feed(handler, data); + end end function listener.ondisconnect(conn, err) - log("warn", "DNS socket for %s disconnected: %s", peername, err); - local servers = resolver.server; - if resolver.socketset[conn] == resolver.best_server and resolver.best_server == #servers then - log("error", "Exhausted all %d configured DNS servers, next lookup will try %s again", #servers, servers[1]); + if err then + log("warn", "DNS socket for %s disconnected: %s", peername, err); + local servers = resolver.server; + if resolver.socketset[conn] == resolver.best_server and resolver.best_server == #servers then + log("error", "Exhausted all %d configured DNS servers, next lookup will try %s again", #servers, servers[1]); + end + + resolver:servfail(conn); -- Let the magic commence end - - resolver:servfail(conn); -- Let the magic commence end handler = server.wrapclient(sock, "dns", 53, listener); if not handler then
--- a/net/connlisteners.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/connlisteners.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/net/dns.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/dns.lua Fri May 21 19:45:33 2010 +0100 @@ -532,14 +532,19 @@ if not self.server or #self.server == 0 then -- TODO log warning about no nameservers, adding opendns servers as fallback self:addnameserver("208.67.222.222"); - self:addnameserver("208.67.220.220") ; + self:addnameserver("208.67.220.220"); end else -- posix local resolv_conf = io.open("/etc/resolv.conf"); if resolv_conf then for line in resolv_conf:lines() do - local address = line:gsub("#.*$", ""):match('^%s*nameserver%s+(%d+%.%d+%.%d+%.%d+)%s*$'); - if address then self:addnameserver(address) end + line = line:gsub("#.*$", "") + :match('^%s*nameserver%s+(.*)%s*$'); + if line then + line:gsub("%f[%d.](%d+%.%d+%.%d+%.%d+)%f[^%d.]", function (address) + self:addnameserver(address) + end); + end end end if not self.server or #self.server == 0 then @@ -796,7 +801,7 @@ set(self.wanted, q.class, q.type, q.name, nil); end end - end + end return response; end @@ -846,7 +851,13 @@ function resolver:lookup(qname, qtype, qclass) -- - - - - - - - - - lookup self:query (qname, qtype, qclass) - while self:pulse() do socket.select(self.socket, nil, 4); end + while self:pulse() do + local recvt = {} + for i, s in ipairs(self.socket) do + recvt[i] = s + end + socket.select(recvt, nil, 4) + end --print(self.cache); return self:peek(qname, qtype, qclass); end
--- a/net/http.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/http.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -17,11 +17,10 @@ local listener = connlisteners_get("httpclient") or error("No httpclient listener!"); local t_insert, t_concat = table.insert, table.concat; -local tonumber, tostring, pairs, xpcall, select, debug_traceback, char, format = +local tonumber, tostring, pairs, xpcall, select, debug_traceback, char, format = tonumber, tostring, pairs, xpcall, select, debug.traceback, string.char, string.format; local log = require "util.logger".init("http"); -local print = function () end module "http" @@ -43,6 +42,7 @@ elseif request.state ~= "completed" then -- Error.. connection was closed prematurely request.callback("connection-closed", 0, request); + return; end destroy_request(request); request.body = nil; @@ -50,7 +50,7 @@ return; end if request.state == "body" and request.state ~= "completed" then - print("Reading body...") + log("debug", "Reading body...") if not request.body then request.body = {}; request.havebodylength, request.bodylength = 0, tonumber(request.responseheaders["content-length"]); end if startpos then data = data:sub(startpos, -1) @@ -67,42 +67,54 @@ request.body = nil; request.state = "completed"; else - print("", "Have "..request.havebodylength.." bytes out of "..request.bodylength); + log("debug", "Have "..request.havebodylength.." bytes out of "..request.bodylength); end end elseif request.state == "headers" then - print("Reading headers...") + log("debug", "Reading headers...") local pos = startpos; - local headers = request.responseheaders or {}; + local headers, headers_complete = request.responseheaders; + if not headers then + headers = {}; + request.responseheaders = headers; + end for line in data:sub(startpos, -1):gmatch("(.-)\r\n") do startpos = startpos + #line + 2; local k, v = line:match("(%S+): (.+)"); if k and v then headers[k:lower()] = v; - print("Header: "..k:lower().." = "..v); + --log("debug", "Header: "..k:lower().." = "..v); elseif #line == 0 then - request.responseheaders = headers; + headers_complete = true; break; else - print("Unhandled header line: "..line); + log("warn", "Unhandled header line: "..line); end end + if not headers_complete then return; end -- Reached the end of the headers - request.state = "body"; + if not expectbody(request, request.code) then + request.callback(nil, request.code, request); + return; + end + request.state = "body"; if #data > startpos then return request_reader(request, data, startpos); end elseif request.state == "status" then - print("Reading status...") + log("debug", "Reading status...") local http, code, text, linelen = data:match("^HTTP/(%S+) (%d+) (.-)\r\n()", startpos); code = tonumber(code); if not code then - return request.callback("invalid-status-line", 0, request); + log("warn", "Invalid HTTP status line, telling callback then closing"); + local ret = request.callback("invalid-status-line", 0, request); + destroy_request(request); + return ret; end request.code, request.responseversion = code, http; - if request.onlystatus or not expectbody(request, code) then + if request.onlystatus then if request.callback then request.callback(nil, code, request); end @@ -199,8 +211,9 @@ function destroy_request(request) if request.conn then - request.handler.close() - listener.ondisconnect(request.conn, "closed"); + request.conn = nil; + request.handler:close() + listener.ondisconnect(request.handler, "closed"); end end
--- a/net/httpclient_listener.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/httpclient_listener.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -30,7 +30,7 @@ function httpclient.ondisconnect(conn, err) local request = requests[conn]; - if request then + if request and err ~= "closed" then request:reader(nil); end requests[conn] = nil;
--- a/net/httpserver.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/httpserver.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/net/httpserver_listener.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/httpserver_listener.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -29,7 +29,7 @@ end end - if data then + if data and data ~= "" then request_reader(request, data); end end
--- a/net/server.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/server.lua Fri May 21 19:45:33 2010 +0100 @@ -1,3 +1,10 @@ +-- 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. +-- local use_luaevent = require "core.configmanager".get("*", "core", "use_libevent"); @@ -36,7 +43,6 @@ if type(signal_id) ~= "number" then return false, "invalid-signal"; end - --_signal_signal(signal_id, handler); return server.hook_signal(signal_id, handler); end end @@ -47,4 +53,4 @@ -- require "net.server" shall now forever return this, -- ie. server_select or server_event as chosen above. -return server; +return server;
--- a/net/server_event.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/server_event.lua Fri May 21 19:45:33 2010 +0100 @@ -20,14 +20,14 @@ local cfg = { MAX_CONNECTIONS = 100000, -- max per server connections (use "ulimit -n" on *nix) - MAX_HANDSHAKE_ATTEMPS = 10, -- attemps to finish ssl handshake - HANDSHAKE_TIMEOUT = 1, -- timout in seconds per handshake attemp + MAX_HANDSHAKE_ATTEMPS = 1000, -- attempts to finish ssl handshake + HANDSHAKE_TIMEOUT = 60, -- timout in seconds per handshake attempt MAX_READ_LENGTH = 1024 * 1024 * 1024 * 1024, -- max bytes allowed to read from sockets MAX_SEND_LENGTH = 1024 * 1024 * 1024 * 1024, -- max bytes size of write buffer (for writing on sockets) - ACCEPT_DELAY = 10, -- seconds to wait until the next attemp of a full server to accept - READ_TIMEOUT = 60 * 30, -- timeout in seconds for read data from socket - WRITE_TIMEOUT = 30, -- timeout in seconds for write data on socket - CONNECT_TIMEOUT = 10, -- timeout in seconds for connection attemps + ACCEPT_DELAY = 10, -- seconds to wait until the next attempt of a full server to accept + READ_TIMEOUT = 60 * 60 * 6, -- timeout in seconds for read data from socket + WRITE_TIMEOUT = 180, -- timeout in seconds for write data on socket + CONNECT_TIMEOUT = 20, -- timeout in seconds for connection attempts CLEAR_DELAY = 5, -- seconds to wait for clearing interface list (and calling ondisconnect listeners) DEBUG = true, -- show debug messages } @@ -160,8 +160,8 @@ local callback = function( ) self:_lock( false, false, false ) --vdebug( "start listening on client socket with id:", self.id ) - self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ) -- register callback - self:onincoming() + self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ); -- register callback + self:onconnect() self.eventsession = nil return -1 end @@ -197,7 +197,7 @@ local _, err local attempt = 0 local maxattempt = cfg.MAX_HANDSHAKE_ATTEMPS - while attempt < 1000 do -- no endless loop + while attempt < maxattempt do -- no endless loop attempt = attempt + 1 debug( "ssl handshake of client with id:"..tostring(self).."attemp:"..attempt ) if attempt > maxattempt then @@ -262,7 +262,7 @@ _ = self.eventsession and self.eventsession:close( ) _ = self.eventwritetimeout and self.eventwritetimeout:close( ) _ = self.eventreadtimeout and self.eventreadtimeout:close( ) - _ = self.ondisconnect and self:ondisconnect( self.fatalerror ) -- call ondisconnect listener (wont be the case if handshake failed on connect) + _ = self.ondisconnect and self:ondisconnect( self.fatalerror ~= "client to close" and self.fatalerror) -- call ondisconnect listener (wont be the case if handshake failed on connect) _ = self.conn and self.conn:close( ) -- close connection, must also be called outside of any socket registered events! _ = self._server and self._server:counter(-1); self.eventread, self.eventwrite = nil, nil @@ -281,6 +281,23 @@ self.nointerface, self.noreading, self.nowriting = nointerface, noreading, nowriting return nointerface, noreading, nowriting end + + --TODO: Deprecate + function interface_mt:lock_read(switch) + if switch then + return self:pause(); + else + return self:resume(); + end + end + + function interface_mt:pause() + return self:_lock(self.nointerface, true, self.nowriting); + end + + function interface_mt:resume() + return self:_lock(self.nointerface, false, self.nowriting); + end function interface_mt:counter(c) if c then @@ -385,6 +402,13 @@ self.starttls = false; -- prevent starttls() end end + + function interface_mt:set_mode(pattern) + if pattern then + self._pattern = pattern; + end + return self._pattern; + end function interface_mt:set_send(new_send) -- No-op, we always use the underlying connection's send @@ -433,6 +457,7 @@ -- Stub handlers function interface_mt:onconnect() + return self:onincoming(nil); end function interface_mt:onincoming() end @@ -440,6 +465,8 @@ end function interface_mt:ontimeout() end + function interface_mt:ondrain() + end function interface_mt:onstatus() debug("server.lua: Dummy onstatus()") end @@ -520,6 +547,7 @@ if succ then -- writing succesful interface.writebuffer = "" interface.writebufferlen = 0 + interface:ondrain(); if interface.fatalerror then debug "closing client after writing" interface:_close() -- close interface if needed @@ -531,7 +559,7 @@ end interface.eventwrite = nil return -1 - elseif byte then -- want write again + elseif byte and (err == "timeout" or err == "wantwrite") then -- want write again --vdebug( "writebuffer is not empty:", err ) interface.writebuffer = string_sub( interface.writebuffer, byte + 1, interface.writebufferlen ) -- new buffer interface.writebufferlen = interface.writebufferlen - byte @@ -539,7 +567,7 @@ local callback = function( ) interface:_close() interface.eventwritetimeout = nil - return evreturn, evtimeout + return -1; end interface.eventwritetimeout = addevent( base, nil, EV_TIMEOUT, callback, cfg.WRITE_TIMEOUT ) -- reg a new timeout event debug( "wantread during write attemp, reg it in readcallback but dont know what really happens next..." ) @@ -581,7 +609,7 @@ interface.eventreadtimeout = nil end end - local buffer, err, part = interface.conn:receive( pattern ) -- receive buffer with "pattern" + local buffer, err, part = interface.conn:receive( interface._pattern ) -- receive buffer with "pattern" --vdebug( "read data:", tostring(buffer), "error:", tostring(err), "part:", tostring(part) ) buffer = buffer or part or "" local len = string_len( buffer ) @@ -667,16 +695,16 @@ debug( "maximal connections reached, refuse client connection; accept delay:", delay ) return EV_TIMEOUT, delay -- delay for next accept attemp end - local ip, port = client:getpeername( ) + local client_ip, client_port = client:getpeername( ) interface._connections = interface._connections + 1 -- increase connection count - local clientinterface = handleclient( client, ip, port, interface, pattern, listener, nil, sslctx ) + local clientinterface = handleclient( client, client_ip, client_port, interface, pattern, listener, nil, sslctx ) --vdebug( "client id:", clientinterface, "startssl:", startssl ) if ssl and sslctx then clientinterface:starttls(sslctx) else clientinterface:_start_session( clientinterface.onconnect ) end - debug( "accepted incoming client connection from:", ip, port ) + debug( "accepted incoming client connection from:", client_ip or "<unknown IP>", client_port or "<unknown port>", "to", port or "<unknown port>"); client, err = server:accept() -- try to accept again end @@ -758,7 +786,7 @@ local server = function( ) return nil, "this is a dummy server interface" end - local interface = wrapclient( client, ip, serverport, listeners, pattern, sslctx, startssl ) + local interface = wrapclient( client, ip, serverport, listener, pattern, sslctx, startssl ) interface:_start_connection( startssl ) debug( "new connection id:", interface.id ) return interface, err @@ -817,11 +845,32 @@ return signal_events[signal_num]; end +local function link(sender, receiver, buffersize) + sender:set_mode(buffersize); + local sender_locked; + + function receiver:ondrain() + if sender_locked then + sender:resume(); + sender_locked = nil; + end + end + + function sender:onincoming(data) + receiver:write(data); + if receiver.writebufferlen >= buffersize then + sender_locked = true; + sender:pause(); + end + end +end + return { cfg = cfg, base = base, loop = loop, + link = link, event = event, event_base = base, addevent = newevent,
--- a/net/server_select.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/server_select.lua Fri May 21 19:45:33 2010 +0100 @@ -2,7 +2,7 @@ -- server.lua by blastbeat of the luadch project -- Re-used here under the MIT/X Consortium License -- --- Modifications (C) 2008-2009 Matthew Wild, Waqas Hussain +-- Modifications (C) 2008-2010 Matthew Wild, Waqas Hussain -- -- // wrapping luadch stuff // -- @@ -252,6 +252,7 @@ local dispatch = listeners.onincoming local status = listeners.onstatus local disconnect = listeners.ondisconnect + local drain = listeners.ondrain local bufferqueue = { } -- buffer array local bufferqueuelen = 0 -- end of buffer array @@ -284,6 +285,7 @@ dispatch = listeners.onincoming disconnect = listeners.ondisconnect status = listeners.onstatus + drain = listeners.ondrain end handler.getstats = function( ) return readtraffic, sendtraffic @@ -379,7 +381,7 @@ handler.socket = function( self ) return socket end - handler.pattern = function( self, new ) + handler.set_mode = function( self, new ) pattern = new or pattern return pattern end @@ -392,6 +394,7 @@ maxreadlen = readlen or maxreadlen return bufferlen, maxreadlen, maxsendlen end + --TODO: Deprecate handler.lock_read = function (self, switch) if switch == true then local tmp = _readlistlen @@ -409,6 +412,12 @@ end return noread end + handler.pause = function (self) + return self:lock_read(true); + end + handler.resume = function (self) + return self:lock_read(false); + end handler.lock = function( self, switch ) handler.lock_read (switch) if switch == true then @@ -430,12 +439,12 @@ end local _readbuffer = function( ) -- this function reads data local buffer, err, part = receive( socket, pattern ) -- receive buffer with "pattern" - if not err or (err == "wantread" or err == "timeout") or string_len(part) > 0 then -- received something + if not err or (err == "wantread" or err == "timeout") then -- received something local buffer = buffer or part or "" local len = string_len( buffer ) if len > maxreadlen then disconnect( handler, "receive buffer exceeded" ) - handler.close( true ) + handler:close( true ) return false end local count = len * STAT_UNIT @@ -448,7 +457,7 @@ out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) ) fatalerror = true disconnect( handler, err ) - _ = handler and handler.close( ) + _ = handler and handler:close( ) return false end end @@ -472,7 +481,10 @@ _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) -- delete socket from writelist _ = needtls and handler:starttls(nil, true) _writetimes[ handler ] = nil - _ = toclose and handler.close( ) + if drain then + drain(handler) + end + _ = toclose and handler:close( ) return true elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer @@ -485,7 +497,7 @@ out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) ) fatalerror = true disconnect( handler, err ) - _ = handler and handler.close( ) + _ = handler and handler:close( ) return false end end @@ -611,7 +623,16 @@ _socketlist[ socket ] = handler _readlistlen = addsocket(_readlist, socket, _readlistlen) - + if listeners.onconnect then + _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) + handler.sendbuffer = function () + listeners.onconnect(handler); + handler.sendbuffer = _sendbuffer; + if bufferqueuelen > 0 then + return _sendbuffer(); + end + end + end return handler, socket end @@ -654,6 +675,28 @@ --mem_free( ) end +local function link(sender, receiver, buffersize) + sender:set_mode(buffersize); + local sender_locked; + local _sendbuffer = receiver.sendbuffer; + function receiver.sendbuffer() + _sendbuffer(); + if sender_locked and receiver.bufferlen() < buffersize then + sender:lock_read(false); -- Unlock now + sender_locked = nil; + end + end + + local _readbuffer = sender.readbuffer; + function sender.readbuffer() + _readbuffer(); + if not sender_locked and receiver.bufferlen() >= buffersize then + sender_locked = true; + sender:lock_read(true); + end + end +end + ----------------------------------// PUBLIC //-- addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server @@ -661,7 +704,7 @@ if type( listeners ) ~= "table" then err = "invalid listener table" end - if not type( port ) == "number" or not ( port >= 0 and port <= 65535 ) then + if type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then err = "invalid port" elseif _server[ port ] then err = "listeners on port '" .. port .. "' already exist" @@ -877,6 +920,7 @@ wrapclient = wrapclient, loop = loop, + link = link, stats = stats, closeall = closeall, addtimer = addtimer,
--- a/net/xmppclient_listener.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/xmppclient_listener.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -33,13 +33,32 @@ local stream_callbacks = { default_ns = "jabber:client", streamopened = sm_streamopened, streamclosed = sm_streamclosed, handlestanza = core_process_stanza }; +local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; + function stream_callbacks.error(session, error, data) if error == "no-stream" then session.log("debug", "Invalid opening stream header"); session:close("invalid-namespace"); - elseif session.close then - (session.log or log)("debug", "Client XML parse error: %s", tostring(error)); + elseif error == "parse-error" then + (session.log or log)("debug", "Client XML parse error: %s", tostring(data)); session:close("xml-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
--- a/net/xmppcomponent_listener.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/xmppcomponent_listener.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -34,16 +34,33 @@ 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 log("warn", "Error processing component stream: "..tostring(error)); if error == "no-stream" then session:close("invalid-namespace"); - elseif error == "xml-parse-error" and data == "unexpected-element-close" then - session.log("warn", "Unexpected close of '%s' tag", data2); + elseif error == "parse-error" then + session.log("warn", "External component %s XML parse error: %s", tostring(session.host), tostring(data)); session:close("xml-not-well-formed"); - else - session.log("warn", "External component %s XML parse error: %s", tostring(session.host), tostring(error)); - session:close("xml-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 @@ -71,8 +88,8 @@ end function stream_callbacks.streamclosed(session) - session.send("</stream:stream>"); - session.notopen = true; + session.log("Received </stream:stream>"); + session:close(); end local core_process_stanza = core_process_stanza; @@ -89,6 +106,7 @@ 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 @@ -146,6 +164,7 @@ function session.data(conn, data) local ok, err = parser:parse(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("xml-not-well-formed"); end @@ -167,7 +186,12 @@ hosts[session.host].connected = nil; end sessions[conn] = nil; - for k in pairs(session) do session[k] = nil; end + 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
--- a/net/xmppserver_listener.lua Fri May 21 19:44:31 2010 +0100 +++ b/net/xmppserver_listener.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -50,6 +50,9 @@ local function handleerr(err) log("error", "Traceback[s2s]: %s: %s", tostring(err), debug.traceback()); end function stream_callbacks.handlestanza(a, b) + if b.attr.xmlns == "jabber:client" then --COMPAT: Prosody pre-0.6.2 may send jabber:client + b.attr.xmlns = nil; + end xpcall(function () core_process_stanza(a, b) end, handleerr); end @@ -176,7 +179,7 @@ return; -- 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)); + (session.log or log)("info", "s2s disconnected: %s->%s (%s)", tostring(session.from_host), tostring(session.to_host), tostring(err or "closed")); s2s_destroy_session(session, err); sessions[conn] = nil; session = nil;
--- a/plugins/mod_announce.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_announce.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_bosh.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_bosh.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -23,7 +23,7 @@ local log = logger.init("mod_bosh"); local xmlns_bosh = "http://jabber.org/protocol/httpbind"; -- (hard-coded into a literal in session.send) -local stream_callbacks = { stream_ns = "http://jabber.org/protocol/httpbind", stream_tag = "body", default_ns = xmlns_bosh }; +local stream_callbacks = { stream_ns = "http://jabber.org/protocol/httpbind", stream_tag = "body", default_ns = "jabber:client" }; local BOSH_DEFAULT_HOLD = tonumber(module:get_option("bosh_default_hold")) or 1; local BOSH_DEFAULT_INACTIVITY = tonumber(module:get_option("bosh_max_inactivity")) or 60; @@ -31,6 +31,8 @@ local BOSH_DEFAULT_REQUESTS = tonumber(module:get_option("bosh_max_requests")) or 2; local BOSH_DEFAULT_MAXPAUSE = tonumber(module:get_option("bosh_max_pause")) or 300; +local consider_bosh_secure = module:get_option_boolean("consider_bosh_secure"); + local default_headers = { ["Content-Type"] = "text/xml; charset=utf-8" }; local session_close_reply = { headers = default_headers, body = st.stanza("body", { xmlns = xmlns_bosh, type = "terminate" }), attr = {} }; @@ -63,8 +65,11 @@ local session = sessions[request.sid]; if session then local requests = session.requests; - for i,r in pairs(requests) do - if r == request then requests[i] = nil; break; end + for i,r in ipairs(requests) do + if r == request then + t_remove(requests, i); + break; + end end -- If this session now has no requests open, mark it as inactive @@ -90,6 +95,8 @@ --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 parser = lxp.new(init_xmlhandlers(request, stream_callbacks), "\1"); parser:parse(body); @@ -118,14 +125,21 @@ session.send(resp); end - if not request.destroyed and session.bosh_wait then - request.reply_before = os_time() + session.bosh_wait; - request.on_destroy = on_destroy_request; - waiting_requests[request] = true; + if not request.destroyed 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 + request.reply_before = os_time() + session.bosh_wait; + waiting_requests[request] = true; + end + if inactive_sessions[session] then + -- Session was marked as inactive, since we have + -- a request open now, unmark it + inactive_sessions[session] = nil; + end end - log("debug", "Have nothing to say, so leaving request unanswered for now"); - return true; + return true; -- Inform httpserver we shall reply later end end @@ -162,10 +176,14 @@ -- New session sid = new_uuid(); - local session = { type = "c2s_unauthed", conn = {}, sid = sid, rid = tonumber(attr.rid), host = attr.to, bosh_version = attr.ver, bosh_wait = attr.wait, streamid = sid, - bosh_hold = BOSH_DEFAULT_HOLD, bosh_max_inactive = BOSH_DEFAULT_INACTIVITY, - requests = { }, send_buffer = {}, reset_stream = bosh_reset_stream, close = bosh_close_stream, - dispatch_stanza = core_process_stanza, log = logger.init("bosh"..sid), secure = request.secure }; + local session = { + type = "c2s_unauthed", conn = {}, sid = sid, rid = tonumber(attr.rid)-1, host = attr.to, + bosh_version = attr.ver, bosh_wait = attr.wait, streamid = sid, + bosh_hold = BOSH_DEFAULT_HOLD, bosh_max_inactive = BOSH_DEFAULT_INACTIVITY, + requests = { }, send_buffer = {}, reset_stream = bosh_reset_stream, + close = bosh_close_stream, dispatch_stanza = core_process_stanza, + log = logger.init("bosh"..sid), secure = consider_bosh_secure or request.secure + }; sessions[sid] = session; log("info", "New BOSH session, assigned it sid '%s'", sid); @@ -174,11 +192,6 @@ function session.send(s) --log("debug", "Sending BOSH data: %s", tostring(s)); local oldest_request = r[1]; - while oldest_request and oldest_request.destroyed do - t_remove(r, 1); - waiting_requests[oldest_request] = nil; - oldest_request = r[1]; - end if oldest_request then log("debug", "We have an open request, so sending on that"); response.body = t_concat{"<body xmlns='http://jabber.org/protocol/httpbind' sid='", sid, "' xmlns:stream = 'http://etherx.jabber.org/streams'>", tostring(s), "</body>" }; @@ -193,7 +206,6 @@ else log("debug", "Destroying the request now..."); oldest_request:destroy(); - t_remove(r, 1); end elseif s ~= "" then log("debug", "Saved to send buffer because there are %d open requests", #r); @@ -235,8 +247,9 @@ session.log("warn", "rid too large (means a request was lost). Last rid: %d New rid: %s", session.rid, attr.rid); elseif diff <= 0 then -- Repeated, ignore - session.log("debug", "rid repeated (on request %s), ignoring: %d", request.id, session.rid); + session.log("debug", "rid repeated (on request %s), ignoring: %s (diff %d)", request.id, session.rid, diff); request.notopen = nil; + request.sid = sid; t_insert(session.requests, request); return; end @@ -250,12 +263,6 @@ return; end - -- If session was inactive, make sure it is now marked as not - if #session.requests == 0 then - (session.log or log)("debug", "BOSH client now active again at %d", os_time()); - inactive_sessions[session] = nil; - end - if session.notopen then local features = st.stanza("stream:features"); hosts[session.host].events.fire_event("stream-features", { origin = session, features = features }); @@ -274,7 +281,7 @@ local session = sessions[request.sid]; if session then if stanza.attr.xmlns == xmlns_bosh then - stanza.attr.xmlns = "jabber:client"; + stanza.attr.xmlns = nil; end session.ip = request.handler:ip(); core_process_stanza(session, stanza);
--- a/plugins/mod_component.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_component.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_compression.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_compression.lua Fri May 21 19:45:33 2010 +0100 @@ -8,6 +8,8 @@ local st = require "util.stanza"; local zlib = require "zlib"; local pcall = pcall; +local tostring = tostring; + local xmlns_compression_feature = "http://jabber.org/features/compress" local xmlns_compression_protocol = "http://jabber.org/protocol/compress" local xmlns_stream = "http://etherx.jabber.org/streams"; @@ -71,7 +73,7 @@ local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); (session.sends2s or session.send)(error_st); session.log("error", "Failed to create zlib.deflate filter."); - module:log("error", deflate_stream); + module:log("error", "%s", tostring(deflate_stream)); return end return deflate_stream @@ -83,8 +85,8 @@ if status == false then local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); (session.sends2s or session.send)(error_st); - session.log("error", "Failed to create zlib.deflate filter."); - module:log("error", inflate_stream); + session.log("error", "Failed to create zlib.inflate filter."); + module:log("error", "%s", tostring(inflate_stream)); return end return inflate_stream @@ -104,7 +106,7 @@ text = compressed; extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed"); }); - module:log("warn", compressed); + module:log("warn", "%s", tostring(compressed)); return; end session.conn:write(compressed); @@ -125,7 +127,7 @@ text = decompressed; extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed"); }); - module:log("warn", decompressed); + module:log("warn", "%s", tostring(decompressed)); return; end old_data(conn, decompressed); @@ -166,15 +168,17 @@ function(session, stanza) -- fail if we are already compressed if session.compressed then - local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method"); + local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); (session.sends2s or session.send)(error_st); - session.log("warn", "Tried to establish another compression layer."); + session.log("debug", "Client tried to establish another compression layer."); + return; end -- checking if the compression method is supported - local method = stanza:child_with_name("method")[1]; + local method = stanza:child_with_name("method"); + method = method and (method[1] or ""); if method == "zlib" then - session.log("debug", method.." compression selected."); + session.log("debug", "zlib compression enabled."); -- create deflate and inflate streams local deflate_stream = get_deflate_stream(session); @@ -199,10 +203,12 @@ return true; end; session.compressed = true; - else - session.log("warn", method.." compression selected. But we don't support it."); + elseif method then + session.log("debug", "%s compression selected, but we don't support it.", tostring(method)); local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method"); (session.sends2s or session.send)(error_st); + else + (session.sends2s or session.send)(st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed")); end end );
--- a/plugins/mod_console.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_console.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -53,76 +53,78 @@ local sessions = {}; +function console_listener.onconnect(conn) + -- Handle new connection + local session = console:new_session(conn); + sessions[conn] = session; + printbanner(session); + session.send(string.char(0)); +end + function console_listener.onincoming(conn, data) local session = sessions[conn]; - - if not session then - -- Handle new connection - session = console:new_session(conn); - sessions[conn] = session; - printbanner(session); - end - if data then - -- Handle data - (function(session, data) - local useglobalenv; - - if data:match("^>") then - data = data:gsub("^>", ""); - useglobalenv = true; - elseif data == "\004" then - commands["bye"](session, data); - return; - else - local command = data:lower(); - command = data:match("^%w+") or data:match("%p"); - if commands[command] then - commands[command](session, data); - return; - end - end - session.env._ = data; - - local chunk, err = loadstring("return "..data); - if not chunk then - chunk, err = loadstring(data); - if not chunk then - err = err:gsub("^%[string .-%]:%d+: ", ""); - err = err:gsub("^:%d+: ", ""); - err = err:gsub("'<eof>'", "the end of the line"); - session.print("Sorry, I couldn't understand that... "..err); - return; - end - end - - setfenv(chunk, (useglobalenv and redirect_output(_G, session)) or session.env or nil); - - local ranok, taskok, message = pcall(chunk); - - if not (ranok or message or useglobalenv) and commands[data:lower()] then - commands[data:lower()](session, data); + -- Handle data + (function(session, data) + local useglobalenv; + + if data:match("^>") then + data = data:gsub("^>", ""); + useglobalenv = true; + elseif data == "\004" then + commands["bye"](session, data); + return; + else + local command = data:lower(); + command = data:match("^%w+") or data:match("%p"); + if commands[command] then + commands[command](session, data); return; end - - if not ranok then - session.print("Fatal error while running command, it did not complete"); - session.print("Error: "..taskok); + end + + session.env._ = data; + + local chunkname = "=console"; + local chunk, err = loadstring("return "..data, chunkname); + if not chunk then + chunk, err = loadstring(data, chunkname); + if not chunk then + err = err:gsub("^%[string .-%]:%d+: ", ""); + err = err:gsub("^:%d+: ", ""); + err = err:gsub("'<eof>'", "the end of the line"); + session.print("Sorry, I couldn't understand that... "..err); return; end - - if not message then - session.print("Result: "..tostring(taskok)); - return; - elseif (not taskok) and message then - session.print("Command completed with a problem"); - session.print("Message: "..tostring(message)); - return; - end - - session.print("OK: "..tostring(message)); - end)(session, data); - end + end + + setfenv(chunk, (useglobalenv and redirect_output(_G, session)) or session.env or nil); + + local ranok, taskok, message = pcall(chunk); + + if not (ranok or message or useglobalenv) and commands[data:lower()] then + commands[data:lower()](session, data); + return; + end + + if not ranok then + session.print("Fatal error while running command, it did not complete"); + session.print("Error: "..taskok); + return; + end + + if not message then + session.print("Result: "..tostring(taskok)); + return; + elseif (not taskok) and message then + session.print("Command completed with a problem"); + session.print("Message: "..tostring(message)); + return; + end + + session.print("OK: "..tostring(message)); + end)(session, data); + session.send(string.char(0)); end @@ -192,7 +194,7 @@ elseif section == "server" then print [[server:version() - Show the server's version number]] print [[server:uptime() - Show how long the server has been running]] - --print [[server:shutdown(reason) - Shut down the server, with an optional reason to be broadcast to all connections]] + print [[server:shutdown(reason) - Shut down the server, with an optional reason to be broadcast to all connections]] elseif section == "config" then print [[config:reload() - Reload the server configuration. Modules may need to be reloaded for changes to take effect.]] elseif section == "console" then
--- a/plugins/mod_debug.lua Fri May 21 19:44:31 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,191 +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. --- - -module.host = "*"; - -local connlisteners_register = require "net.connlisteners".register; - -local console_listener = { default_port = 5583; default_mode = "*l"; default_interface = "127.0.0.1" }; - -local sha256, missingglobal = require "util.hashes".sha256; - -local commands = {}; -local debug_env = {}; -local debug_env_mt = { __index = function (t, k) return rawget(_G, k) or missingglobal(k); end, __newindex = function (t, k, v) rawset(_G, k, v); end }; - -local t_insert, t_concat = table.insert, table.concat; -local t_concatall = function (t, sep) local tt = {}; for k, s in pairs(t) do tt[k] = tostring(s); end return t_concat(tt, sep); end - - -setmetatable(debug_env, debug_env_mt); - -console = {}; - -function console:new_session(conn) - local w = function(s) conn.write(s:gsub("\n", "\r\n")); end; - local session = { conn = conn; - send = function (t) w(tostring(t)); end; - print = function (t) w("| "..tostring(t).."\n"); end; - disconnect = function () conn.close(); end; - }; - - return session; -end - -local sessions = {}; - -function console_listener.listener(conn, data) - local session = sessions[conn]; - - if not session then - -- Handle new connection - session = console:new_session(conn); - sessions[conn] = session; - printbanner(session); - end - if data then - -- Handle data - (function(session, data) - if data:match("[!.]$") then - local command = data:lower(); - command = data:match("^%w+") or data:match("%p"); - if commands[command] then - commands[command](session, data); - return; - end - end - - local chunk, err = loadstring("return "..data); - if not chunk then - chunk, err = loadstring(data); - if not chunk then - err = err:gsub("^%[string .-%]:%d+: ", ""); - err = err:gsub("^:%d+: ", ""); - err = err:gsub("'<eof>'", "the end of the line"); - session.print("Sorry, I couldn't understand that... "..err); - return; - end - end - - debug_env.print = session.print; - - setfenv(chunk, debug_env); - - local ret = { pcall(chunk) }; - - if not ret[1] then - session.print("Fatal error while running command, it did not complete"); - session.print("Error: "..ret[2]); - return; - end - - table.remove(ret, 1); - - local retstr = t_concatall(ret, ", "); - if retstr ~= "" then - session.print("Result: "..retstr); - else - session.print("No result, or nil"); - return; - end - end)(session, data); - end - session.send(string.char(0)); -end - -function console_listener.disconnect(conn, err) - -end - -connlisteners_register('debug', console_listener); -require "net.connlisteners".start("debug"); - --- Console commands -- --- These are simple commands, not valid standalone in Lua - -function commands.bye(session) - session.print("See you! :)"); - session.disconnect(); -end - -commands["!"] = function (session, data) - if data:match("^!!") then - session.print("!> "..session.env._); - return console_listener.listener(session.conn, session.env._); - end - local old, new = data:match("^!(.-[^\\])!(.-)!$"); - if old and new then - local ok, res = pcall(string.gsub, session.env._, old, new); - if not ok then - session.print(res) - return; - end - session.print("!> "..res); - return console_listener.listener(session.conn, res); - end - session.print("Sorry, not sure what you want"); -end - -function printbanner(session) -session.print [[ - ____ \ / _ - | _ \ _ __ ___ ___ _-_ __| |_ _ - | |_) | '__/ _ \/ __|/ _ \ / _` | | | | - | __/| | | (_) \__ \ |_| | (_| | |_| | - |_| |_| \___/|___/\___/ \__,_|\__, | - A study in simplicity |___/ - -]] -session.print("Welcome to the Prosody debug console. For a list of commands, type: help"); -session.print("You may find more help on using this console in our online documentation at "); -session.print("http://prosody.im/doc/debugconsole\n"); -end - -local byte, char = string.byte, string.char; -local gmatch, gsub = string.gmatch, string.gsub; - -local function vdecode(text, key) - local keyarr = {}; - for l in gmatch(key, ".") do t_insert(keyarr, byte(l) - 32) end - local pos, keylen = 0, #keyarr; - return (gsub(text, ".", function (letter) - if byte(letter) < 32 then return ""; end - pos = (pos%keylen)+1; - return char(((byte(letter) - 32 - keyarr[pos]) % 94) + 32); - end)); -end - -local subst = { - ["f880c08056ba7dbecb1ccfe5d7728bd6dcd654e94f7a9b21788c43397bae0bc5"] = - [=[nRYeKR$l'5Ix%u*1Mc-K}*bwv*\ $1KLMBd$KH R38`$[6}VQ@,6Qn]=]; - ["92f718858322157202ec740698c1390e47bc819e52b6a099c54c378a9f7529d6"] = - [=[V\Z5`WZ5,T$<)7LM'w3Z}M(7V'{pa) &'>0+{v)O(0M*V5K$$LL$|2wT}6 - 1as*")e!>]=]; - ["467b65edcc7c7cd70abf2136cc56abd037216a6cd9e17291a2219645be2e2216"] = - [=[i#'Z,E1-"YaHW(j/0xs]I4x&%(Jx1h&18'(exNWT D3b+K{*8}w(%D {]=]; - ["f73729d7f2fbe686243a25ac088c7e6aead3d535e081329f2817438a5c78bee5"] = - [=[,3+(Q{3+W\ftQ%wvv/C0z-l%f>ABc(vkp<bb8]=]; - ["6afa189489b096742890d0c5bd17d5bb8af8ac460c7026984b64e8f14a40404e"] = - [=[9N{)5j34gd*}&]H&dy"I&7(",a F1v6jY+IY7&S+86)1z(Vo]=]; - ["cc5e5293ef8a1acbd9dd2bcda092c5c77ef46d3ec5aea65024fca7ed4b3c94a9"] = - [=[_]Rc}IF'Kfa&))Ry+6|x!K2|T*Vze)%4Hwz'L3uI|OwIa)|q#uq2+Qu u7 - [V3(z(*TYY|T\1_W'2] Dwr{-{@df#W.H5^x(ydtr{c){UuV@]=]; - ["b3df231fd7ddf73f72f39cb2510b1fe39318f4724728ed58948a180663184d3e"] = - [=[iH!"9NLS'%geYw3^R*fvWM1)MwxLS!d[zP(p0sQ|8tX{dWO{9w!+W)b"MU - W)V8&(2Wx"'dTL9*PP%1"JV(I|Jr1^f'-Hc3U\2H3Z='K#,)dPm]=]; - } - -function missingglobal(name) - if sha256 then - local hash = sha256(name.."|"..name:reverse(), true); - - if subst[hash] then - return vdecode(subst[hash], sha256(name:reverse(), true)); - end - end -end
--- a/plugins/mod_dialback.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_dialback.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_disco.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_disco.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_groups.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_groups.lua Fri May 21 19:45:33 2010 +0100 @@ -1,14 +1,14 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. -- -local groups = { default = {} }; -local members = { [false] = {} }; +local groups; +local members; local groups_file; @@ -18,9 +18,9 @@ local module_host = module:get_host(); function inject_roster_contacts(username, host, roster) - module:log("warn", "Injecting group members to roster"); + --module:log("debug", "Injecting group members to roster"); local bare_jid = username.."@"..host; - if not members[bare_jid] then return; end -- Not a member of any groups + if not members[bare_jid] and not members[false] then return; end -- Not a member of any groups local function import_jids_to_roster(group_name) for jid in pairs(groups[group_name]) do @@ -39,13 +39,23 @@ end -- Find groups this JID is a member of - for _, group_name in ipairs(members[bare_jid]) do - import_jids_to_roster(group_name); + if members[bare_jid] then + for _, group_name in ipairs(members[bare_jid]) do + --module:log("debug", "Importing group %s", group_name); + import_jids_to_roster(group_name); + end end -- Import public groups - for _, group_name in ipairs(members[false]) do - import_jids_to_roster(group_name); + if members[false] then + for _, group_name in ipairs(members[false]) do + --module:log("debug", "Importing group %s", group_name); + import_jids_to_roster(group_name); + end + end + + if roster[false] then + roster[false].version = true; end end @@ -57,6 +67,7 @@ new_roster[jid] = contact; end end + new_roster[false].version = nil; -- Version is void return username, host, datastore, new_roster; end @@ -71,20 +82,23 @@ datamanager.add_callback(remove_virtual_contacts); groups = { default = {} }; - members = { [false] = {} }; + members = { }; local curr_group = "default"; for line in io.lines(groups_file) do if line:match("^%s*%[.-%]%s*$") then curr_group = line:match("^%s*%[(.-)%]%s*$"); if curr_group:match("^%+") then curr_group = curr_group:gsub("^%+", ""); + if not members[false] then + members[false] = {}; + end members[false][#members[false]+1] = curr_group; -- Is a public group end module:log("debug", "New group: %s", tostring(curr_group)); groups[curr_group] = groups[curr_group] or {}; else -- Add JID - local jid = jid_prep(line); + local jid = jid_prep(line:match("%S+")); if jid then module:log("debug", "New member of %s: %s", tostring(curr_group), tostring(jid)); groups[curr_group][jid] = true;
--- a/plugins/mod_httpserver.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_httpserver.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_iq.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_iq.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -53,6 +53,18 @@ end end); +module:hook("iq/self", function(data) + -- IQ to bare JID recieved + local origin, stanza = data.origin, data.stanza; + + if stanza.attr.type == "get" or stanza.attr.type == "set" then + return module:fire_event("iq/self/"..stanza.tags[1].attr.xmlns..":"..stanza.tags[1].name, data); + else + module:fire_event("iq/self/"..stanza.attr.id, data); + return true; + end +end); + module:hook("iq/host", function(data) -- IQ to a local host recieved local origin, stanza = data.origin, data.stanza;
--- a/plugins/mod_lastactivity.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_lastactivity.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_legacyauth.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_legacyauth.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_message.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_message.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_offline.lua Fri May 21 19:44:31 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +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 datamanager = require "util.datamanager"; -local st = require "util.stanza"; -local datetime = require "util.datetime"; -local ipairs = ipairs; -local jid_split = require "util.jid".split; - -module:add_feature("msgoffline"); - -module:hook("message/offline/store", function(event) - local origin, stanza = event.origin, event.stanza; - local to = stanza.attr.to; - local node, host; - if to then - node, host = jid_split(to) - else - node, host = origin.username, origin.host; - end - - stanza.attr.stamp, stanza.attr.stamp_legacy = datetime.datetime(), datetime.legacy(); - local result = datamanager.list_append(node, host, "offline", st.preserialize(stanza)); - stanza.attr.stamp, stanza.attr.stamp_legacy = nil, nil; - - return true; -end); - -module:hook("message/offline/broadcast", function(event) - local origin = event.origin; - local node, host = origin.username, origin.host; - - local data = datamanager.list_load(node, host, "offline"); - if not data then return true; end - for _, stanza in ipairs(data) do - stanza = st.deserialize(stanza); - stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = host, stamp = stanza.attr.stamp}):up(); -- XEP-0203 - stanza:tag("x", {xmlns = "jabber:x:delay", from = host, stamp = stanza.attr.stamp_legacy}):up(); -- XEP-0091 (deprecated) - stanza.attr.stamp, stanza.attr.stamp_legacy = nil, nil; - origin.send(stanza); - end - return true; -end); - -module:hook("message/offline/delete", function(event) - local origin = event.origin; - local node, host = origin.username, origin.host; - - return datamanager.list_store(node, host, "offline", nil); -end);
--- a/plugins/mod_pep.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_pep.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_ping.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_ping.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_posix.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_posix.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -82,6 +82,7 @@ end pidfile = module:get_option("pidfile"); if pidfile then + local err; local mode = stat(pidfile) and "r+" or "w+"; pidfile_handle, err = io.open(pidfile, mode); if not pidfile_handle then
--- a/plugins/mod_presence.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_presence.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_privacy.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_privacy.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- Copyright (C) 2009-2010 Matthew Wild +-- Copyright (C) 2009-2010 Waqas Hussain -- Copyright (C) 2009 Thilo Cestonaro -- -- This project is MIT/X11 licensed. Please see the @@ -13,7 +13,7 @@ local bare_sessions, full_sessions = bare_sessions, full_sessions; local util_Jid = require "util.jid"; local jid_bare = util_Jid.bare; -local jid_split = util_Jid.split; +local jid_split, jid_join = util_Jid.split, util_Jid.join; local load_roster = require "core.rostermanager".load_roster; local to_number = tonumber; @@ -160,26 +160,7 @@ end end - if tmp.type == "group" then - local found = false; - local roster = load_roster(origin.username, origin.host); - for jid,item in pairs(roster) do - if item.groups ~= nil then - for group in pairs(item.groups) do - if group == tmp.value then - found = true; - break; - end - end - if found == true then - break; - end - end - end - if found == false then - return {"cancel", "item-not-found", "Specifed roster group not existing."}; - end - elseif tmp.type == "subscription" then + if tmp.type == "subscription" then if tmp.value ~= "both" and tmp.value ~= "to" and tmp.value ~= "from" and @@ -379,17 +360,22 @@ block = (item.action == "deny"); elseif item.type == "group" then local roster = load_roster(session.username, session.host); - local groups = roster[evilJid.node .. "@" .. evilJid.host].groups; - for group in pairs(groups) do - if group == item.value then - apply = true; - block = (item.action == "deny"); - break; + local roster_entry = roster[jid_join(evilJid.node, evilJid.host)]; + if roster_entry then + local groups = roster_entry.groups; + for group in pairs(groups) do + if group == item.value then + apply = true; + block = (item.action == "deny"); + break; + end end end - elseif item.type == "subscription" and evilJid.node ~= nil and evilJid.host ~= nil then -- we need a valid bare evil jid + elseif item.type == "subscription" then -- we need a valid bare evil jid local roster = load_roster(session.username, session.host); - if roster[evilJid.node .. "@" .. evilJid.host].subscription == item.value then + local roster_entry = roster[jid_join(evilJid.node, evilJid.host)]; + if (not(roster_entry) and item.value == "none") + or (roster_entry and roster_entry.subscription == item.value) then apply = true; block = (item.action == "deny"); end
--- a/plugins/mod_private.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_private.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_proxy65.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_proxy65.lua Fri May 21 19:45:33 2010 +0100 @@ -20,6 +20,7 @@ local config_get = require "core.configmanager".get; local connlisteners = require "net.connlisteners"; local sha1 = require "util.hashes".sha1; +local server = require "net.server"; local host, name = module:get_host(), "SOCKS5 Bytestreams Service"; local sessions, transfers, component, replies_cache = {}, {}, nil, {}; @@ -28,6 +29,7 @@ local proxy_interface = config_get(host, "core", "proxy65_interface") or "*"; local proxy_address = config_get(host, "core", "proxy65_address") or (proxy_interface ~= "*" and proxy_interface) or host; local proxy_acl = config_get(host, "core", "proxy65_acl"); +local max_buffer_size = 4096; local connlistener = { default_port = proxy_port, default_interface = proxy_interface, default_mode = "*a" }; @@ -84,19 +86,19 @@ transfers[sha].initiator = conn; session.sha = sha; module:log("debug", "initiator connected ... "); - throttle_sending(conn, transfers[sha].target); - throttle_sending(transfers[sha].target, conn); + server.link(conn, transfers[sha].target, max_buffer_size); + server.link(transfers[sha].target, conn, max_buffer_size); end conn:write(string.char(5, 0, 0, 3, sha:len()) .. sha .. string.char(0, 0)); -- VER, REP, RSV, ATYP, BND.ADDR (sha), BND.PORT (2 Byte) conn:lock_read(true) else module:log("warn", "Neither data transfer nor initial connect of a participator of a transfer.") - conn.close(); + conn:close(); end else if data ~= nil then module:log("warn", "unknown connection with no authentication data -> closing it"); - conn.close(); + conn:close(); end end end @@ -107,9 +109,9 @@ if session.sha and transfers[session.sha] then local initiator, target = transfers[session.sha].initiator, transfers[session.sha].target; if initiator == conn and target ~= nil then - target.close(); + target:close(); elseif target == conn and initiator ~= nil then - initiator.close(); + initiator:close(); end transfers[session.sha] = nil; end @@ -234,8 +236,12 @@ elseif xmlns == "http://jabber.org/protocol/bytestreams" then origin.send(get_stream_host(origin, stanza)); return true; + else + origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); + return true; end elseif stanza.name == "iq" and type == "set" then + module:log("debug", "Received activation request from %s", stanza.attr.from); local reply, from, to, sid = set_activation(stanza); if reply ~= nil and from ~= nil and to ~= nil and sid ~= nil then local sha = sha1(sid .. from .. to, true); @@ -246,6 +252,15 @@ transfers[sha].activated = true; transfers[sha].target:lock_read(false); transfers[sha].initiator:lock_read(false); + else + module:log("debug", "Both parties were not yet connected"); + local message = "Neither party is connected to the proxy"; + if transfers[sha].initiator then + message = "The recipient is not connected to the proxy"; + elseif transfers[sha].target then + message = "The sender (you) is not connected to the proxy"; + end + origin.send(st.error_reply(stanza, "cancel", "not-allowed", message)); end else module:log("error", "activation failed: sid: %s, initiator: %s, target: %s", tostring(sid), tostring(from), tostring(to)); @@ -262,25 +277,3 @@ connlisteners.start(module.host .. ':proxy65'); component = componentmanager.register_component(host, handle_to_domain); -local sender_lock_threshold = 4096; -function throttle_sending(sender, receiver) - sender:pattern(sender_lock_threshold); - local sender_locked; - local _sendbuffer = receiver.sendbuffer; - function receiver.sendbuffer() - _sendbuffer(); - if sender_locked and receiver.bufferlen() < sender_lock_threshold then - sender:lock_read(false); -- Unlock now - sender_locked = nil; - end - end - - local _readbuffer = sender.readbuffer; - function sender.readbuffer() - _readbuffer(); - if not sender_locked and receiver.bufferlen() >= sender_lock_threshold then - sender_locked = true; - sender:lock_read(true); - end - end -end
--- a/plugins/mod_register.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_register.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -12,6 +12,7 @@ local datamanager = require "util.datamanager"; local usermanager_user_exists = require "core.usermanager".user_exists; local usermanager_create_user = require "core.usermanager".create_user; +local usermanager_set_password = require "core.usermanager".set_password; local datamanager_store = require "util.datamanager".store; local os_time = os.time; local nodeprep = require "util.encodings".stringprep.nodeprep; @@ -34,7 +35,7 @@ local username, host = session.username, session.host; --session.send(st.error_reply(stanza, "cancel", "not-allowed")); --return; - usermanager_create_user(username, nil, host); -- Disable account + usermanager_set_password(username, host, nil); -- Disable account -- FIXME the disabling currently allows a different user to recreate the account -- we should add an in-memory account block mode when we have threading session.send(st.reply(stanza)); @@ -69,7 +70,7 @@ username = nodeprep(table.concat(username)); password = table.concat(password); if username == session.username then - if usermanager_create_user(username, password, session.host) then -- password change -- TODO is this the right way? + if usermanager_set_password(username, session.host, password) then session.send(st.reply(stanza)); else -- TODO unable to write file, file may be locked, etc, what's the correct error?
--- a/plugins/mod_roster.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_roster.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -36,9 +36,10 @@ if stanza.attr.type == "get" then local roster = st.reply(stanza); - local ver = stanza.tags[1].attr.ver + local client_ver = tonumber(stanza.tags[1].attr.ver); + local server_ver = tonumber(session.roster[false].version or 1); - if (not ver) or tonumber(ver) ~= (session.roster[false].version or 1) then + if not (client_ver and server_ver) or client_ver ~= server_ver then roster:query("jabber:iq:roster"); -- Client does not support versioning, or has stale roster for jid in pairs(session.roster) do @@ -55,7 +56,7 @@ roster:up(); -- move out from item end end - roster.tags[1].attr.ver = tostring(session.roster[false].version or "1"); + roster.tags[1].attr.ver = server_ver; end session.send(roster); session.interested = true; -- resource is interested in roster updates
--- a/plugins/mod_saslauth.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_saslauth.lua Fri May 21 19:45:33 2010 +0100 @@ -1,7 +1,7 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain --- +-- 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. -- @@ -28,6 +28,12 @@ local secure_auth_only = module:get_option("c2s_require_encryption") or module:get_option("require_encryption"); local sasl_backend = module:get_option("sasl_backend") or "builtin"; +-- Cyrus config options +local require_provisioning = module:get_option("cyrus_require_provisioning") or false; +local cyrus_service_realm = module:get_option("cyrus_service_realm"); +local cyrus_service_name = module:get_option("cyrus_service_name"); +local cyrus_application_name = module:get_option("cyrus_application_name"); + local log = module._log; local xmlns_sasl ='urn:ietf:params:xml:ns:xmpp-sasl'; @@ -35,21 +41,29 @@ local xmlns_stanzas ='urn:ietf:params:xml:ns:xmpp-stanzas'; local new_sasl; -if sasl_backend == "cyrus" then - local cyrus, err = pcall(require, "util.sasl_cyrus"); - if cyrus then +if sasl_backend == "builtin" then + new_sasl = require "util.sasl".new; +elseif sasl_backend == "cyrus" then + prosody.unlock_globals(); --FIXME: Figure out why this is needed and + -- why cyrussasl isn't caught by the sandbox + local ok, cyrus = pcall(require, "util.sasl_cyrus"); + prosody.lock_globals(); + if ok then local cyrus_new = cyrus.new; new_sasl = function(realm) - return cyrus_new(realm, module:get_option("cyrus_service_name") or "xmpp"); + return cyrus_new( + cyrus_service_realm or realm, + cyrus_service_name or "xmpp", + cyrus_application_name or "prosody" + ); end else - sasl_backend = "builtin"; - module:log("warn", "Failed to load Cyrus SASL, falling back to builtin auth mechanisms"); + module:log("error", "Failed to load Cyrus SASL because: %s", cyrus); + error("Failed to load Cyrus SASL"); end -end -if not new_sasl then - if sasl_backend ~= "builtin" then module:log("warn", "Unknown SASL backend %s", sasl_backend); end; - new_sasl = require "util.sasl".new; +else + module:log("error", "Unknown SASL backend: %s", sasl_backend); + error("Unknown SASL backend"); end local default_authentication_profile = { @@ -90,7 +104,7 @@ return reply; end -local function handle_status(session, status) +local function handle_status(session, status, ret, err_msg) if status == "failure" then session.sasl_handler = session.sasl_handler:clean_clone(); elseif status == "success" then @@ -99,12 +113,20 @@ module:log("warn", "SASL succeeded but we didn't get a username!"); session.sasl_handler = nil; session:reset_stream(); - return; + return status, ret, err_msg; end - sm_make_authenticated(session, session.sasl_handler.username); - session.sasl_handler = nil; - session:reset_stream(); + + if not(require_provisioning) or usermanager_user_exists(username, session.host) then + sm_make_authenticated(session, session.sasl_handler.username); + session.sasl_handler = nil; + session:reset_stream(); + else + module:log("warn", "SASL succeeded but we don't have an account provisioned for %s", username); + session.sasl_handler = session.sasl_handler:clean_clone(); + return "failure", "not-authorized", "User authenticated successfully, but not provisioned for XMPP"; + end end + return status, ret, err_msg; end local function sasl_handler(session, stanza) @@ -138,7 +160,7 @@ end end local status, ret, err_msg = session.sasl_handler:process(text); - handle_status(session, status); + status, ret, err_msg = handle_status(session, status, ret, err_msg); local s = build_reply(status, ret, err_msg); log("debug", "sasl reply: %s", tostring(s)); session.send(s); @@ -157,10 +179,11 @@ if secure_auth_only and not origin.secure then return; end + local realm = module:get_option("sasl_realm") or origin.host; if module:get_option("anonymous_login") then - origin.sasl_handler = new_sasl(origin.host, anonymous_authentication_profile); + origin.sasl_handler = new_sasl(realm, anonymous_authentication_profile); else - origin.sasl_handler = new_sasl(origin.host, default_authentication_profile); + origin.sasl_handler = new_sasl(realm, default_authentication_profile); if not (module:get_option("allow_unencrypted_plain_auth")) and not origin.secure then origin.sasl_handler:forbidden({"PLAIN"}); end
--- a/plugins/mod_selftests.lua Fri May 21 19:44:31 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +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. --- - -module.host = "*" -- Global module - -local st = require "util.stanza"; -local register_component = require "core.componentmanager".register_component; -local core_route_stanza = core_route_stanza; -local socket = require "socket"; -local ping_hosts = module:get_option("ping_hosts") or { "coversant.interop.xmpp.org", "djabberd.interop.xmpp.org", "djabberd-trunk.interop.xmpp.org", "ejabberd.interop.xmpp.org", "openfire.interop.xmpp.org" }; - -local open_pings = {}; - -local t_insert = table.insert; - -local log = require "util.logger".init("mod_selftests"); - -local tests_jid = "self_tests@getjabber.ath.cx"; -local host = "getjabber.ath.cx"; - -if not (tests_jid and host) then - for currhost in pairs(host) do - if currhost ~= "localhost" then - tests_jid, host = "self_tests@"..currhost, currhost; - end - end -end - -if tests_jid and host then - local bot = register_component(tests_jid, function(origin, stanza, ourhost) - local time = open_pings[stanza.attr.id]; - - if time then - log("info", "Ping reply from %s in %fs", tostring(stanza.attr.from), socket.gettime() - time); - else - log("info", "Unexpected reply: %s", stanza:pretty_print()); - end - end); - - - local our_origin = hosts[host]; - module:add_event_hook("server-started", - function () - local id = st.new_id(); - local ping_attr = { xmlns = 'urn:xmpp:ping' }; - local function send_ping(to) - log("info", "Sending ping to %s", to); - core_route_stanza(our_origin, st.iq{ to = to, from = tests_jid, id = id, type = "get" }:tag("ping", ping_attr)); - open_pings[id] = socket.gettime(); - end - - for _, host in ipairs(ping_hosts) do - send_ping(host); - end - end); -end
--- a/plugins/mod_time.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_time.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_tls.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_tls.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -10,6 +10,7 @@ local secure_auth_only = module:get_option("c2s_require_encryption") or module:get_option("require_encryption"); local secure_s2s_only = module:get_option("s2s_require_encryption"); +local allow_s2s_tls = module:get_option("s2s_allow_encryption") ~= false; local xmlns_starttls = 'urn:ietf:params:xml:ns:xmpp-tls'; local starttls_attr = { xmlns = xmlns_starttls }; @@ -27,8 +28,10 @@ local function can_do_tls(session) if session.type == "c2s_unauthed" then return session.conn.starttls and host.ssl_ctx_in; - elseif session.type == "s2sin_unauthed" then + elseif session.type == "s2sin_unauthed" and allow_s2s_tls then return session.conn.starttls and host.ssl_ctx_in; + elseif session.direction == "outgoing" and allow_s2s_tls then + return session.conn.starttls and host.ssl_ctx; end return false; end @@ -69,7 +72,7 @@ -- For s2sout connections, start TLS if we can module:hook_stanza("http://etherx.jabber.org/streams", "features", function (session, stanza) module:log("debug", "Received features element"); - if session.conn.starttls and stanza:child_with_ns(xmlns_starttls) then + 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); session.sends2s("<starttls xmlns='"..xmlns_starttls.."'/>"); return true;
--- a/plugins/mod_uptime.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_uptime.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_vcard.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_vcard.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_version.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_version.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_watchregistrations.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_watchregistrations.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/mod_welcome.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/mod_welcome.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/muc/mod_muc.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/muc/mod_muc.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/plugins/muc/muc.lib.lua Fri May 21 19:44:31 2010 +0100 +++ b/plugins/muc/muc.lib.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -319,6 +319,11 @@ :tag("item", {affiliation=affiliation or "none", role=role or "none"}):up() :tag("status", {code='110'})); end + if self._data.whois == 'anyone' then -- non-anonymous? + self:_route_stanza(st.stanza("message", {from=to, to=from, type='groupchat'}) + :tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) + :tag("status", {code='100'})); + end self:send_history(from); else -- banned local reply = st.error_reply(stanza, "auth", "forbidden"):up(); @@ -514,6 +519,9 @@ if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation local occupant = self._occupants[self.jid.."/"..item.attr.nick]; if occupant then item.attr.jid = occupant.jid; end + elseif not item.attr.nick and item.attr.jid then + local nick = self._jid_nick[item.attr.jid]; + if nick then item.attr.nick = select(3, jid_split(nick)); end end local reason = item.tags[1] and item.tags[1].name == "reason" and #item.tags[1] == 1 and item.tags[1][1]; if item.attr.affiliation and item.attr.jid and not item.attr.role then @@ -743,7 +751,7 @@ function room_mt:set_role(actor, occupant_jid, role, callback, reason) if role == "none" then role = nil; end if role and role ~= "moderator" and role ~= "participant" and role ~= "visitor" then return nil, "modify", "not-acceptable"; end - if self:get_affiliation(actor) ~= "owner" then return nil, "cancel", "not-allowed"; end + if self:get_role(self._jid_nick[actor]) ~= "moderator" then return nil, "cancel", "not-allowed"; end local occupant = self._occupants[occupant_jid]; if not occupant then return nil, "modify", "not-acceptable"; end if occupant.affiliation == "owner" or occupant.affiliation == "admin" then return nil, "cancel", "not-allowed"; end @@ -796,9 +804,6 @@ end end end - if self._data.whois == 'anyone' then - muc_child:tag('status', { code = '100' }); - end end self:route_stanza(stanza); if muc_child then
--- a/prosody Fri May 21 19:44:31 2010 +0100 +++ b/prosody Fri May 21 19:45:33 2010 +0100 @@ -1,7 +1,7 @@ #!/usr/bin/env lua -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -123,6 +123,33 @@ end end +function set_function_metatable() + local mt = {}; + function mt.__index(f, upvalue) + local i, name, value = 0; + repeat + i = i + 1; + name, value = debug.getupvalue(f, i); + until name == upvalue or name == nil; + return value; + end + function mt.__newindex(f, upvalue, value) + local i, name = 0; + repeat + i = i + 1; + name = debug.getupvalue(f, i); + until name == upvalue or name == nil; + if name then + debug.setupvalue(f, i, value); + end + end + function mt.__tostring(f) + local info = debug.getinfo(f); + return ("function(%s:%d)"):format(info.short_src:match("[^\\/]*$"), info.linedefined); + end + debug.setmetatable(function() end, mt); +end + function init_global_state() bare_sessions = {}; full_sessions = {}; @@ -418,6 +445,7 @@ init_logging(); check_dependencies(); sandbox_require(); +set_function_metatable(); load_libraries(); init_global_state(); read_version();
--- a/prosody.cfg.lua.dist Fri May 21 19:44:31 2010 +0100 +++ b/prosody.cfg.lua.dist Fri May 21 19:45:33 2010 +0100 @@ -1,110 +1,127 @@ -- Prosody Example Configuration File -- --- If it wasn't already obvious, -- starts a comment, and all --- text after it on a line is ignored by Prosody. --- --- The config is split into sections, a global section, and one --- for each defined host that we serve. You can add as many host --- sections as you like. --- --- Lists are written { "like", "this", "one" } --- Lists can also be of { 1, 2, 3 } numbers, and other things. --- Either commas, or semi-colons; may be used --- as seperators. --- --- A table is a list of values, except each value has a name. An --- example table would be: --- --- ssl = { key = "keyfile.key", certificate = "certificate.cert" } --- --- Whitespace (that is tabs, spaces, line breaks) is mostly insignificant, so --- can --- be placed anywhere that you deem fitting. --- --- Tip: You can check that the syntax of this file is correct when you have finished --- by running: luac -p prosody.cfg.lua --- If there are any errors, it will let you know what and where they are, otherwise it --- will keep quiet. +-- Information on configuring Prosody can be found on our +-- website at http://prosody.im/doc/configure +-- +-- Tip: You can check that the syntax of this file is correct +-- when you have finished by running: luac -p prosody.cfg.lua +-- If there are any errors, it will let you know what and where +-- they are, otherwise it will keep quiet. -- -- The only thing left to do is rename this file to remove the .dist ending, and fill in the -- blanks. Good luck, and happy Jabbering! --- Server-wide settings go in this section -Host "*" - - -- This is a (by default, empty) list of accounts that are admins - -- for the server. Note that you must create the accounts separately - -- (see http://prosody.im/doc/creating_accounts for info) - -- Example: admins = { "user1@example.com", "user2@example.net" } - admins = { } - - -- This is the list of modules Prosody will load on startup. - -- It looks for mod_modulename.lua in the plugins folder, so make sure that exists too. - modules_enabled = { - -- Generally required - "roster"; -- Allow users to have a roster. Recommended ;) - "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. - "tls"; -- Add support for secure TLS on c2s/s2s connections - "dialback"; -- s2s dialback support - "disco"; -- Service discovery - - -- Not essential, but recommended - "private"; -- Private XML storage (for room bookmarks, etc.) - "vcard"; -- Allow users to set vCards - - -- Nice to have - "legacyauth"; -- Legacy authentication. Only used by some old clients and bots. - "version"; -- Replies to server version requests - "uptime"; -- Report how long server has been running - "time"; -- Let others know the time here on this server - "ping"; -- Replies to XMPP pings with pongs - "pep"; -- Enables users to publish their mood, activity, playing music and more - "register"; -- Allow users to register on this server using a client and change passwords + +---------- Server-wide settings ---------- +-- Settings in this section apply to the whole server and are the default settings +-- for any virtual hosts + +-- This is a (by default, empty) list of accounts that are admins +-- for the server. Note that you must create the accounts separately +-- (see http://prosody.im/doc/creating_accounts for info) +-- Example: admins = { "user1@example.com", "user2@example.net" } +admins = { } + +-- Enable use of libevent for better performance under high load +-- For more information see: http://prosody.im/doc/libevent +--use_libevent = true; + +-- This is the list of modules Prosody will load on startup. +-- It looks for mod_modulename.lua in the plugins folder, so make sure that exists too. +-- Documentation on modules can be found at: http://prosody.im/doc/modules +modules_enabled = { + + -- Generally required + "roster"; -- Allow users to have a roster. Recommended ;) + "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. + "tls"; -- Add support for secure TLS on c2s/s2s connections + "dialback"; -- s2s dialback support + "disco"; -- Service discovery + + -- Not essential, but recommended + "private"; -- Private XML storage (for room bookmarks, etc.) + "vcard"; -- Allow users to set vCards + --"privacy"; -- Support privacy lists + --"compression"; -- Stream compression + + -- Nice to have + "legacyauth"; -- Legacy authentication. Only used by some old clients and bots. + "version"; -- Replies to server version requests + "uptime"; -- Report how long server has been running + "time"; -- Let others know the time here on this server + "ping"; -- Replies to XMPP pings with pongs + "pep"; -- Enables users to publish their mood, activity, playing music and more + "register"; -- Allow users to register on this server using a client and change passwords - -- Other specific functionality - --"posix"; -- POSIX functionality, sends server to background, enables syslog, etc. - --"console"; -- Opens admin telnet interface on localhost port 5582 - --"bosh"; -- Enable BOSH clients, aka "Jabber over HTTP" - --"httpserver"; -- Serve static files from a directory over HTTP - }; - - -- These modules are auto-loaded, should you - -- for (for some mad reason) want to disable - -- them then uncomment them below - modules_disabled = { - -- "presence"; - -- "message"; - -- "iq"; - }; + -- Other specific functionality + --"posix"; -- POSIX functionality, sends server to background, enables syslog, etc. + --"console"; -- Opens admin telnet interface on localhost port 5582 + --"bosh"; -- Enable BOSH clients, aka "Jabber over HTTP" + --"httpserver"; -- Serve static files from a directory over HTTP + --"groups"; -- Shared roster support + --"announce"; -- Send announcement to all online users + --"welcome"; -- Welcome users who register accounts + --"watchregistrations"; -- Alert admins of registrations +}; + +-- These modules are auto-loaded, should you +-- for (for some mad reason) want to disable +-- them then uncomment them below +modules_disabled = { + -- "presence"; + -- "message"; + -- "iq"; +}; - -- Disable account creation by default, for security - -- For more information see http://prosody.im/doc/creating_accounts - allow_registration = false; +-- Disable account creation by default, for security +-- For more information see http://prosody.im/doc/creating_accounts +allow_registration = false; - -- These are the SSL/TLS-related settings. If you don't want - -- to use SSL/TLS, you may comment or remove this - ssl = { - key = "certs/localhost.key"; - certificate = "certs/localhost.cert"; - } +-- These are the SSL/TLS-related settings. If you don't want +-- to use SSL/TLS, you may comment or remove this +ssl = { + key = "certs/localhost.key"; + certificate = "certs/localhost.cert"; +} + +-- Require encryption on client/server connections? +--c2s_require_encryption = false +--s2s_require_encryption = false --- This allows clients to connect to localhost. No harm in it. -Host "localhost" +-- Logging configuration +-- For advanced logging see http://prosody.im/doc/logging +log = "prosody.log"; +debug = false; -- Log debug messages? --- Section for example.com --- (replace example.com with your domain name) -Host "example.com" +----------- Virtual hosts ----------- +-- You need to add a VirtualHost entry for each domain you wish Prosody to serve. +-- Settings under each VirtualHost entry apply *only* to that host. - enabled = false -- This will disable the host, preserving the config, but denying connections +VirtualHost "localhost" + +VirtualHost "example.com" + enabled = false -- Remove this line to enable this host -- Assign this host a certificate for TLS, otherwise it would use the one -- set in the global section (if any). -- Note that old-style SSL on port 5223 only supports one certificate, and will always -- use the global one. - ssl = { + ssl = { key = "certs/example.com.key"; certificate = "certs/example.com.crt"; - } + } + +------ Components ------ +-- You can specify components to add hosts that provide special services, +-- like multi-user conferences, and transports. +-- For more information on components, see http://prosody.im/doc/components --- Set up a MUC (multi-user chat) room server on conference.example.com: -Component "conference.example.com" "muc" +---Set up a MUC (multi-user chat) room server on conference.example.com: +--Component "conference.example.com" "muc" + +-- Set up a SOCKS5 bytestream proxy for server-proxied file transfers: +--Component "proxy.example.com" "proxy65" + +---Set up an external component (default component port is 5347) +--Component "gateway.example.com" +-- component_secret = "password"
--- a/prosodyctl Fri May 21 19:44:31 2010 +0100 +++ b/prosodyctl Fri May 21 19:45:33 2010 +0100 @@ -433,6 +433,19 @@ return 1; end +function commands.restart(arg) + if arg[1] == "--help" then + show_usage([[restart]], [[Restart a running Prosody server]]); + return 1; + end + + local ret = commands.stop(arg); + if ret == 0 then + ret = commands.start(arg); + end + return ret; +end + -- ejabberdctl compatibility function commands.register(arg) @@ -491,6 +504,10 @@ }; function commands.addplugin(arg) + if not arg[1] or arg[1] == "--help" then + show_usage("addplugin URL", "Download and install a plugin from a URL"); + return 1; + end local url = arg[1]; if url:match("^http://") then local http = require "socket.http"; @@ -562,8 +579,8 @@ print(""); print("Where COMMAND may be one of:\n"); - local hidden_commands = require "util.set".new{ "register", "unregister" }; - local commands_order = { "adduser", "passwd", "deluser" }; + local hidden_commands = require "util.set".new{ "register", "unregister", "addplugin" }; + local commands_order = { "adduser", "passwd", "deluser", "start", "stop", "restart" }; local done = {};
--- a/tests/test.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/test.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/tests/test_core_configmanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/test_core_configmanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/tests/test_core_modulemanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/test_core_modulemanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/tests/test_core_s2smanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/test_core_s2smanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -30,18 +30,18 @@ assert_equal(csp(r3, r2), false); assert_equal(csp(r3, r3), false); assert_equal(csp(r3, r4), false); - assert_equal(csp(r3, r5), true); + assert_equal(csp(r3, r5), false); assert_equal(csp(r4, r1), false); assert_equal(csp(r4, r2), false); assert_equal(csp(r4, r3), false); assert_equal(csp(r4, r4), false); - assert_equal(csp(r4, r5), true); + assert_equal(csp(r4, r5), false); assert_equal(csp(r5, r1), false); assert_equal(csp(r5, r2), false); - assert_equal(csp(r5, r3), false); - assert_equal(csp(r5, r4), false); + assert_equal(csp(r5, r3), true); + assert_equal(csp(r5, r4), true); assert_equal(csp(r5, r5), false); end
--- a/tests/test_core_stanza_router.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/test_core_stanza_router.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/tests/test_sasl.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/test_sasl.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/tests/test_util_jid.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/test_util_jid.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/tests/test_util_multitable.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/test_util_multitable.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/tests/test_util_stanza.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/test_util_stanza.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/tests/util/logger.lua Fri May 21 19:44:31 2010 +0100 +++ b/tests/util/logger.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/tools/ejabberd2prosody.lua Fri May 21 19:44:31 2010 +0100 +++ b/tools/ejabberd2prosody.lua Fri May 21 19:45:33 2010 +0100 @@ -1,7 +1,7 @@ #!/usr/bin/env lua -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -17,6 +17,8 @@ require "erlparse"; +prosody = {}; + local serialize = require "util.serialization".serialize; local st = require "util.stanza"; package.loaded["util.logger"] = {init = function() return function() end; end} @@ -49,7 +51,7 @@ end function password(node, host, password) local ret, err = dm.store(node, host, "accounts", {password = password}); - print("["..(err or "success").."] accounts: "..node.."@"..host.." = "..password); + print("["..(err or "success").."] accounts: "..node.."@"..host); end function roster(node, host, jid, item) local roster = dm.load(node, host, "roster") or {};
--- a/tools/ejabberdsql2prosody.lua Fri May 21 19:44:31 2010 +0100 +++ b/tools/ejabberdsql2prosody.lua Fri May 21 19:45:33 2010 +0100 @@ -1,7 +1,7 @@ #!/usr/bin/env lua -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -254,7 +254,7 @@ for i, row in ipairs(t["users"] or NULL) do local node, password = row.username, row.password; local ret, err = dm.store(node, host, "accounts", {password = password}); - print("["..(err or "success").."] accounts: "..node.."@"..host.." = "..password); + print("["..(err or "success").."] accounts: "..node.."@"..host); end function roster(node, host, jid, item)
--- a/tools/erlparse.lua Fri May 21 19:44:31 2010 +0100 +++ b/tools/erlparse.lua Fri May 21 19:45:33 2010 +0100 @@ -1,21 +1,27 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. -- - +local string_byte, string_char = string.byte, string.char; +local t_concat, t_insert = table.concat, table.insert; +local type, tonumber, tostring = type, tonumber, tostring; local file = nil; local last = nil; +local line = 1; local function read(expected) local ch; if last then ch = last; last = nil; - else ch = file:read(1); end - if expected and ch ~= expected then error("expected: "..expected.."; got: "..(ch or "nil")); end + else + ch = file:read(1); + if ch == "\n" then line = line + 1; end + end + if expected and ch ~= expected then error("expected: "..expected.."; got: "..(ch or "nil").." on line "..line); end return ch; end local function pushback(ch) @@ -27,21 +33,21 @@ return last; end -local _A, _a, _Z, _z, _0, _9, __, _at, _space = string.byte("AaZz09@_ ", 1, 9); +local _A, _a, _Z, _z, _0, _9, __, _at, _space, _minus = string_byte("AaZz09@_ -", 1, 10); local function isLowerAlpha(ch) - ch = string.byte(ch) or 0; + ch = string_byte(ch) or 0; return (ch >= _a and ch <= _z); end local function isNumeric(ch) - ch = string.byte(ch) or 0; - return (ch >= _0 and ch <= _9); + ch = string_byte(ch) or 0; + return (ch >= _0 and ch <= _9) or ch == _minus; end local function isAtom(ch) - ch = string.byte(ch) or 0; + ch = string_byte(ch) or 0; return (ch >= _A and ch <= _Z) or (ch >= _a and ch <= _z) or (ch >= _0 and ch <= _9) or ch == __ or ch == _at; end local function isSpace(ch) - ch = string.byte(ch) or "x"; + ch = string_byte(ch) or "x"; return ch <= _space; end @@ -49,79 +55,85 @@ local function readString() read("\""); -- skip quote local slash = nil; - local str = ""; + local str = {}; while true do local ch = read(); if slash then slash = slash..ch; if not escapes[slash] then error("Unknown escape sequence: "..slash); end - str = str..escapes[slash]; + str[#str+1] = escapes[slash]; slash = nil; elseif ch == "\"" then break; elseif ch == "\\" then slash = ch; else - str = str..ch; + str[#str+1] = ch; end end - return str; + return t_concat(str); end local function readAtom1() - local var = read(); + local var = { read() }; while isAtom(peek()) do - var = var..read(); + var[#var+1] = read(); end - return var; + return t_concat(var); end local function readAtom2() - local str = read("'"); + local str = { read("'") }; local slash = nil; while true do local ch = read(); - str = str..ch; + str[#str+1] = ch; if ch == "'" and not slash then break; end end - return str; + return t_concat(str); end local function readNumber() - local num = read(); + local num = { read() }; while isNumeric(peek()) do - num = num..read(); + num[#num+1] = read(); end - return tonumber(num); + return tonumber(t_concat(num)); end local readItem = nil; local function readTuple() local t = {}; - local s = ""; -- string representation + local s = {}; -- string representation read(); -- read {, or [, or < while true do local item = readItem(); if not item then break; end - if type(item) ~= type(0) or item > 255 then + if type(item) ~= "number" or item > 255 then s = nil; elseif s then - s = s..string.char(item); + s[#s+1] = string_char(item); end - table.insert(t, item); + t_insert(t, item); end read(); -- read }, or ], or > - if s and s ~= "" then - return s + if s and #s > 0 then + return t_concat(s) else return t end; end local function readBinary() read("<"); -- read < + -- Discard PIDs + if isNumeric(peek()) then + while peek() ~= ">" do read(); end + read(">"); + return {}; + end local t = readTuple(); read(">") -- read > local ch = peek(); - if type(t) == type("") then + if type(t) == "string" then -- binary is a list of integers return t; - elseif type(t) == type({}) then + elseif type(t) == "table" then if t[1] then -- binary contains string return t[1];
--- a/util-src/encodings.c Fri May 21 19:44:31 2010 +0100 +++ b/util-src/encodings.c Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -/* Prosody IM v0.4 --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +/* 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.
--- a/util-src/hashes.c Fri May 21 19:44:31 2010 +0100 +++ b/util-src/hashes.c Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -/* Prosody IM v0.4 --- Copyright (C) 2008 Matthew Wild --- Copyright (C) 2008 Waqas Hussain +/* Prosody IM +-- Copyright (C) 2009-2010 Matthew Wild +-- Copyright (C) 2009-2010 Waqas Hussain -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information.
--- a/util-src/pposix.c Fri May 21 19:44:31 2010 +0100 +++ b/util-src/pposix.c Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -/* Prosody IM v0.4 --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +/* Prosody IM +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain -- Copyright (C) 2009 Tobias Markmann -- -- This project is MIT/X11 licensed. Please see the
--- a/util-src/windows.c Fri May 21 19:44:31 2010 +0100 +++ b/util-src/windows.c Fri May 21 19:45:33 2010 +0100 @@ -1,45 +1,58 @@ - -#include <stdio.h> -#include <windows.h> -#include <windns.h> - -#include "lua.h" -#include "lauxlib.h" - -static int Lget_nameservers(lua_State *L) { - char stack_buffer[1024]; // stack allocated buffer - IP4_ARRAY* ips = (IP4_ARRAY*) stack_buffer; - DWORD len = sizeof(stack_buffer); - DNS_STATUS status; - - status = DnsQueryConfig(DnsConfigDnsServerList, FALSE, NULL, NULL, ips, &len); - if (status == 0) { - DWORD i; - lua_createtable(L, ips->AddrCount, 0); - for (i = 0; i < ips->AddrCount; i++) { - DWORD ip = ips->AddrArray[i]; - char ip_str[16] = ""; - sprintf_s(ip_str, sizeof(ip_str), "%d.%d.%d.%d", (ip >> 0) & 255, (ip >> 8) & 255, (ip >> 16) & 255, (ip >> 24) & 255); - lua_pushstring(L, ip_str); - lua_rawseti(L, -2, i+1); - } - return 1; - } else { - luaL_error(L, "DnsQueryConfig returned %d", status); - return 0; // unreachable, but prevents a compiler warning - } -} - -static const luaL_Reg Reg[] = -{ - { "get_nameservers", Lget_nameservers }, - { NULL, NULL } -}; - -LUALIB_API int luaopen_util_windows(lua_State *L) { - luaL_register(L, "windows", Reg); - lua_pushliteral(L, "version"); /** version */ - lua_pushliteral(L, "-3.14"); - lua_settable(L,-3); - return 1; -} +/* 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. +-- +*/ + +/* +* windows.c +* Windows support functions for Lua +*/ + +#include <stdio.h> +#include <windows.h> +#include <windns.h> + +#include "lua.h" +#include "lauxlib.h" + +static int Lget_nameservers(lua_State *L) { + char stack_buffer[1024]; // stack allocated buffer + IP4_ARRAY* ips = (IP4_ARRAY*) stack_buffer; + DWORD len = sizeof(stack_buffer); + DNS_STATUS status; + + status = DnsQueryConfig(DnsConfigDnsServerList, FALSE, NULL, NULL, ips, &len); + if (status == 0) { + DWORD i; + lua_createtable(L, ips->AddrCount, 0); + for (i = 0; i < ips->AddrCount; i++) { + DWORD ip = ips->AddrArray[i]; + char ip_str[16] = ""; + sprintf_s(ip_str, sizeof(ip_str), "%d.%d.%d.%d", (ip >> 0) & 255, (ip >> 8) & 255, (ip >> 16) & 255, (ip >> 24) & 255); + lua_pushstring(L, ip_str); + lua_rawseti(L, -2, i+1); + } + return 1; + } else { + luaL_error(L, "DnsQueryConfig returned %d", status); + return 0; // unreachable, but prevents a compiler warning + } +} + +static const luaL_Reg Reg[] = +{ + { "get_nameservers", Lget_nameservers }, + { NULL, NULL } +}; + +LUALIB_API int luaopen_util_windows(lua_State *L) { + luaL_register(L, "windows", Reg); + lua_pushliteral(L, "version"); /** version */ + lua_pushliteral(L, "-3.14"); + lua_settable(L,-3); + return 1; +}
--- a/util/array.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/array.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/broadcast.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/broadcast.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/dataforms.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/dataforms.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/datamanager.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/datamanager.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/datetime.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/datetime.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/dependencies.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/dependencies.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/events.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/events.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/helpers.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/helpers.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/hmac.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/hmac.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/import.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/import.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/iterators.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/iterators.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/jid.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/jid.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/logger.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/logger.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/multitable.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/multitable.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/pluginloader.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/pluginloader.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/prosodyctl.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/prosodyctl.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/sasl.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/sasl.lua Fri May 21 19:45:33 2010 +0100 @@ -1,5 +1,5 @@ -- sasl.lua v0.4 --- Copyright (C) 2008-2009 Tobias Markmann +-- Copyright (C) 2008-2010 Tobias Markmann -- -- All rights reserved. -- @@ -143,7 +143,7 @@ end -- load the mechanisms -load_mechs = {"plain", "digest-md5", "anonymous", "scram"} +local load_mechs = {"plain", "digest-md5", "anonymous", "scram"} for _, mech in ipairs(load_mechs) do local name = "util.sasl."..mech; local m = require(name);
--- a/util/sasl/digest-md5.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/sasl/digest-md5.lua Fri May 21 19:45:33 2010 +0100 @@ -35,8 +35,6 @@ local function serialize(message) local data = "" - if type(message) ~= "table" then error("serialize needs an argument of type table.") end - -- testing all possible values if message["realm"] then data = data..[[realm="]]..message.realm..[[",]] end if message["nonce"] then data = data..[[nonce="]]..message.nonce..[[",]] end
--- a/util/sasl/scram.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/sasl/scram.lua Fri May 21 19:45:33 2010 +0100 @@ -15,7 +15,6 @@ local type = type local string = string local base64 = require "util.encodings".base64; -local xor = require "bit".bxor local hmac_sha1 = require "util.hmac".sha1; local sha1 = require "util.hashes".sha1; local generate_uuid = require "util.uuid".generate;
--- a/util/sasl_cyrus.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/sasl_cyrus.lua Fri May 21 19:45:33 2010 +0100 @@ -39,24 +39,37 @@ if st then initialized = true; else - log("error", "Failed to initialize CyrusSASL: %s", errmsg); + log("error", "Failed to initialize Cyrus SASL: %s", errmsg); end end end -- create a new SASL object which can be used to authenticate clients -function new(realm, service_name) +function new(realm, service_name, app_name) local sasl_i = {}; - init(service_name); + init(app_name or service_name); sasl_i.realm = realm; sasl_i.service_name = service_name; - sasl_i.cyrus = cyrussasl.server_new(service_name, nil, nil, nil, nil) - if sasl_i.cyrus == 0 then - log("error", "got NULL return value from server_new") + + local st, ret = pcall(cyrussasl.server_new, service_name, nil, realm, nil, nil) + if st then + sasl_i.cyrus = ret; + else + log("error", "Creating SASL server connection failed: %s", ret); return nil; end + + if cyrussasl.set_canon_cb then + local c14n_cb = function (user) + local node = s_match(user, "^([^@]+)"); + log("debug", "Canonicalizing username %s to %s", user, node) + return node + end + cyrussasl.set_canon_cb(sasl_i.cyrus, c14n_cb); + end + cyrussasl.setssf(sasl_i.cyrus, 0, 0xffffffff) local s = setmetatable(sasl_i, method); return s; @@ -69,7 +82,7 @@ -- set the forbidden mechanisms function method:forbidden( restrict ) - log("debug", "Called method:forbidden. NOT IMPLEMENTED.") + log("warn", "Called method:forbidden. NOT IMPLEMENTED.") return {} end @@ -87,6 +100,7 @@ -- select a mechanism to use function method:select(mechanism) self.mechanism = mechanism; + if not self.mechs then self:mechanisms(); end return self.mechs[mechanism]; end @@ -109,16 +123,12 @@ return "challenge", data elseif (err == -4) then -- SASL_NOMECH log("debug", "SASL mechanism not available from remote end") - return "failure", - "undefined-condition", - "SASL mechanism not available" + return "failure", "invalid-mechanism", "SASL mechanism not available" elseif (err == -13) then -- SASL_BADAUTH return "failure", "not-authorized", cyrussasl.get_message( self.cyrus ) else log("debug", "Got SASL error condition %d", err) - return "failure", - "undefined-condition", - cyrussasl.get_message( self.cyrus ) + return "failure", "undefined-condition", cyrussasl.get_message( self.cyrus ) end end
--- a/util/serialization.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/serialization.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/set.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/set.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/stanza.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/stanza.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -247,14 +247,14 @@ for i=1,#attr do attr[i] = nil; end local attrx = {}; for att in pairs(attr) do - if s_find(att, "|", 1, true) and not s_find(k, "\1", 1, true) then - local ns,na = s_match(k, "^([^|]+)|(.+)$"); + if s_find(att, "|", 1, true) and not s_find(att, "\1", 1, true) then + local ns,na = s_match(att, "^([^|]+)|(.+)$"); attrx[ns.."\1"..na] = attr[att]; attr[att] = nil; end end for a,v in pairs(attrx) do - attr[x] = v; + attr[a] = v; end setmetatable(stanza, stanza_mt); for _, child in ipairs(stanza) do
--- a/util/termcolours.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/termcolours.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/timer.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/timer.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -55,11 +55,12 @@ else local EVENT_LEAVE = (event.core and event.core.LEAVE) or -1; function _add_task(delay, func) - event_base:addevent(nil, 0, function () + local event_handle; + event_handle = event_base:addevent(nil, 0, function () local ret = func(); if ret then return 0, ret; - else + elseif event_handle then return EVENT_LEAVE; end end
--- a/util/uuid.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/uuid.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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. @@ -32,7 +32,7 @@ buffer = new_random(buffer..x); end local function get_nibbles(n) - if #buffer < n then seed(uniq_time()); end + if #buffer < n then _seed(uniq_time()); end local r = buffer:sub(0, n); buffer = buffer:sub(n+1); return r;
--- a/util/xmlrpc.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/xmlrpc.lua Fri May 21 19:45:33 2010 +0100 @@ -1,6 +1,6 @@ -- Prosody IM --- Copyright (C) 2008-2009 Matthew Wild --- Copyright (C) 2008-2009 Waqas Hussain +-- 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.
--- a/util/ztact.lua Fri May 21 19:44:31 2010 +0100 +++ b/util/ztact.lua Fri May 21 19:45:33 2010 +0100 @@ -114,7 +114,7 @@ function tostring_r (d, indent, tab0) -- - - - - - - - - - - - - tostring_r - tab1 = tab0 or {} + local tab1 = tab0 or {} local rep = string.rep (' ', indent or 0) if type (d) == 'table' then for k,v in pairs (d) do @@ -210,7 +210,7 @@ local function test_queue () - t = {} + local t = {} enqueue (t, 1) enqueue (t, 2) enqueue (t, 3)