90 -- apply SASLprep |
90 -- apply SASLprep |
91 username = saslprep(username); |
91 username = saslprep(username); |
92 return username; |
92 return username; |
93 end |
93 end |
94 |
94 |
|
95 function saltedPasswordSHA1(password, salt, iteration_count) |
|
96 local salted_password |
|
97 if type(password) ~= "string" and type(salt) ~= "string" and type(iteration_count) ~= "number" then |
|
98 return false, "inappropriate argument types" |
|
99 end |
|
100 if iteration_count < 4096 then |
|
101 log("warning", "Iteration count < 4096 which is the suggested minimum according to RFC 5802.") |
|
102 end |
|
103 |
|
104 return true, Hi(hmac_sha1, password, salt, iteration_count); |
|
105 end |
|
106 |
95 local function scram_gen(hash_name, H_f, HMAC_f) |
107 local function scram_gen(hash_name, H_f, HMAC_f) |
96 local function scram_hash(self, message) |
108 local function scram_hash(self, message) |
97 if not self.state then self["state"] = {} end |
109 if not self.state then self["state"] = {} end |
98 |
110 |
99 if not self.state.name then |
111 if not self.state.name then |
131 password = saslprep(password); |
143 password = saslprep(password); |
132 if not password then |
144 if not password then |
133 log("debug", "Password violates SASLprep."); |
145 log("debug", "Password violates SASLprep."); |
134 return "failure", "not-authorized", "Invalid password." |
146 return "failure", "not-authorized", "Invalid password." |
135 end |
147 end |
|
148 |
136 self.state.salt = generate_uuid(); |
149 self.state.salt = generate_uuid(); |
137 self.state.iteration_count = default_i; |
150 self.state.iteration_count = default_i; |
138 self.state.salted_password = Hi(HMAC_f, password, self.state.salt, default_i); |
151 |
|
152 local succ = false; |
|
153 succ, self.state.salted_password = saltedPasswordSHA1(password, self.state.salt, default_i, self.state.iteration_count); |
|
154 if not succ then |
|
155 log("error", "Generating salted password failed. Reason: %s", self.state.salted_password); |
|
156 return "failure", "temporary-auth-failure"; |
|
157 end |
139 elseif self.profile["scram_"..hash_name] then |
158 elseif self.profile["scram_"..hash_name] then |
140 local salted_password, iteration_count, salt, state = self.profile["scram-"..hash_name](self.state.name, self.realm); |
159 local salted_password, iteration_count, salt, state = self.profile["scram-"..hash_name](self.state.name, self.realm); |
141 if state == nil then return "failure", "not-authorized" |
160 if state == nil then return "failure", "not-authorized" |
142 elseif state == false then return "failure", "account-disabled" end |
161 elseif state == false then return "failure", "account-disabled" end |
143 |
162 |