Uncertain merge with 0.5's SASL
authorMatthew Wild <mwild1@gmail.com>
Thu, 20 Aug 2009 12:57:50 +0000 (13:57 +0100)
committerMatthew Wild <mwild1@gmail.com>
Thu, 20 Aug 2009 12:57:50 +0000 (13:57 +0100)
1  2 
plugins/mod_saslauth.lua
util/sasl.lua

index 8d3b4ae40133be814cc6dbb7b2d408df7f161d46,322692210116b5c9ef22038e1ea9147cd8f0de62..da66717cf2e48a0e744709f4c60acfe749fe1d1a
@@@ -12,12 -12,9 +12,13 @@@ local st = require "util.stanza"
  local sm_bind_resource = require "core.sessionmanager".bind_resource;
  local sm_make_authenticated = require "core.sessionmanager".make_authenticated;
  local base64 = require "util.encodings".base64;
 +
+ local nodeprep = require "util.encodings".stringprep.nodeprep;
  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
@@@ -67,28 -64,22 +68,32 @@@ local function handle_status(session, s
        end
  end
  
 -local function password_callback(node, hostname, realm, mechanism, decoder)
 -      local func = function(x) return x; end;
 -      local node = nodeprep(node);
 -      if not node then
 -              return func, nil;
 -      end
 -      local password = (datamanager_load(node, hostname, "accounts") or {}).password; -- FIXME handle hashed passwords
 -      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 = ...;
++              username = nodeprep(username);
++              if not username then
++                      return false;
++              end
 +              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)
diff --cc util/sasl.lua
index 444d4cf4ea432d877ab01f5a52688aa59c891e8d,295f568445fc1adc39d52b41086ddcc625f468f1..d176fd8530e6cf5c79325236c5ba06253aa91ced
@@@ -30,38 -31,42 +30,38 @@@ local print = prin
  
  module "sasl"
  
 -local function new_plain(realm, password_handler)
 -      local object = { mechanism = "PLAIN", realm = realm, password_handler = password_handler}
 +-- Credentials handler:
 +--   Arguments: ("PLAIN", user, host, password)
 +--   Returns: true (success) | false (fail) | nil (user unknown)
 +local function new_plain(realm, credentials_handler)
 +      local object = { mechanism = "PLAIN", realm = realm, credentials_handler = credentials_handler}
        function object.feed(self, message)
 -      
                if message == "" or message == nil then return "failure", "malformed-request" end
                local response = message
-               local authorization = s_match(response, "([^&%z]+)")
-               local authentication = s_match(response, "%z([^&%z]+)%z")
-               local password = s_match(response, "%z[^&%z]+%z([^&%z]+)")
+               local authorization = s_match(response, "([^%z]+)")
+               local authentication = s_match(response, "%z([^%z]+)%z")
+               local password = s_match(response, "%z[^%z]+%z([^%z]+)")
 -              authorization, authentication, password = saslprep(authorization), saslprep(authentication), saslprep(password);
 -              
 -              if authentication == nil or password == nil then return "failure", "malformed-request" end
 -              
 -              local password_encoding, correct_password = self.password_handler(authentication, self.realm, self.realm, "PLAIN")
 -              
 -              if correct_password == nil then return "failure", "not-authorized"
 -              elseif correct_password == false then return "failure", "account-disabled" end
 -              
 -              local claimed_password = ""
 -              if password_encoding == nil then claimed_password = password
 -              else claimed_password = password_encoding(password) end
 -              claimed_password = saslprep(claimed_password);
 -              
 -              self.username = authentication
 -              if claimed_password == correct_password then
 -                      return "success"
 -              else
 -                      return "failure", "not-authorized"
 -              end
 -      end
 -      return object
 -end
  
 +    if authentication == nil or password == nil then return "failure", "malformed-request" end
 +    self.username = authentication
 +    local auth_success = self.credentials_handler("PLAIN", self.username, self.realm, password)
 +
 +    if auth_success then
 +      return "success"
 +    elseif auth_success == nil then
 +      return "failure", "account-disabled"
 +    else
 +      return "failure", "not-authorized"
 +    end
 +  end
 +  return object
 +end
  
 +-- credentials_handler:
 +--   Arguments: (mechanism, node, domain, realm, decoder)
 +--   Returns: Password encoding, (plaintext) password
  -- implementing RFC 2831
 -local function new_digest_md5(realm, password_handler)
 +local function new_digest_md5(realm, credentials_handler)
        --TODO complete support for authzid
  
        local function serialize(message)