plugins/mod_auth_internal_hashed.lua
changeset 5500 eeea0eb2602a
parent 5302 52fe5df91c65
child 5776 bd0ff8ae98a8
equal deleted inserted replaced
5498:2a67235e1d4d 5500:eeea0eb2602a
     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());
    42 -- define auth provider
    43 -- define auth provider
    43 local provider = {};
    44 local provider = {};
    44 log("debug", "initializing internal_hashed authentication provider for host '%s'", host);
    45 log("debug", "initializing internal_hashed authentication provider for host '%s'", host);
    45 
    46 
    46 function provider.test_password(username, password)
    47 function provider.test_password(username, password)
    47 	local credentials = datamanager.load(username, host, "accounts") or {};
    48 	local credentials = accounts:get(username) or {};
    48 
    49 
    49 	if credentials.password ~= nil and string.len(credentials.password) ~= 0 then
    50 	if credentials.password ~= nil and string.len(credentials.password) ~= 0 then
    50 		if credentials.password ~= password then
    51 		if credentials.password ~= password then
    51 			return nil, "Auth failed. Provided password is incorrect.";
    52 			return nil, "Auth failed. Provided password is incorrect.";
    52 		end
    53 		end
    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);