Software /
code /
prosody
Comparison
plugins/mod_auth_internal_hashed.lua @ 3214:a69d8021b1db
Merge with Tobias.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Wed, 09 Jun 2010 21:34:32 +0500 |
parent | 3204:7a15cbf23c5b |
parent | 3213:c85bba8bd41a |
child | 3216:d4d0519cd0c1 |
comparison
equal
deleted
inserted
replaced
3204:7a15cbf23c5b | 3214:a69d8021b1db |
---|---|
12 local type = type; | 12 local type = type; |
13 local error = error; | 13 local error = error; |
14 local ipairs = ipairs; | 14 local ipairs = ipairs; |
15 local hashes = require "util.hashes"; | 15 local hashes = require "util.hashes"; |
16 local jid_bare = require "util.jid".bare; | 16 local jid_bare = require "util.jid".bare; |
17 local saltedPasswordSHA1 = require "util.sasl.scram".saltedPasswordSHA1; | 17 local getAuthenticationDatabaseSHA1 = require "util.sasl.scram".getAuthenticationDatabaseSHA1; |
18 local config = require "core.configmanager"; | 18 local config = require "core.configmanager"; |
19 local usermanager = require "core.usermanager"; | 19 local usermanager = require "core.usermanager"; |
20 local generate_uuid = require "util.uuid".generate; | 20 local generate_uuid = require "util.uuid".generate; |
21 local new_sasl = require "util.sasl".new; | 21 local new_sasl = require "util.sasl".new; |
22 local nodeprep = require "util.encodings".stringprep.nodeprep; | 22 local nodeprep = require "util.encodings".stringprep.nodeprep; |
23 local hosts = hosts; | 23 local hosts = hosts; |
24 | |
25 -- TODO: remove these two lines in near future | |
26 local hmac_sha1 = require "util.hmac".sha1; | |
27 local sha1 = require "util.hashes".sha1; | |
24 | 28 |
25 local prosody = _G.prosody; | 29 local prosody = _G.prosody; |
26 | 30 |
27 local is_cyrus = usermanager.is_cyrus; | 31 local is_cyrus = usermanager.is_cyrus; |
28 | 32 |
50 end | 54 end |
51 | 55 |
52 if credentials.iteration_count == nil or credentials.salt == nil or string.len(credentials.salt) == 0 then | 56 if credentials.iteration_count == nil or credentials.salt == nil or string.len(credentials.salt) == 0 then |
53 return nil, "Auth failed. Stored salt and iteration count information is not complete."; | 57 return nil, "Auth failed. Stored salt and iteration count information is not complete."; |
54 end | 58 end |
55 | 59 |
56 local valid, binpass = saltedPasswordSHA1(password, credentials.salt, credentials.iteration_count); | 60 local valid, stored_key, server_key |
57 local hexpass = binpass:gsub(".", function (c) return ("%02x"):format(c:byte()); end); | 61 |
58 | 62 -- convert hexpass to stored_key and server_key |
59 if valid and hexpass == credentials.hashpass then | 63 -- TODO: remove this in near future |
64 if credentials.hashpass then | |
65 valid = true; | |
66 local salted_password = credentials.hashpass:gsub("..", function(x) return string.char(tonumber(x, 16)); end); | |
67 credentials.stored_key = sha1(hmac_sha1(salted_password, "Client Key")):gsub(".", function (c) return ("%02x"):format(c:byte()); end); | |
68 credentials.server_key = hmac_sha1(salted_password, "Server Key"):gsub(".", function (c) return ("%02x"):format(c:byte()); end); | |
69 credentials.hashpass = nil | |
70 datamanager.store(username, host, "accounts", credentials); | |
71 end | |
72 | |
73 local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, credentials.salt, credentials.iteration_count); | |
74 | |
75 local stored_key_hex = stored_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end); | |
76 local server_key_hex = server_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end); | |
77 | |
78 if valid and stored_key_hex == credentials.stored_key and server_key_hex == credentials.server_key then | |
60 return true; | 79 return true; |
61 else | 80 else |
62 return nil, "Auth failed. Invalid username, password, or password hash information."; | 81 return nil, "Auth failed. Invalid username, password, or password hash information."; |
63 end | 82 end |
64 end | 83 end |
65 | 84 |
66 function provider.set_password(username, password) | 85 function provider.set_password(username, password) |
67 if is_cyrus(host) then return nil, "Passwords unavailable for Cyrus SASL."; end | 86 if is_cyrus(host) then return nil, "Passwords unavailable for Cyrus SASL."; end |
68 local account = datamanager.load(username, host, "accounts"); | 87 local account = datamanager.load(username, host, "accounts"); |
69 if account then | 88 if account then |
70 if account.iteration_count == nil then | 89 account.salt = account.salt or generate_uuid(); |
71 account.iteration_count = iteration_count; | 90 account.iteration_count = account.iteration_count or iteration_count; |
72 end | 91 local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, account.salt, account.iteration_count); |
73 | 92 local stored_key_hex = stored_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end); |
74 if account.salt == nil then | 93 local server_key_hex = server_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end); |
75 account.salt = generate_uuid(); | 94 |
76 end | 95 account.stored_key = stored_key_hex |
77 | 96 account.server_key = server_key_hex |
78 local valid, binpass = saltedPasswordSHA1(password, account.salt, account.iteration_count); | |
79 local hexpass = binpass:gsub(".", function (c) return ("%02x"):format(c:byte()); end); | |
80 account.hashpass = hexpass; | |
81 | 97 |
82 account.password = nil; | 98 account.password = nil; |
83 return datamanager.store(username, host, "accounts", account); | 99 return datamanager.store(username, host, "accounts", account); |
84 end | 100 end |
85 return nil, "Account not available."; | 101 return nil, "Account not available."; |
100 end | 116 end |
101 | 117 |
102 function provider.create_user(username, password) | 118 function provider.create_user(username, password) |
103 if is_cyrus(host) then return nil, "Account creation/modification not available with Cyrus SASL."; end | 119 if is_cyrus(host) then return nil, "Account creation/modification not available with Cyrus SASL."; end |
104 local salt = generate_uuid(); | 120 local salt = generate_uuid(); |
105 local valid, binpass = saltedPasswordSHA1(password, salt, iteration_count); | 121 local valid, stored_key, server_key = saltedPasswordSHA1(password, salt, iteration_count); |
106 local hexpass = binpass:gsub(".", function (c) return ("%02x"):format(c:byte()); end); | 122 local stored_key_hex = stored_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end); |
107 return datamanager.store(username, host, "accounts", {hashpass = hexpass, salt = salt, iteration_count = iteration_count}); | 123 local server_key_hex = server_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end); |
124 return datamanager.store(username, host, "accounts", {stored_key = stored_key_hex, server_key = server_key_hex, salt = salt, iteration_count = iteration_count}); | |
108 end | 125 end |
109 | 126 |
110 function provider.get_sasl_handler() | 127 function provider.get_sasl_handler() |
111 local realm = module:get_option("sasl_realm") or module.host; | 128 local realm = module:get_option("sasl_realm") or module.host; |
112 local testpass_authentication_profile = { | 129 local testpass_authentication_profile = { |
122 local credentials = datamanager.load(username, host, "accounts") or {}; | 139 local credentials = datamanager.load(username, host, "accounts") or {}; |
123 if credentials.password then | 140 if credentials.password then |
124 usermanager.set_password(username, credentials.password, host); | 141 usermanager.set_password(username, credentials.password, host); |
125 credentials = datamanager.load(username, host, "accounts") or {}; | 142 credentials = datamanager.load(username, host, "accounts") or {}; |
126 end | 143 end |
127 local salted_password, iteration_count, salt = credentials.hashpass, credentials.iteration_count, credentials.salt; | 144 |
128 salted_password = salted_password and salted_password:gsub("..", function(x) return string.char(tonumber(x, 16)); end); | 145 -- convert hexpass to stored_key and server_key |
129 return salted_password, iteration_count, salt, true; | 146 -- TODO: remove this in near future |
147 if credentials.hashpass then | |
148 local salted_password = credentials.hashpass:gsub("..", function(x) return string.char(tonumber(x, 16)); end); | |
149 credentials.stored_key = sha1(hmac_sha1(salted_password, "Client Key")):gsub(".", function (c) return ("%02x"):format(c:byte()); end); | |
150 credentials.server_key = hmac_sha1(salted_password, "Server Key"):gsub(".", function (c) return ("%02x"):format(c:byte()); end); | |
151 credentials.hashpass = nil | |
152 datamanager.store(username, host, "accounts", credentials); | |
153 end | |
154 | |
155 local stored_key, server_key, iteration_count, salt = credentials.stored_key, credentials.server_key, credentials.iteration_count, credentials.salt; | |
156 stored_key = stored_key and stored_key:gsub("..", function(x) return string.char(tonumber(x, 16)); end); | |
157 server_key = server_key and server_key:gsub("..", function(x) return string.char(tonumber(x, 16)); end); | |
158 return stored_key, server_key, iteration_count, salt, true; | |
130 end | 159 end |
131 }; | 160 }; |
132 return new_sasl(realm, testpass_authentication_profile); | 161 return new_sasl(realm, testpass_authentication_profile); |
133 end | 162 end |
134 | 163 |