From 6db3d039b3d8d55c9e03ebdc776cf1a23dd826c2 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 2 Oct 2008 01:08:58 +0100 Subject: SASL! (but before you get too excited, no resource binding yet. And yes, there are still plenty of rough edges to the code...) ((eg. must move out of xmlhandlers.lua o_O )) --- core/modulemanager.lua | 29 +++++++++++++++++++++-------- core/sessionmanager.lua | 39 ++++++++++++++++++++++++++++++++++++++- core/usermanager.lua | 2 ++ core/xmlhandlers.lua | 20 ++++++++++++++------ 4 files changed, 75 insertions(+), 15 deletions(-) (limited to 'core') diff --git a/core/modulemanager.lua b/core/modulemanager.lua index ed70b75b..ad92b41b 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -23,19 +23,25 @@ function modulehelpers.add_iq_handler(origin_type, xmlns, handler) if not handlers[origin_type].iq[xmlns] then handlers[origin_type].iq[xmlns]= handler; handler_info[handler] = getfenv(2).module; - log("debug", "mod_%s now handles iq,%s", getfenv(2).module.name, xmlns); + log("debug", "mod_%s now handles tag 'iq' with query namespace '%s'", getfenv(2).module.name, xmlns); else - log("warning", "mod_%s wants to handle iq,%s but mod_%s already handles that", getfenv(2).module.name, xmlns, handler_info[handlers[origin_type].iq[xmlns]].module.name); + log("warning", "mod_%s wants to handle tag 'iq' with query namespace '%s' but mod_%s already handles that", getfenv(2).module.name, xmlns, handler_info[handlers[origin_type].iq[xmlns]].module.name); end end -function modulehelpers.add_presence_handler(origin_type, handler) -end - -function modulehelpers.add_message_handler(origin_type, handler) +function modulehelpers.add_handler(origin_type, tag, handler) + handlers[origin_type] = handlers[origin_type] or {}; + if not handlers[origin_type][tag] then + handlers[origin_type][tag]= handler; + handler_info[handler] = getfenv(2).module; + log("debug", "mod_%s now handles tag '%s'", getfenv(2).module.name, tag); + elseif handler_info[handlers[origin_type][tag]] then + log("warning", "mod_%s wants to handle tag '%s' but mod_%s already handles that", getfenv(2).module.name, tag, handler_info[handlers[origin_type][tag]].module.name); + end end function loadall() + load("saslauth"); load("legacyauth"); load("roster"); end @@ -58,9 +64,9 @@ function load(name) end function handle_stanza(origin, stanza) - local name, origin_type = stanza.name, origin.type; + local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns, origin.type; - if name == "iq" then + if name == "iq" and xmlns == "jabber:client" and handlers[origin_type] then log("debug", "Stanza is an "); local child = stanza.tags[1]; if child then @@ -73,6 +79,13 @@ function handle_stanza(origin, stanza) end end + --FIXME: All iq's must be replied to, here we should return service-unavailable I think + elseif handlers[origin_type] then + local handler = handlers[origin_type][name]; + if handler then + log("debug", "Passing stanza to mod_%s", handler_info[handler].name); + return handler(origin, stanza) or true; + end end log("debug", "Stanza unhandled by any modules"); return false; -- we didn't handle it diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua index 47f47ba9..e89de262 100644 --- a/core/sessionmanager.lua +++ b/core/sessionmanager.lua @@ -1,6 +1,10 @@ local tostring = tostring; +local print = print; + +local hosts = hosts; + local log = require "util.logger".init("sessionmanager"); module "sessionmanager" @@ -12,9 +16,42 @@ function new_session(conn) return session; end +function destroy_session(session) +end + function send_to_session(session, data) - log("debug", "Sending...", tostring(data)); + log("debug", "Sending: %s", tostring(data)); session.conn.write(tostring(data)); end +function make_authenticated(session, username) + session.username = username; + session.resource = resource; + if session.type == "c2s_unauthed" then + session.type = "c2s"; + end +end + +function bind_resource(session, resource) + if not session.username then return false, "auth"; end + if session.resource then return false, "constraint"; end -- We don't support binding multiple resources + resource = resource or math.random(100000, 99999999); -- FIXME: Clearly we have issues :) + --FIXME: Randomly-generated resources must be unique per-user, and never conflict with existing + + if not hosts[session.host].sessions[session.username] then + hosts[session.host].sessions[session.username] = { sessions = {} }; + else + if hosts[session.host].sessions[session.username].sessions[resource] then + -- Resource conflict + return false, "conflict"; + end + end + + session.resource = resource; + session.full_jid = session.username .. '@' .. session.host .. '/' .. resource; + hosts[session.host].sessions[session.username].sessions[resource] = session; + + return true; +end + return _M; \ No newline at end of file diff --git a/core/usermanager.lua b/core/usermanager.lua index c98a1918..a67ad368 100644 --- a/core/usermanager.lua +++ b/core/usermanager.lua @@ -9,3 +9,5 @@ function validate_credentials(host, username, password) if password == credentials.password then return true; end return false; end + +return _M; \ No newline at end of file diff --git a/core/xmlhandlers.lua b/core/xmlhandlers.lua index 96e3f3ac..b6050c5a 100644 --- a/core/xmlhandlers.lua +++ b/core/xmlhandlers.lua @@ -27,6 +27,7 @@ function init_xmlhandlers(session) local stanza function xml_handlers:StartElement(name, attr) + log("info", "xmlhandlers", "Start element: " .. name); if stanza and #chardata > 0 then -- We have some character data in the buffer stanza:text(t_concat(chardata)); @@ -41,21 +42,28 @@ function init_xmlhandlers(session) session.streamid = m_random(1000000, 99999999); print(session, session.host, "Client opened stream"); send(""); - send(format("", session.streamid, session.host)); - --send(""); - --send("PLAIN"); + send(format("", session.streamid, session.host)); + send(""); + if not session.username then + send(""); + send("PLAIN"); + send(""); + else + send(""); + end --send [[ ]] - --send(""); + send(""); log("info", "core", "Stream opened successfully"); session.notopen = nil; return; end error("Client failed to open stream successfully"); end - if name ~= "iq" and name ~= "presence" and name ~= "message" then + if curr_ns == "jabber:client" and name ~= "iq" and name ~= "presence" and name ~= "message" then error("Client sent invalid top-level stanza"); end - stanza = st.stanza(name, { to = attr.to, type = attr.type, id = attr.id, xmlns = curr_ns }); + attr.xmlns = curr_ns; + stanza = st.stanza(name, attr); --{ to = attr.to, type = attr.type, id = attr.id, xmlns = curr_ns }); curr_tag = stanza; else attr.xmlns = curr_ns; -- cgit v1.2.3