Diff

util/sasl.lua @ 2176:aaf2b2df61f7 sasl

Mostly making the code run; includes fixing typos and so on.
author Tobias Markmann <tm@ayena.de>
date Mon, 10 Aug 2009 23:04:19 +0200
parent 2175:3ca8755581a1
child 2177:8505e1da5408
line wrap: on
line diff
--- a/util/sasl.lua	Mon Aug 10 12:14:40 2009 +0200
+++ b/util/sasl.lua	Mon Aug 10 23:04:19 2009 +0200
@@ -17,6 +17,7 @@
 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 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 @@
 	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;