X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=plugins%2Fmod_saslauth.lua;h=52ef68c7eb26f95620e83e3d39b847bcc8dde5ec;hb=9ded002d6d01fa5df9a171c5618071ecde34d0f1;hp=35585f0bb5b455b80193ce22aca20d8e9ec59993;hpb=e15af5482fdd91b7458ad2458ee7fff93e0b607c;p=prosody.git diff --git a/plugins/mod_saslauth.lua b/plugins/mod_saslauth.lua index 35585f0b..52ef68c7 100644 --- a/plugins/mod_saslauth.lua +++ b/plugins/mod_saslauth.lua @@ -1,13 +1,34 @@ +-- Prosody IM v0.1 +-- Copyright (C) 2008 Matthew Wild +-- Copyright (C) 2008 Waqas Hussain +-- +-- This program is free software; you can redistribute it and/or +-- modify it under the terms of the GNU General Public License +-- as published by the Free Software Foundation; either version 2 +-- of the License, or (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +-- + + local st = require "util.stanza"; -local send = require "core.sessionmanager".send_to_session; local sm_bind_resource = require "core.sessionmanager".bind_resource; local jid +local base64 = require "util.encodings".base64; local usermanager_validate_credentials = require "core.usermanager".validate_credentials; local t_concat, t_insert = table.concat, table.insert; local tostring = tostring; local jid_split = require "util.jid".split +local md5 = require "util.hashes".md5; local log = require "util.logger".init("mod_saslauth"); @@ -43,14 +64,14 @@ local function handle_status(session, status) end end -local function password_callback(node, host, mechanism) +local function password_callback(node, host, mechanism, raw_host) local password = (datamanager.load(node, host, "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 - return func, require "hashes".md5(node..":"..host..":"..password); + return func, md5(node..":"..raw_host..":"..password); end end return func, nil; @@ -79,32 +100,33 @@ function sasl_handler(session, stanza) session.send(s); end -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); +module:add_handler("c2s_unauthed", "auth", xmlns_sasl, sasl_handler); +module:add_handler("c2s_unauthed", "abort", xmlns_sasl, sasl_handler); +module:add_handler("c2s_unauthed", "response", xmlns_sasl, sasl_handler); -add_event_hook("stream-features", +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) 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", +module:add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-bind", function (session, stanza) log("debug", "Client tried to bind to a resource"); local resource; if stanza.attr.type == "set" then local bind = stanza.tags[1]; - if bind and bind.attr.xmlns == xmlns_bind then resource = bind:child_with_name("resource"); if resource then @@ -112,31 +134,18 @@ add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-bind", end end end - local success, err = sm_bind_resource(session, resource); + local success, err_type, err, err_msg = sm_bind_resource(session, resource); if not success then - local reply = st.reply(stanza); - reply.attr.type = "error"; - if err == "conflict" then - reply:tag("error", { type = "modify" }) - :tag("conflict", { xmlns = xmlns_stanzas }); - elseif err == "constraint" then - reply:tag("error", { type = "cancel" }) - :tag("resource-constraint", { xmlns = xmlns_stanzas }); - elseif err == "auth" then - reply:tag("error", { type = "cancel" }) - :tag("not-allowed", { xmlns = xmlns_stanzas }); - end - send(session, reply); + session.send(st.error_reply(stanza, err_type, err, err_msg)); else - local reply = st.reply(stanza); - reply:tag("bind", { xmlns = xmlns_bind}) - :tag("jid"):text(session.full_jid); - send(session, reply); + session.send(st.reply(stanza) + :tag("bind", { xmlns = xmlns_bind}) + :tag("jid"):text(session.full_jid)); end end); -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 tried to bind to a resource"); - send(session, st.reply(stanza)); + session.send(st.reply(stanza)); end);