comparison util/sasl.lua @ 5843:fb6573e191cf

Merge Tobias SCRAM-PLUS work
author Kim Alvefur <zash@zash.se>
date Sun, 22 Sep 2013 00:44:20 +0200
parents e879b53e9df8 1b0c7e7c6be8
children 7e83c8448cd6
comparison
equal deleted inserted replaced
5827:ae16bf17785d 5843:fb6573e191cf
16 local t_insert = table.insert; 16 local t_insert = table.insert;
17 local type = type 17 local type = type
18 local setmetatable = setmetatable; 18 local setmetatable = setmetatable;
19 local assert = assert; 19 local assert = assert;
20 local require = require; 20 local require = require;
21 local print = print
21 22
22 module "sasl" 23 module "sasl"
23 24
24 --[[ 25 --[[
25 Authentication Backend Prototypes: 26 Authentication Backend Prototypes:
26 27
27 state = false : disabled 28 state = false : disabled
28 state = true : enabled 29 state = true : enabled
29 state = nil : non-existant 30 state = nil : non-existant
31
32 Channel Binding:
33
34 To enable support of channel binding in some mechanisms you need to provide appropriate callbacks in a table
35 at profile.cb.
36
37 Example:
38 profile.cb["tls-unique"] = function(self)
39 return self.user
40 end
41
30 ]] 42 ]]
31 43
32 local method = {}; 44 local method = {};
33 method.__index = method; 45 method.__index = method;
34 local mechanisms = {}; 46 local mechanisms = {};
35 local backend_mechanism = {}; 47 local backend_mechanism = {};
48 local mechanism_channelbindings = {};
36 49
37 -- register a new SASL mechanims 50 -- register a new SASL mechanims
38 function registerMechanism(name, backends, f) 51 local function registerMechanism(name, backends, f, cb_backends)
39 assert(type(name) == "string", "Parameter name MUST be a string."); 52 assert(type(name) == "string", "Parameter name MUST be a string.");
40 assert(type(backends) == "string" or type(backends) == "table", "Parameter backends MUST be either a string or a table."); 53 assert(type(backends) == "string" or type(backends) == "table", "Parameter backends MUST be either a string or a table.");
41 assert(type(f) == "function", "Parameter f MUST be a function."); 54 assert(type(f) == "function", "Parameter f MUST be a function.");
55 if cb_backends then assert(type(cb_backends) == "table"); end
42 mechanisms[name] = f 56 mechanisms[name] = f
57 if cb_backends then
58 mechanism_channelbindings[name] = {};
59 for _, cb_name in ipairs(cb_backends) do
60 mechanism_channelbindings[name][cb_name] = true;
61 end
62 end
43 for _, backend_name in ipairs(backends) do 63 for _, backend_name in ipairs(backends) do
44 if backend_mechanism[backend_name] == nil then backend_mechanism[backend_name] = {}; end 64 if backend_mechanism[backend_name] == nil then backend_mechanism[backend_name] = {}; end
45 t_insert(backend_mechanism[backend_name], name); 65 t_insert(backend_mechanism[backend_name], name);
46 end 66 end
47 end 67 end
61 profile.mechanisms = mechanisms; 81 profile.mechanisms = mechanisms;
62 end 82 end
63 return setmetatable({ profile = profile, realm = realm, mechs = mechanisms }, method); 83 return setmetatable({ profile = profile, realm = realm, mechs = mechanisms }, method);
64 end 84 end
65 85
86 -- add a channel binding handler
87 function method:add_cb_handler(name, f)
88 if type(self.profile.cb) ~= "table" then
89 self.profile.cb = {};
90 end
91 self.profile.cb[name] = f;
92 return self;
93 end
94
66 -- get a fresh clone with the same realm and profile 95 -- get a fresh clone with the same realm and profile
67 function method:clean_clone() 96 function method:clean_clone()
68 return new(self.realm, self.profile) 97 return new(self.realm, self.profile)
69 end 98 end
70 99
71 -- get a list of possible SASL mechanims to use 100 -- get a list of possible SASL mechanims to use
72 function method:mechanisms() 101 function method:mechanisms()
73 return self.mechs; 102 local current_mechs = {};
103 for mech, _ in pairs(self.mechs) do
104 if mechanism_channelbindings[mech] and self.profile.cb then
105 local ok = false;
106 for cb_name, _ in pairs(self.profile.cb) do
107 if mechanism_channelbindings[mech][cb_name] then
108 ok = true;
109 end
110 end
111 if ok == true then current_mechs[mech] = true; end
112 else
113 current_mechs[mech] = true;
114 end
115 end
116 return current_mechs;
74 end 117 end
75 118
76 -- select a mechanism to use 119 -- select a mechanism to use
77 function method:select(mechanism) 120 function method:select(mechanism)
78 if not self.selected and self.mechs[mechanism] then 121 if not self.selected and self.mechs[mechanism] then