diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/mod_console.lua | 29 | ||||
-rw-r--r-- | plugins/mod_muc.lua | 3 | ||||
-rw-r--r-- | plugins/mod_saslauth.lua | 57 | ||||
-rw-r--r-- | plugins/mod_xmlrpc.lua | 30 |
4 files changed, 82 insertions, 37 deletions
diff --git a/plugins/mod_console.lua b/plugins/mod_console.lua index a3ed9499..367c46b8 100644 --- a/plugins/mod_console.lua +++ b/plugins/mod_console.lua @@ -70,6 +70,9 @@ function console_listener.listener(conn, data) 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"); @@ -205,7 +208,8 @@ end -- Anything in def_env will be accessible within the session as a global variable def_env.server = {}; -function def_env.server:reload() + +function def_env.server:insane_reload() prosody.unlock_globals(); dofile "prosody" prosody = _G.prosody; @@ -230,6 +234,11 @@ function def_env.server:uptime() minutes, (minutes ~= 1 and "s") or "", os.date("%c", prosody.start_time)); end +function def_env.server:shutdown(reason) + prosody.shutdown(reason); + return true, "Shutdown initiated"; +end + def_env.module = {}; local function get_hosts_set(hosts, module) @@ -333,6 +342,11 @@ function def_env.config:get(host, section, key) return true, tostring(config_get(host, section, key)); end +function def_env.config:reload() + local ok, err = prosody.reload_config(); + return ok, (ok and "Config reloaded (you may need to reload modules to take effect)") or tostring(err); +end + def_env.hosts = {}; function def_env.hosts:list() for host, host_session in pairs(hosts) do @@ -359,10 +373,19 @@ end function def_env.c2s:show(match_jid) local print, count = self.session.print, 0; - show_c2s(function (jid) + show_c2s(function (jid, session) if (not match_jid) or jid:match(match_jid) then count = count + 1; - print(jid); + local status, priority = "unavailable", tostring(session.priority or "-"); + if session.presence then + status = session.presence:child_with_name("show"); + if status then + status = status:get_text() or "[invalid!]"; + else + status = "available"; + end + end + print(jid.." - "..status.."("..priority..")"); end end); return true, "Total: "..count.." clients"; diff --git a/plugins/mod_muc.lua b/plugins/mod_muc.lua index e99ef83c..b38468ea 100644 --- a/plugins/mod_muc.lua +++ b/plugins/mod_muc.lua @@ -76,6 +76,8 @@ component = register_component(muc_host, function(origin, stanza) handle_to_domain(origin, stanza); end); +prosody.hosts[module:get_host()].muc = { rooms = rooms }; + module.unload = function() deregister_component(muc_host); end @@ -84,4 +86,5 @@ module.save = function() end module.restore = function(data) rooms = data.rooms or {}; + prosody.hosts[module:get_host()].muc = { rooms = rooms }; end diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index 8d1e0529..8d3b4ae4 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -1,7 +1,7 @@ -- 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. -- @@ -15,6 +15,9 @@ local base64 = require "util.encodings".base64; local datamanager_load = require "util.datamanager".load; local usermanager_validate_credentials = require "core.usermanager".validate_credentials; +local usermanager_get_supported_methods = require "core.usermanager".get_supported_methods; +local usermanager_user_exists = require "core.usermanager".user_exists; +local usermanager_get_password = require "core.usermanager".get_password; local t_concat, t_insert = table.concat, table.insert; local tostring = tostring; local jid_split = require "util.jid".split @@ -57,25 +60,35 @@ local function handle_status(session, status) session.sasl_handler = nil; session:reset_stream(); return; - end + end sm_make_authenticated(session, session.sasl_handler.username); session.sasl_handler = nil; session:reset_stream(); end end -local function password_callback(node, hostname, realm, mechanism, decoder) - local password = (datamanager_load(node, hostname, "accounts") or {}).password; -- FIXME handle hashed passwords - local func = function(x) return x; end; - if password then - if mechanism == "PLAIN" then - return func, password; - elseif mechanism == "DIGEST-MD5" then - if decoder then node, realm, password = decoder(node), decoder(realm), decoder(password); end +local function credentials_callback(mechanism, ...) + if mechanism == "PLAIN" then + local username, hostname, password = ...; + local response = usermanager_validate_credentials(hostname, username, password, mechanism); + if response == nil then + return false; + else + return response; + end + elseif mechanism == "DIGEST-MD5" then + function func(x) return x; end + local node, domain, realm, decoder = ...; + local password = usermanager_get_password(node, domain); + if password then + if decoder then + node, realm, password = decoder(node), decoder(realm), decoder(password); + end return func, md5(node..":"..realm..":"..password); + else + return func, nil; end end - return func, nil; end local function sasl_handler(session, stanza) @@ -88,7 +101,7 @@ local function sasl_handler(session, stanza) elseif stanza.attr.mechanism == "ANONYMOUS" then return session.send(build_reply("failure", "mechanism-too-weak")); end - session.sasl_handler = new_sasl(stanza.attr.mechanism, session.host, password_callback); + session.sasl_handler = new_sasl(stanza.attr.mechanism, session.host, credentials_callback); if not session.sasl_handler then return session.send(build_reply("failure", "invalid-mechanism")); end @@ -107,7 +120,7 @@ local function sasl_handler(session, stanza) end local status, ret, err_msg = session.sasl_handler:feed(text); handle_status(session, status); - local s = build_reply(status, ret, err_msg); + local s = build_reply(status, ret, err_msg); log("debug", "sasl reply: %s", tostring(s)); session.send(s); end @@ -119,8 +132,8 @@ module: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' }; -module:add_event_hook("stream-features", - function (session, features) +module:add_event_hook("stream-features", + function (session, features) if not session.username then if secure_auth_only and not session.secure then return; @@ -130,8 +143,10 @@ module:add_event_hook("stream-features", if config.get(session.host or "*", "core", "anonymous_login") then features:tag("mechanism"):text("ANONYMOUS"):up(); else - features:tag("mechanism"):text("DIGEST-MD5"):up(); - features:tag("mechanism"):text("PLAIN"):up(); + mechanisms = usermanager_get_supported_methods(session.host or "*"); + for k, v in pairs(mechanisms) do + features:tag("mechanism"):text(k):up(); + end end features:up(); else @@ -139,8 +154,8 @@ module:add_event_hook("stream-features", features:tag("session", xmpp_session_attr):up(); end end); - -module:add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-bind", + +module:add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-bind", function (session, stanza) log("debug", "Client requesting a resource bind"); local resource; @@ -162,8 +177,8 @@ module:add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-bind", :tag("jid"):text(session.full_jid)); end end); - -module:add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-session", + +module:add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-session", function (session, stanza) log("debug", "Client requesting a session"); session.send(st.reply(stanza)); diff --git a/plugins/mod_xmlrpc.lua b/plugins/mod_xmlrpc.lua index 46edcaee..7165386a 100644 --- a/plugins/mod_xmlrpc.lua +++ b/plugins/mod_xmlrpc.lua @@ -16,6 +16,7 @@ local unpack = unpack; local tostring = tostring; local is_admin = require "core.usermanager".is_admin; local jid_split = require "util.jid".split; +local jid_bare = require "util.jid".bare; local b64_decode = require "util.encodings".base64.decode; local get_method = require "core.objectmanager".get_object; local validate_credentials = require "core.usermanager".validate_credentials; @@ -65,10 +66,15 @@ local function parse_xml(xml) return stanza.tags[1]; end -local function handle_xmlrpc_request(method, args) +local function handle_xmlrpc_request(jid, method, args) + local is_secure_call = (method:sub(1,7) == "secure/"); + if not is_admin(jid) and not is_secure_call then + return create_error_response(401, "not authorized"); + end method = get_method(method); if not method then return create_error_response(404, "method not found"); end args = args or {}; + if is_secure_call then table.insert(args, 1, jid); end local success, result = pcall(method, unpack(args)); if success then success, result = pcall(create_response, result or "nil"); @@ -77,22 +83,20 @@ local function handle_xmlrpc_request(method, args) end return create_error_response(500, "Error in creating response: "..result); end - return create_error_response(0, result or "nil"); + return create_error_response(0, tostring(result):gsub("^[^:]+:%d+: ", "")); end local function handle_xmpp_request(origin, stanza) local query = stanza.tags[1]; if query.name == "query" then if #query.tags == 1 then - if is_admin(stanza.attr.from) then - local success, method, args = pcall(translate_request, query.tags[1]); - if success then - local result = handle_xmlrpc_request(method, args); - origin.send(st.reply(stanza):tag('query', {xmlns='jabber:iq:rpc'}):add_child(result)); - else - origin.send(st.error_reply(stanza, "modify", "bad-request", method)); - end - else origin.send(st.error_reply(stanza, "auth", "forbidden", "No content in XML-RPC request")); end + local success, method, args = pcall(translate_request, query.tags[1]); + if success then + local result = handle_xmlrpc_request(jid_bare(stanza.attr.from), method, args); + origin.send(st.reply(stanza):tag('query', {xmlns='jabber:iq:rpc'}):add_child(result)); + else + origin.send(st.error_reply(stanza, "modify", "bad-request", method)); + end else origin.send(st.error_reply(stanza, "modify", "bad-request", "No content in XML-RPC request")); end else origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); end end @@ -106,7 +110,7 @@ local function handle_http_request(method, body, request) -- authenticate user local username, password = b64_decode(request['authorization'] or ''):gmatch('([^:]*):(.*)')(); -- TODO digest auth local node, host = jid_split(username); - if not validate_credentials(host, node, password) and is_admin(username) then + if not validate_credentials(host, node, password) then return unauthorized_response; end -- parse request @@ -117,7 +121,7 @@ local function handle_http_request(method, body, request) -- execute request local success, method, args = pcall(translate_request, stanza); if success then - return { headers = default_headers; body = tostring(handle_xmlrpc_request(method, args)) }; + return { headers = default_headers; body = tostring(handle_xmlrpc_request(node.."@"..host, method, args)) }; end return "<html><body>Error parsing XML-RPC request: "..tostring(method).."</body></html>"; end |