aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--util/sasl.lua63
1 files changed, 56 insertions, 7 deletions
diff --git a/util/sasl.lua b/util/sasl.lua
index b2dd4034..d6ac5c1e 100644
--- a/util/sasl.lua
+++ b/util/sasl.lua
@@ -17,6 +17,7 @@ local log = require "util.logger".init("sasl");
local tostring = tostring;
local st = require "util.stanza";
local generate_uuid = require "util.uuid".generate;
+local pairs, ipairs = pairs, ipairs;
local t_insert, t_concat = table.insert, table.concat;
local to_byte, to_char = string.byte, string.char;
local to_unicode = require "util.encodings".idna.to_unicode;
@@ -30,9 +31,14 @@ local print = print
local setmetatable = setmetatable;
local assert = assert;
+require "util.iterators"
+local keys = keys
+
+local array = require "util.array"
module "sasl"
-local method = {}
+local method = {};
+method.__index = method;
local mechanisms = {};
local backend_mechanism = {};
@@ -41,25 +47,68 @@ local function registerMechanism(name, backends, f)
assert(type(name) == "string", "Parameter name MUST be a string.");
assert(type(backends) == "string" or type(backends) == "table", "Parameter backends MUST be either a string or a table.");
assert(type(f) == "function", "Parameter f MUST be a function.");
- mechanism[name] = f
- for _, backend_name in ipairs(backend)
+ mechanisms[name] = f
+ for _, backend_name in ipairs(backends) do
+ if backend_mechanism[backend_name] == nil then backend_mechanism[backend_name] = {}; end
+ t_insert(backend_mechanism[backend_name], name);
+ end
end
-- create a new SASL object which can be used to authenticate clients
function new(realm, profile)
- sasl_i = {};
-
+ sasl_i = {profile = profile};
return setmetatable(sasl_i, method);
end
-- get a list of possible SASL mechanims to use
function method:mechanisms()
-
+ local mechanisms = {}
+ for backend, f in pairs(self.profile) do
+ print(backend)
+ if backend_mechanism[backend] then
+ for _, mechanism in ipairs(backend_mechanism[backend]) do
+ mechanisms[mechanism] = true;
+ end
+ end
+ end
+ return array.collect(keys(mechanisms));
end
-- select a mechanism to use
-function method.select( mechanism )
+function method:select(mechanism)
+
+end
+
+-- feed new messages to process into the library
+function method:process(message)
+
+end
+
+--=========================
+--SASL PLAIN
+local function sasl_mechanism_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]+)")
+
+ 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
+registerMechanism("PLAIN", {"plain", "plain_test"}, sasl_mechanism_plain);
return _M;