local backend_mechanism = {};
-- register a new SASL mechanims
-local function registerMechanism(name, backends, f)
+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.");
-- create a new SASL object which can be used to authenticate clients
function new(realm, profile)
- local sasl_i = {profile = profile};
- sasl_i.realm = realm;
- return setmetatable(sasl_i, method);
+ local mechanisms = profile.mechanisms;
+ if not mechanisms then
+ mechanisms = {};
+ for backend, f in pairs(profile) do
+ if backend_mechanism[backend] then
+ for _, mechanism in ipairs(backend_mechanism[backend]) do
+ mechanisms[mechanism] = true;
+ end
+ end
+ end
+ profile.mechanisms = mechanisms;
+ end
+ return setmetatable({ profile = profile, realm = realm, mechs = mechanisms }, method);
end
-- get a fresh clone with the same realm and profile
-- get a list of possible SASL mechanims to use
function method:mechanisms()
- local mechanisms = self.mechs;
- if not mechanisms then
- mechanisms = {}
- for backend, f in pairs(self.profile) do
- if backend_mechanism[backend] then
- for _, mechanism in ipairs(backend_mechanism[backend]) do
- mechanisms[mechanism] = true;
- end
- end
- end
- self.mechs = mechanisms;
- end
- return mechanisms;
+ return self.mechs;
end
-- select a mechanism to use
function method:select(mechanism)
- if self.mech_i then
- return false;
+ if not self.selected and self.mechs[mechanism] then
+ self.selected = mechanism;
+ return true;
end
-
- self.mech_i = mechanisms[self:mechanisms()[mechanism] and mechanism];
- return (self.mech_i ~= nil);
end
-- feed new messages to process into the library
function method:process(message)
--if message == "" or message == nil then return "failure", "malformed-request" end
- return self.mech_i(self, message);
+ return mechanisms[self.selected](self, message);
end
-- load the mechanisms
-local load_mechs = {"plain", "digest-md5", "anonymous", "scram"}
-for _, mech in ipairs(load_mechs) do
- local name = "util.sasl."..mech;
- local m = require(name);
- m.init(registerMechanism)
-end
+require "util.sasl.plain" .init(registerMechanism);
+require "util.sasl.digest-md5".init(registerMechanism);
+require "util.sasl.anonymous" .init(registerMechanism);
+require "util.sasl.scram" .init(registerMechanism);
return _M;