Mercurial > prosody-hg
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 |
