util/sasl/scram.lua

changeset 3120
6f1b7260925c
parent 3117
f4e7ca2aa2f7
child 3121
27f895bac9c0
equal deleted inserted replaced
3117:f4e7ca2aa2f7 3120:6f1b7260925c
30 --SASL SCRAM-SHA-1 according to draft-ietf-sasl-scram-10 30 --SASL SCRAM-SHA-1 according to draft-ietf-sasl-scram-10
31 31
32 --[[ 32 --[[
33 Supported Authentication Backends 33 Supported Authentication Backends
34 34
35 scram-{MECH}: 35 scram_{MECH}:
36 -- MECH being a standard hash name (like those at IANA's hash registry) with '-' replaced with '_'
36 function(username, realm) 37 function(username, realm)
37 return salted_password, iteration_count, salt, state; 38 return salted_password, iteration_count, salt, state;
38 end 39 end
39 ]] 40 ]]
40 41
88 username = username:gsub("=3D", "="); 89 username = username:gsub("=3D", "=");
89 90
90 -- apply SASLprep 91 -- apply SASLprep
91 username = saslprep(username); 92 username = saslprep(username);
92 return username; 93 return username;
94 end
95
96 local function hashprep( hashname )
97 local hash = hashname:lower()
98 hash = hash:gsub("-", "_")
99 return hash
93 end 100 end
94 101
95 function saltedPasswordSHA1(password, salt, iteration_count) 102 function saltedPasswordSHA1(password, salt, iteration_count)
96 local salted_password 103 local salted_password
97 if type(password) ~= "string" or type(salt) ~= "string" or type(iteration_count) ~= "number" then 104 if type(password) ~= "string" or type(salt) ~= "string" or type(iteration_count) ~= "number" then
154 succ, self.state.salted_password = saltedPasswordSHA1(password, self.state.salt, default_i, self.state.iteration_count); 161 succ, self.state.salted_password = saltedPasswordSHA1(password, self.state.salt, default_i, self.state.iteration_count);
155 if not succ then 162 if not succ then
156 log("error", "Generating salted password failed. Reason: %s", self.state.salted_password); 163 log("error", "Generating salted password failed. Reason: %s", self.state.salted_password);
157 return "failure", "temporary-auth-failure"; 164 return "failure", "temporary-auth-failure";
158 end 165 end
159 elseif self.profile["scram_"..hash_name] then 166 elseif self.profile["scram_"..hashprep(hash_name)] then
160 local salted_password, iteration_count, salt, state = self.profile["scram-"..hash_name](self.state.name, self.realm); 167 local salted_password, iteration_count, salt, state = self.profile["scram-"..hash_name](self.state.name, self.realm);
161 if state == nil then return "failure", "not-authorized" 168 if state == nil then return "failure", "not-authorized"
162 elseif state == false then return "failure", "account-disabled" end 169 elseif state == false then return "failure", "account-disabled" end
163 170
164 self.state.salted_password = salted_password; 171 self.state.salted_password = salted_password;
204 return scram_hash; 211 return scram_hash;
205 end 212 end
206 213
207 function init(registerMechanism) 214 function init(registerMechanism)
208 local function registerSCRAMMechanism(hash_name, hash, hmac_hash) 215 local function registerSCRAMMechanism(hash_name, hash, hmac_hash)
209 registerMechanism("SCRAM-"..hash_name, {"plain", "scram_"..(hash_name:lower())}, scram_gen(hash_name:lower(), hash, hmac_hash)); 216 registerMechanism("SCRAM-"..hash_name, {"plain", "scram_"..(hashprep(hash_name))}, scram_gen(hash_name:lower(), hash, hmac_hash));
210 end 217 end
211 218
212 registerSCRAMMechanism("SHA-1", sha1, hmac_sha1); 219 registerSCRAMMechanism("SHA-1", sha1, hmac_sha1);
213 end 220 end
214 221

mercurial