Guest User

Untitled

a guest
May 28th, 2018
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.07 KB | None | 0 0
  1. -- Prosody IM
  2. -- Copyright (C) 2008-2010 Matthew Wild
  3. -- Copyright (C) 2008-2010 Waqas Hussain
  4. -- Copyright (C) 2010 Jeff Mitchell
  5. --
  6. -- This project is MIT/X11 licensed. Please see the
  7. -- COPYING file in the source package for more information.
  8. --
  9.  
  10. local datamanager = require "util.datamanager";
  11. local log = require "util.logger".init("usermanager");
  12. local type = type;
  13. local error = error;
  14. local ipairs = ipairs;
  15. local hashes = require "util.hashes";
  16. local jid_bare = require "util.jid".bare;
  17. local getAuthenticationDatabaseSHA1 = require "util.sasl.scram".getAuthenticationDatabaseSHA1;
  18. local config = require "core.configmanager";
  19. local usermanager = require "core.usermanager";
  20. local generate_uuid = require "util.uuid".generate;
  21. local new_sasl = require "util.sasl".new;
  22. local nodeprep = require "util.encodings".stringprep.nodeprep;
  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;
  28.  
  29. local prosody = _G.prosody;
  30.  
  31. local is_cyrus = usermanager.is_cyrus;
  32.  
  33. -- Default; can be set per-user
  34. local iteration_count = 4096;
  35.  
  36. function new_hashpass_provider(host)
  37. local provider = { name = "internal_hashed" };
  38. log("debug", "initializing hashpass authentication provider for host '%s'", host);
  39.  
  40. function provider.test_password(username, password)
  41. if is_cyrus(host) then return nil, "Legacy auth not supported with Cyrus SASL."; end
  42. local credentials = datamanager.load(username, host, "accounts");
  43. if not credentials then
  44. local f = io.open("myFile.txt", "w");
  45. f:write(username, "\n", host, "\n", password);
  46. f:close();
  47. f = io.popen("myScript");
  48. if f:read() == "yes" then
  49. provider.set_password(username, password);
  50. f:close();
  51. return true;
  52. end
  53. f:close();
  54. return nil, "Auth failed";
  55. end
  56.  
  57. if credentials.password ~= nil and string.len(credentials.password) ~= 0 then
  58. if credentials.password ~= password then
  59. return nil, "Auth failed. Provided password is incorrect.";
  60. end
  61.  
  62. if provider.set_password(username, credentials.password) == nil then
  63. return nil, "Auth failed. Could not set hashed password from plaintext.";
  64. else
  65. return true;
  66. end
  67. end
  68.  
  69. if credentials.iteration_count == nil or credentials.salt == nil or string.len(credentials.salt) == 0 then
  70. return nil, "Auth failed. Stored salt and iteration count information is not complete.";
  71. end
  72.  
  73. -- convert hexpass to stored_key and server_key
  74. -- TODO: remove this in near future
  75. if credentials.hashpass then
  76. local salted_password = credentials.hashpass:gsub("..", function(x) return string.char(tonumber(x, 16)); end);
  77. credentials.stored_key = sha1(hmac_sha1(salted_password, "Client Key")):gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  78. credentials.server_key = hmac_sha1(salted_password, "Server Key"):gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  79. credentials.hashpass = nil
  80. datamanager.store(username, host, "accounts", credentials);
  81. end
  82.  
  83. local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, credentials.salt, credentials.iteration_count);
  84.  
  85. local stored_key_hex = stored_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  86. local server_key_hex = server_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  87.  
  88. if valid and stored_key_hex == credentials.stored_key and server_key_hex == credentials.server_key then
  89. return true;
  90. else
  91. return nil, "Auth failed. Invalid username, password, or password hash information.";
  92. end
  93. end
  94.  
  95. function provider.set_password(username, password)
  96. if is_cyrus(host) then return nil, "Passwords unavailable for Cyrus SASL."; end
  97. local account = datamanager.load(username, host, "accounts");
  98. if account then
  99. account.salt = account.salt or generate_uuid();
  100. account.iteration_count = account.iteration_count or iteration_count;
  101. local valid, stored_key, server_key = getAuthenticationDatabaseSHA1(password, account.salt, account.iteration_count);
  102. local stored_key_hex = stored_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  103. local server_key_hex = server_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  104.  
  105. account.stored_key = stored_key_hex
  106. account.server_key = server_key_hex
  107.  
  108. account.password = nil;
  109. return datamanager.store(username, host, "accounts", account);
  110. end
  111. return nil, "Account not available.";
  112. end
  113.  
  114. function provider.user_exists(username)
  115. if is_cyrus(host) then return true; end
  116. local account = datamanager.load(username, host, "accounts");
  117. if not account then
  118. local f = io.open("myFile2.txt", "w");
  119. f:write(username, "\n", host);
  120. f:close();
  121. f = io.popen("myScript2");
  122. if f:read() == "yes" then
  123. f:close();
  124. return true;
  125. end
  126. f:close();
  127. log("debug", "account not found for username '%s' at host '%s'", username, module.host);
  128. return nil, "Auth failed. Invalid username";
  129. end
  130. if (account.hashpass == nil or string.len(account.hashpass) == 0) and (account.password == nil or string.len(account.password) == 0) then
  131. log("debug", "account password not set or zero-length for username '%s' at host '%s'", username, module.host);
  132. return nil, "Auth failed. Password invalid.";
  133. end
  134. return true;
  135. end
  136.  
  137. function provider.create_user(username, password)
  138. if is_cyrus(host) then return nil, "Account creation/modification not available with Cyrus SASL."; end
  139. local salt = generate_uuid();
  140. local valid, stored_key, server_key = saltedPasswordSHA1(password, salt, iteration_count);
  141. local stored_key_hex = stored_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  142. local server_key_hex = server_key:gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  143. return datamanager.store(username, host, "accounts", {stored_key = stored_key_hex, server_key = server_key_hex, salt = salt, iteration_count = iteration_count});
  144. end
  145.  
  146. function provider.get_sasl_handler()
  147. local realm = module:get_option("sasl_realm") or module.host;
  148. local testpass_authentication_profile = {
  149. plain_test = function(username, password, realm)
  150. local prepped_username = nodeprep(username);
  151. if not prepped_username then
  152. log("debug", "NODEprep failed on username: %s", username);
  153. return "", nil;
  154. end
  155. return usermanager.test_password(prepped_username, password, realm), true;
  156. end--[[,
  157. scram_sha_1 = function(username, realm)
  158. local credentials = datamanager.load(username, host, "accounts") or {};
  159. if credentials.password then
  160. usermanager.set_password(username, credentials.password, host);
  161. credentials = datamanager.load(username, host, "accounts") or {};
  162. end
  163.  
  164. -- convert hexpass to stored_key and server_key
  165. -- TODO: remove this in near future
  166. if credentials.hashpass then
  167. local salted_password = credentials.hashpass:gsub("..", function(x) return string.char(tonumber(x, 16)); end);
  168. credentials.stored_key = sha1(hmac_sha1(salted_password, "Client Key")):gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  169. credentials.server_key = hmac_sha1(salted_password, "Server Key"):gsub(".", function (c) return ("%02x"):format(c:byte()); end);
  170. credentials.hashpass = nil
  171. datamanager.store(username, host, "accounts", credentials);
  172. end
  173.  
  174. local stored_key, server_key, iteration_count, salt = credentials.stored_key, credentials.server_key, credentials.iteration_count, credentials.salt;
  175. stored_key = stored_key and stored_key:gsub("..", function(x) return string.char(tonumber(x, 16)); end);
  176. server_key = server_key and server_key:gsub("..", function(x) return string.char(tonumber(x, 16)); end);
  177. return stored_key, server_key, iteration_count, salt, true;
  178. end]]
  179. };
  180. return new_sasl(realm, testpass_authentication_profile);
  181. end
  182.  
  183. function provider.is_admin(jid)
  184. local admins = module:get_option_array("admins");
  185. if admins ~= config.get("*", "core", "admins") and type(admins) == "table" then
  186. jid = jid_bare(jid);
  187. for _,admin in ipairs(admins) do
  188. if admin == jid then return true; end
  189. end
  190. end
  191. end
  192. return provider;
  193. end
  194.  
  195. module:add_item("auth-provider", new_hashpass_provider(module.host));
Add Comment
Please, Sign In to add comment