5 -- |
5 -- |
6 -- This project is MIT/X11 licensed. Please see the |
6 -- This project is MIT/X11 licensed. Please see the |
7 -- COPYING file in the source package for more information. |
7 -- COPYING file in the source package for more information. |
8 -- |
8 -- |
9 |
9 |
10 local datamanager = require "util.datamanager"; |
|
11 local log = require "util.logger".init("auth_internal_hashed"); |
10 local log = require "util.logger".init("auth_internal_hashed"); |
12 local getAuthenticationDatabaseSHA1 = require "util.sasl.scram".getAuthenticationDatabaseSHA1; |
11 local getAuthenticationDatabaseSHA1 = require "util.sasl.scram".getAuthenticationDatabaseSHA1; |
13 local usermanager = require "core.usermanager"; |
12 local usermanager = require "core.usermanager"; |
14 local generate_uuid = require "util.uuid".generate; |
13 local generate_uuid = require "util.uuid".generate; |
15 local new_sasl = require "util.sasl".new; |
14 local new_sasl = require "util.sasl".new; |
|
15 |
|
16 local accounts = module:open_store("accounts"); |
16 |
17 |
17 local to_hex; |
18 local to_hex; |
18 do |
19 do |
19 local function replace_byte_with_hex(byte) |
20 local function replace_byte_with_hex(byte) |
20 return ("%02x"):format(byte:byte()); |
21 return ("%02x"):format(byte:byte()); |
73 return nil, "Auth failed. Invalid username, password, or password hash information."; |
74 return nil, "Auth failed. Invalid username, password, or password hash information."; |
74 end |
75 end |
75 end |
76 end |
76 |
77 |
77 function provider.set_password(username, password) |
78 function provider.set_password(username, password) |
78 local account = datamanager.load(username, host, "accounts"); |
79 local account = accounts:get(username); |
79 if account then |
80 if account then |
80 account.salt = account.salt or generate_uuid(); |
81 account.salt = account.salt or generate_uuid(); |
81 account.iteration_count = account.iteration_count or iteration_count; |
82 account.iteration_count = account.iteration_count or iteration_count; |
82 local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, account.salt, account.iteration_count); |
83 local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, account.salt, account.iteration_count); |
83 local stored_key_hex = to_hex(stored_key); |
84 local stored_key_hex = to_hex(stored_key); |
85 |
86 |
86 account.stored_key = stored_key_hex |
87 account.stored_key = stored_key_hex |
87 account.server_key = server_key_hex |
88 account.server_key = server_key_hex |
88 |
89 |
89 account.password = nil; |
90 account.password = nil; |
90 return datamanager.store(username, host, "accounts", account); |
91 return accounts:set(username, account); |
91 end |
92 end |
92 return nil, "Account not available."; |
93 return nil, "Account not available."; |
93 end |
94 end |
94 |
95 |
95 function provider.user_exists(username) |
96 function provider.user_exists(username) |
96 local account = datamanager.load(username, host, "accounts"); |
97 local account = accounts:get(username); |
97 if not account then |
98 if not account then |
98 log("debug", "account not found for username '%s' at host '%s'", username, host); |
99 log("debug", "account not found for username '%s' at host '%s'", username, host); |
99 return nil, "Auth failed. Invalid username"; |
100 return nil, "Auth failed. Invalid username"; |
100 end |
101 end |
101 return true; |
102 return true; |
102 end |
103 end |
103 |
104 |
104 function provider.users() |
105 function provider.users() |
105 return datamanager.users(host, "accounts"); |
106 return accounts:users(); |
106 end |
107 end |
107 |
108 |
108 function provider.create_user(username, password) |
109 function provider.create_user(username, password) |
109 if password == nil then |
110 if password == nil then |
110 return datamanager.store(username, host, "accounts", {}); |
111 return accounts:set(username, {}); |
111 end |
112 end |
112 local salt = generate_uuid(); |
113 local salt = generate_uuid(); |
113 local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, salt, iteration_count); |
114 local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, salt, iteration_count); |
114 local stored_key_hex = to_hex(stored_key); |
115 local stored_key_hex = to_hex(stored_key); |
115 local server_key_hex = to_hex(server_key); |
116 local server_key_hex = to_hex(server_key); |
116 return datamanager.store(username, host, "accounts", {stored_key = stored_key_hex, server_key = server_key_hex, salt = salt, iteration_count = iteration_count}); |
117 return accounts:set(username, {stored_key = stored_key_hex, server_key = server_key_hex, salt = salt, iteration_count = iteration_count}); |
117 end |
118 end |
118 |
119 |
119 function provider.delete_user(username) |
120 function provider.delete_user(username) |
120 return datamanager.store(username, host, "accounts", nil); |
121 return accounts:set(username, nil); |
121 end |
122 end |
122 |
123 |
123 function provider.get_sasl_handler() |
124 function provider.get_sasl_handler() |
124 local testpass_authentication_profile = { |
125 local testpass_authentication_profile = { |
125 plain_test = function(sasl, username, password, realm) |
126 plain_test = function(sasl, username, password, realm) |
126 return usermanager.test_password(username, realm, password), true; |
127 return usermanager.test_password(username, realm, password), true; |
127 end, |
128 end, |
128 scram_sha_1 = function(sasl, username, realm) |
129 scram_sha_1 = function(sasl, username, realm) |
129 local credentials = datamanager.load(username, host, "accounts"); |
130 local credentials = accounts:get(username); |
130 if not credentials then return; end |
131 if not credentials then return; end |
131 if credentials.password then |
132 if credentials.password then |
132 usermanager.set_password(username, credentials.password, host); |
133 usermanager.set_password(username, credentials.password, host); |
133 credentials = datamanager.load(username, host, "accounts"); |
134 credentials = accounts:get(username); |
134 if not credentials then return; end |
135 if not credentials then return; end |
135 end |
136 end |
136 |
137 |
137 local stored_key, server_key, iteration_count, salt = credentials.stored_key, credentials.server_key, credentials.iteration_count, credentials.salt; |
138 local stored_key, server_key, iteration_count, salt = credentials.stored_key, credentials.server_key, credentials.iteration_count, credentials.salt; |
138 stored_key = stored_key and from_hex(stored_key); |
139 stored_key = stored_key and from_hex(stored_key); |