From 4293aefe659dc621166d492f8c91f7031c6774bd Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Mon, 17 Nov 2008 13:51:47 +0500 Subject: Send unsubscribe and unsubscribed on roster item delete, and broadcast available resources' presence in reply to pre-approved subscription request --- plugins/mod_roster.lua | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_roster.lua b/plugins/mod_roster.lua index 23a19828..24d858e7 100644 --- a/plugins/mod_roster.lua +++ b/plugins/mod_roster.lua @@ -4,6 +4,7 @@ local st = require "util.stanza" local jid_split = require "util.jid".split; local t_concat = table.concat; +local handle_outbound_presence_subscriptions_and_probes = require "core.presencemanager".handle_outbound_presence_subscriptions_and_probes; local rm_remove_from_roster = require "core.rostermanager".remove_from_roster; local rm_add_to_roster = require "core.rostermanager".add_to_roster; local rm_roster_push = require "core.rostermanager".roster_push; @@ -38,15 +39,25 @@ add_iq_handler("c2s", "jabber:iq:roster", and query.tags[1].attr.jid ~= "pending" then local item = query.tags[1]; local from_node, from_host = jid_split(stanza.attr.from); + local from_bare = from_node and (from_node.."@"..from_host) or from_host; -- bare JID local node, host, resource = jid_split(item.attr.jid); - if not resource then + local to_bare = node and (node.."@"..host) or host; -- bare JID + if not resource and host then if item.attr.jid ~= from_node.."@"..from_host then if item.attr.subscription == "remove" then - if session.roster[item.attr.jid] then + local r_item = session.roster[item.attr.jid]; + if r_item then local success, err_type, err_cond, err_msg = rm_remove_from_roster(session, item.attr.jid); if success then session.send(st.reply(stanza)); rm_roster_push(from_node, from_host, item.attr.jid); + if r_item.subscription == "both" or r_item.subscription == "from" then + handle_outbound_presence_subscriptions_and_probes(session, + st.presence({type="unsubscribed"}), from_bare, to_bare); + elseif r_item.subscription == "both" or r_item.subscription == "to" then + handle_outbound_presence_subscriptions_and_probes(session, + st.presence({type="unsubscribe"}), from_bare, to_bare); + end else session.send(st.error_reply(stanza, err_type, err_cond, err_msg)); end -- cgit v1.2.3 From 761c52771a80c3dd331ce4bc2da8c6490f118932 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 19 Nov 2008 21:07:40 +0000 Subject: Don't error if the original s2s connection has closed before we get the dialback result --- plugins/mod_dialback.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index c17cbcaf..d7697535 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -55,8 +55,12 @@ add_handler({ "s2sout_unauthed", "s2sout" }, "verify", xmlns_dialback, log("warn", "dialback for "..(origin.dialback_verifying.from_host or "(unknown)").." failed"); valid = "invalid"; end - origin.dialback_verifying.sends2s(format("%s", - attr.from, attr.to, attr.id, valid, origin.dialback_verifying.dialback_key)); + if not origin.dialback_verifying.sends2s then + log("warn", "Incoming s2s session was closed in the meantime, so we can't notify it of the db result"); + else + origin.dialback_verifying.sends2s(format("%s", + attr.from, attr.to, attr.id, valid, origin.dialback_verifying.dialback_key)); + end end end); -- cgit v1.2.3 From 762904eba2b816dd481947e12d46937619d2f323 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 19 Nov 2008 22:03:39 +0000 Subject: Show which session got disconnected in log message --- plugins/mod_dialback.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index d7697535..21769dd9 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -56,7 +56,7 @@ add_handler({ "s2sout_unauthed", "s2sout" }, "verify", xmlns_dialback, valid = "invalid"; end if not origin.dialback_verifying.sends2s then - log("warn", "Incoming s2s session was closed in the meantime, so we can't notify it of the db result"); + log("warn", "Incoming s2s session %s was closed in the meantime, so we can't notify it of the db result", tostring(origin.dialback_verifying):match("%w+$")); else origin.dialback_verifying.sends2s(format("%s", attr.from, attr.to, attr.id, valid, origin.dialback_verifying.dialback_key)); -- cgit v1.2.3 From ccb65fee139d73605b660e144a8f67ca6aaccf12 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Wed, 19 Nov 2008 23:18:12 +0000 Subject: Fix the reversed to/from on the final db:result. Fixes M-Link and Gmail. Thanks dwd!! --- plugins/mod_dialback.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_dialback.lua b/plugins/mod_dialback.lua index 21769dd9..87ac303b 100644 --- a/plugins/mod_dialback.lua +++ b/plugins/mod_dialback.lua @@ -59,7 +59,7 @@ add_handler({ "s2sout_unauthed", "s2sout" }, "verify", xmlns_dialback, log("warn", "Incoming s2s session %s was closed in the meantime, so we can't notify it of the db result", tostring(origin.dialback_verifying):match("%w+$")); else origin.dialback_verifying.sends2s(format("%s", - attr.from, attr.to, attr.id, valid, origin.dialback_verifying.dialback_key)); + attr.to, attr.from, attr.id, valid, origin.dialback_verifying.dialback_key)); end end end); -- cgit v1.2.3 From 5c7ec634b1765f8edcc8b59aff2b2b899180dc65 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 20 Nov 2008 01:33:25 +0000 Subject: Use a stanza for c2s stream features instead of an array of strings. Removes a FIXME. --- plugins/mod_saslauth.lua | 16 +++++++++------- plugins/mod_tls.lua | 3 ++- plugins/mod_vcard.lua | 3 ++- 3 files changed, 13 insertions(+), 9 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index 6ceb0be3..7ca4308b 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -83,19 +83,21 @@ add_handler("c2s_unauthed", "auth", xmlns_sasl, sasl_handler); add_handler("c2s_unauthed", "abort", xmlns_sasl, sasl_handler); add_handler("c2s_unauthed", "response", xmlns_sasl, sasl_handler); +local mechanisms_attr = { xmlns='urn:ietf:params:xml:ns:xmpp-sasl' }; +local bind_attr = { xmlns='urn:ietf:params:xml:ns:xmpp-bind' }; +local xmpp_session_attr = { xmlns='urn:ietf:params:xml:ns:xmpp-session' }; add_event_hook("stream-features", function (session, features) if not session.username then - t_insert(features, ""); + features:tag("mechanisms", mechanisms_attr); -- TODO: Provide PLAIN only if TLS is active, this is a SHOULD from the introduction of RFC 4616. This behavior could be overridden via configuration but will issuing a warning or so. - t_insert(features, "PLAIN"); - t_insert(features, "DIGEST-MD5"); - t_insert(features, ""); + features:tag("mechanism"):text("PLAIN"):up(); + features:tag("mechanism"):text("DIGEST-MD5"):up(); + features:up(); else - t_insert(features, ""); - t_insert(features, ""); + features:tag("bind", bind_attr):tag("required"):up():up(); + features:tag("session", xmpp_session_attr):up(); end - --send [[ ]] end); add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-bind", diff --git a/plugins/mod_tls.lua b/plugins/mod_tls.lua index b5ca5015..cc46d556 100644 --- a/plugins/mod_tls.lua +++ b/plugins/mod_tls.lua @@ -24,9 +24,10 @@ add_handler("c2s_unauthed", "starttls", xmlns_starttls, end end); +local starttls_attr = { xmlns = xmlns_starttls }; add_event_hook("stream-features", function (session, features) if session.conn.starttls then - t_insert(features, ""); + features:tag("starttls", starttls_attr):up(); end end); diff --git a/plugins/mod_vcard.lua b/plugins/mod_vcard.lua index fb7382c2..d2f2c7ba 100644 --- a/plugins/mod_vcard.lua +++ b/plugins/mod_vcard.lua @@ -43,9 +43,10 @@ add_iq_handler({"c2s", "s2sin"}, "vcard-temp", end end); +local feature_vcard_attr = { var='vcard-temp' }; add_event_hook("stream-features", function (session, features) if session.type == "c2s" then - t_insert(features, ""); + features:tag("feature", feature_vcard_attr):up(); end end); -- cgit v1.2.3 From 902d98e4865d92ebeea81c0ddcb5a38fa63d1162 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 20 Nov 2008 22:42:37 +0000 Subject: Adding selftests module, but not enabling in config --- plugins/mod_selftests.lua | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 plugins/mod_selftests.lua (limited to 'plugins') diff --git a/plugins/mod_selftests.lua b/plugins/mod_selftests.lua new file mode 100644 index 00000000..fe09e529 --- /dev/null +++ b/plugins/mod_selftests.lua @@ -0,0 +1,57 @@ + +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 open_pings = {}; + +local t_insert = table.insert; + +local log = require "util.logger".init("mod_selftests"); + +local tests_jid, host; "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]; + 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 + + send_ping "matthewwild.co.uk" + send_ping "snikket.com" + send_ping "gmail.com" + send_ping "isode.com" + send_ping "jabber.org" + send_ping "chrome.pl" + send_ping "swissjabber.ch" + send_ping "soapbox.net" + send_ping "jabber.ccc.de" + end); +end -- cgit v1.2.3 From 799f8f6a6eb9bc20b6a7a47eb4ff55ecabf14820 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sun, 23 Nov 2008 03:31:03 +0500 Subject: Account deletion support --- plugins/mod_register.lua | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/mod_register.lua b/plugins/mod_register.lua index fb001392..c2b85bae 100644 --- a/plugins/mod_register.lua +++ b/plugins/mod_register.lua @@ -2,6 +2,7 @@ local st = require "util.stanza"; local usermanager_user_exists = require "core.usermanager".user_exists; local usermanager_create_user = require "core.usermanager".create_user; +local datamanager_store = require "util.datamanager".store; add_iq_handler("c2s", "jabber:iq:register", function (session, stanza) if stanza.tags[1].name == "query" then @@ -16,7 +17,33 @@ add_iq_handler("c2s", "jabber:iq:register", function (session, stanza) elseif stanza.attr.type == "set" then if query.tags[1] and query.tags[1].name == "remove" then -- TODO delete user auth data, send iq response, kick all user resources with a , delete all user data - session.send(st.error_reply(stanza, "cancel", "not-allowed")); + --session.send(st.error_reply(stanza, "cancel", "not-allowed")); + --return; + usermanager_create_user(session.username, nil, session.host); -- 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)); + local roster = session.roster; + for _, session in pairs(hosts[session.host].sessions[session.username].sessions) do -- disconnect all resources + session:disconnect({condition = "not-authorized", text = "Account deleted"}); + end + -- TODO datamanager should be able to delete all user data itself + datamanager.store(session.username, session.host, "roster", nil); + datamanager.store(session.username, session.host, "vCard", nil); + datamanager.store(session.username, session.host, "private", nil); + datamanager.store(session.username, session.host, "offline", nil); + local bare = session.username.."@"..session.host; + for jid, item in pairs(roster) do + if jid ~= "pending" then + if item.subscription == "both" or item.subscription == "to" then + -- TODO unsubscribe + end + if item.subscription == "both" or item.subscription == "from" then + -- TODO unsubscribe + end + end + end + datamanager.store(session.username, session.host, "accounts", nil); -- delete accounts datastore at the end else local username = query:child_with_name("username"); local password = query:child_with_name("password"); -- cgit v1.2.3 From 43c503330db3d5b1613c1babcd5ef150d2ccf247 Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Sun, 23 Nov 2008 03:32:57 +0500 Subject: Added mod_disco --- plugins/mod_disco.lua | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 plugins/mod_disco.lua (limited to 'plugins') diff --git a/plugins/mod_disco.lua b/plugins/mod_disco.lua new file mode 100644 index 00000000..261650ce --- /dev/null +++ b/plugins/mod_disco.lua @@ -0,0 +1,9 @@ + +local discomanager_handle = require "core.discomanager".handle; + +add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#info", function (session, stanza) + session.send(discomanager_handle(stanza)); +end); +add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#items", function (session, stanza) + session.send(discomanager_handle(stanza)); +end); -- cgit v1.2.3 From a7b3157e9ff6d26b7218931646f6e02ed6063be8 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 23 Nov 2008 02:11:58 +0000 Subject: Fix mod_selftests syntax, and switch it to use config --- plugins/mod_selftests.lua | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'plugins') diff --git a/plugins/mod_selftests.lua b/plugins/mod_selftests.lua index fe09e529..4f128504 100644 --- a/plugins/mod_selftests.lua +++ b/plugins/mod_selftests.lua @@ -3,6 +3,8 @@ 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 config = require "core.configmanager"; +local ping_hosts = config.get("*", "mod_selftests", "ping_hosts") or { "jabber.org" }; local open_pings = {}; @@ -10,7 +12,7 @@ local t_insert = table.insert; local log = require "util.logger".init("mod_selftests"); -local tests_jid, host; "self_tests@getjabber.ath.cx"; +local tests_jid = "self_tests@getjabber.ath.cx"; local host = "getjabber.ath.cx"; if not (tests_jid and host) then @@ -44,14 +46,8 @@ if tests_jid and host then open_pings[id] = socket.gettime(); end - send_ping "matthewwild.co.uk" - send_ping "snikket.com" - send_ping "gmail.com" - send_ping "isode.com" - send_ping "jabber.org" - send_ping "chrome.pl" - send_ping "swissjabber.ch" - send_ping "soapbox.net" - send_ping "jabber.ccc.de" + for _, host in ipairs(ping_hosts) do + send_ping(host); + end end); end -- cgit v1.2.3 From 63554918e90c5f711e199c6fd08021a1944b866f Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 23 Nov 2008 04:54:44 +0000 Subject: Add initial mod_console --- plugins/mod_console.lua | 140 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 plugins/mod_console.lua (limited to 'plugins') diff --git a/plugins/mod_console.lua b/plugins/mod_console.lua new file mode 100644 index 00000000..5787ad25 --- /dev/null +++ b/plugins/mod_console.lua @@ -0,0 +1,140 @@ + +local connlisteners_register = require "net.connlisteners".register; + +local console_listener = { default_port = 5582; default_mode = "*l"; }; + +local commands = {}; +local default_env = {}; +local default_env_mt = { __index = default_env }; + +console = {}; + +function console:new_session(conn) + local w = conn.write; + return { conn = conn; + send = function (t) w(tostring(t)); end; + print = function (t) w("| "..tostring(t).."\n"); end; + disconnect = function () conn.close(); end; + env = setmetatable({}, default_env_mt); + }; +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; + session.print("Welcome to the lxmppd admin console!"); + end + if data then + -- Handle 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 + + 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("''", "the end of the line"); + session.print("Sorry, I couldn't understand that... "..err); + return; + end + end + + setfenv(chunk, session.env); + local ranok, taskok, message = pcall(chunk); + + 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 +end + +function console_listener.disconnect(conn, err) + +end + +connlisteners_register('console', console_listener); + +-- 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 + +-- Session environment -- +-- Anything in default_env will be accessible within the session as a global variable + +default_env.server = {}; +function default_env.server.reload() + dofile "main.lua" + return true, "Server reloaded"; +end + +default_env.module = {}; +function default_env.module.load(name) + local mm = require "modulemanager"; + local ok, err = mm.load(name); + if not ok then + return false, err or "Unknown error loading module"; + end + return true, "Module loaded"; +end + +default_env.config = {}; +function default_env.config.load(filename, format) + local cfgm_load = require "core.configmanager".load; + local ok, err = cfgm_load(filename, format); + if not ok then + return false, err or "Unknown error loading config"; + end + return true, "Config loaded"; +end -- cgit v1.2.3