plugins/mod_auth_internal_hashed.lua
author Kim Alvefur <zash@zash.se>
Thu, 23 Feb 2023 14:44:35 +0100
changeset 12907 13950bf92802
parent 12906 0a0a251bcd6c
child 12920 5a06d07596f9
permissions -rw-r--r--
mod_auth_internal_hashed: Implement methods to enable and disable users
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
     1
-- Prosody IM
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
     4
-- Copyright (C) 2010 Jeff Mitchell
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
     5
--
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
     6
-- This project is MIT/X11 licensed. Please see the
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
     7
-- COPYING file in the source package for more information.
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
     8
--
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
     9
6019
e9147a16059d mod_auth_interal_hashed: Update salt and iteration count when setting a new password
Florian Zeitz <florob@babelmonkeys.de>
parents: 5784
diff changeset
    10
local max = math.max;
e9147a16059d mod_auth_interal_hashed: Update salt and iteration count when setting a new password
Florian Zeitz <florob@babelmonkeys.de>
parents: 5784
diff changeset
    11
10222
e458578ddfd3 mod_auth_internal_hashed: Add support for optionally using SCRAM-SHA-256 instead of SHA-1
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
    12
local scram_hashers = require "util.sasl.scram".hashers;
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    13
local usermanager = require "core.usermanager";
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    14
local generate_uuid = require "util.uuid".generate;
3186
b5f261123013 mod_auth_internal, mod_auth_internal_hashed: Updated to provide get_sasl_handler.
Waqas Hussain <waqas20@gmail.com>
parents: 3180
diff changeset
    15
local new_sasl = require "util.sasl".new;
6710
06cdd4afaaf9 mod_auth_internal_hashed: Use util.hex
Kim Alvefur <zash@zash.se>
parents: 6019
diff changeset
    16
local hex = require"util.hex";
12359
a0ff5c438e9d util.hex: Deprecate to/from in favour of encode/decode, for consistency!
Matthew Wild <mwild1@gmail.com>
parents: 12132
diff changeset
    17
local to_hex, from_hex = hex.encode, hex.decode;
10918
0d7d71dee0a0 mod_auth_internal_*: Apply saslprep to passwords
Kim Alvefur <zash@zash.se>
parents: 10526
diff changeset
    18
local saslprep = require "util.encodings".stringprep.saslprep;
11548
c98aebe601f9 mod_auth_internal_{plain,hashed}: Use constant-time string comparison for secrets
Matthew Wild <mwild1@gmail.com>
parents: 10918
diff changeset
    19
local secure_equals = require "util.hashes".equals;
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    20
5783
3a81e3b0ea4f mod_auth_internal_hashed: Use logger setup by moduleapi instead of going for util.logger directly
Kim Alvefur <zash@zash.se>
parents: 5782
diff changeset
    21
local log = module._log;
5784
02217725454b mod_auth_internal_hashed: Log calls to provider methods and be consistent with mod_auth_internal_plain
Kim Alvefur <zash@zash.se>
parents: 5783
diff changeset
    22
local host = module.host;
5783
3a81e3b0ea4f mod_auth_internal_hashed: Use logger setup by moduleapi instead of going for util.logger directly
Kim Alvefur <zash@zash.se>
parents: 5782
diff changeset
    23
5500
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
    24
local accounts = module:open_store("accounts");
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
    25
10222
e458578ddfd3 mod_auth_internal_hashed: Add support for optionally using SCRAM-SHA-256 instead of SHA-1
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
    26
local hash_name = module:get_option_string("password_hash", "SHA-1");
e458578ddfd3 mod_auth_internal_hashed: Add support for optionally using SCRAM-SHA-256 instead of SHA-1
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
    27
local get_auth_db = assert(scram_hashers[hash_name], "SCRAM-"..hash_name.." not supported by SASL library");
10223
d58925bb74ca mod_auth_internal_hashed: Precompute SCRAM authentication profile name (thanks MattJ)
Kim Alvefur <zash@zash.se>
parents: 10222
diff changeset
    28
local scram_name = "scram_"..hash_name:gsub("%-","_"):lower();
3288
1a84d7d6f667 mod_auth_internal_hashed: Remove far too many instances of inline hex conversion using gsub, which was creating useless closures and what-not
Matthew Wild <mwild1@gmail.com>
parents: 3287
diff changeset
    29
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    30
-- Default; can be set per-user
12132
593e823566e1 mod_auth_internal_hashed: Up iteration count to 10000 per XEP-0438
Kim Alvefur <zash@zash.se>
parents: 12131
diff changeset
    31
local default_iteration_count = module:get_option_number("default_iteration_count", 10000);
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    32
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    33
-- define auth provider
5117
2c7e1ce8f482 mod_auth_*: Use module:provides().
Waqas Hussain <waqas20@gmail.com>
parents: 5116
diff changeset
    34
local provider = {};
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    35
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    36
function provider.test_password(username, password)
5784
02217725454b mod_auth_internal_hashed: Log calls to provider methods and be consistent with mod_auth_internal_plain
Kim Alvefur <zash@zash.se>
parents: 5783
diff changeset
    37
	log("debug", "test password for user '%s'", username);
5500
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
    38
	local credentials = accounts:get(username) or {};
10918
0d7d71dee0a0 mod_auth_internal_*: Apply saslprep to passwords
Kim Alvefur <zash@zash.se>
parents: 10526
diff changeset
    39
	password = saslprep(password);
0d7d71dee0a0 mod_auth_internal_*: Apply saslprep to passwords
Kim Alvefur <zash@zash.se>
parents: 10526
diff changeset
    40
	if not password then
0d7d71dee0a0 mod_auth_internal_*: Apply saslprep to passwords
Kim Alvefur <zash@zash.se>
parents: 10526
diff changeset
    41
		return nil, "Password fails SASLprep.";
0d7d71dee0a0 mod_auth_internal_*: Apply saslprep to passwords
Kim Alvefur <zash@zash.se>
parents: 10526
diff changeset
    42
	end
3166
3c46cb94caed Add mechanism for upgrading to hashed passwords from default. Remove some extra debug.
Jeff Mitchell <jeff@jefferai.org>
parents: 3164
diff changeset
    43
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    44
	if credentials.password ~= nil and string.len(credentials.password) ~= 0 then
11548
c98aebe601f9 mod_auth_internal_{plain,hashed}: Use constant-time string comparison for secrets
Matthew Wild <mwild1@gmail.com>
parents: 10918
diff changeset
    45
		if not secure_equals(saslprep(credentials.password), password) then
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    46
			return nil, "Auth failed. Provided password is incorrect.";
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    47
		end
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    48
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    49
		if provider.set_password(username, credentials.password) == nil then
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    50
			return nil, "Auth failed. Could not set hashed password from plaintext.";
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    51
		else
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    52
			return true;
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    53
		end
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    54
	end
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    55
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    56
	if credentials.iteration_count == nil or credentials.salt == nil or string.len(credentials.salt) == 0 then
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    57
		return nil, "Auth failed. Stored salt and iteration count information is not complete.";
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    58
	end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5500
diff changeset
    59
10222
e458578ddfd3 mod_auth_internal_hashed: Add support for optionally using SCRAM-SHA-256 instead of SHA-1
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
    60
	local valid, stored_key, server_key = get_auth_db(password, credentials.salt, credentials.iteration_count);
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5500
diff changeset
    61
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    62
	local stored_key_hex = to_hex(stored_key);
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    63
	local server_key_hex = to_hex(server_key);
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5500
diff changeset
    64
11548
c98aebe601f9 mod_auth_internal_{plain,hashed}: Use constant-time string comparison for secrets
Matthew Wild <mwild1@gmail.com>
parents: 10918
diff changeset
    65
	if valid and secure_equals(stored_key_hex, credentials.stored_key) and secure_equals(server_key_hex, credentials.server_key) then
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    66
		return true;
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    67
	else
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    68
		return nil, "Auth failed. Invalid username, password, or password hash information.";
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    69
	end
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    70
end
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    71
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    72
function provider.set_password(username, password)
5784
02217725454b mod_auth_internal_hashed: Log calls to provider methods and be consistent with mod_auth_internal_plain
Kim Alvefur <zash@zash.se>
parents: 5783
diff changeset
    73
	log("debug", "set_password for username '%s'", username);
5500
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
    74
	local account = accounts:get(username);
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    75
	if account then
6019
e9147a16059d mod_auth_interal_hashed: Update salt and iteration count when setting a new password
Florian Zeitz <florob@babelmonkeys.de>
parents: 5784
diff changeset
    76
		account.salt = generate_uuid();
e9147a16059d mod_auth_interal_hashed: Update salt and iteration count when setting a new password
Florian Zeitz <florob@babelmonkeys.de>
parents: 5784
diff changeset
    77
		account.iteration_count = max(account.iteration_count or 0, default_iteration_count);
10222
e458578ddfd3 mod_auth_internal_hashed: Add support for optionally using SCRAM-SHA-256 instead of SHA-1
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
    78
		local valid, stored_key, server_key = get_auth_db(password, account.salt, account.iteration_count);
10526
b1ca849b8e3a mod_auth_internal_hashed: Pass on errors from password hash function (fixes #1477)
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
    79
		if not valid then
b1ca849b8e3a mod_auth_internal_hashed: Pass on errors from password hash function (fixes #1477)
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
    80
			return valid, stored_key;
b1ca849b8e3a mod_auth_internal_hashed: Pass on errors from password hash function (fixes #1477)
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
    81
		end
3288
1a84d7d6f667 mod_auth_internal_hashed: Remove far too many instances of inline hex conversion using gsub, which was creating useless closures and what-not
Matthew Wild <mwild1@gmail.com>
parents: 3287
diff changeset
    82
		local stored_key_hex = to_hex(stored_key);
1a84d7d6f667 mod_auth_internal_hashed: Remove far too many instances of inline hex conversion using gsub, which was creating useless closures and what-not
Matthew Wild <mwild1@gmail.com>
parents: 3287
diff changeset
    83
		local server_key_hex = to_hex(server_key);
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5500
diff changeset
    84
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    85
		account.stored_key = stored_key_hex
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    86
		account.server_key = server_key_hex
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
    87
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    88
		account.password = nil;
12650
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
    89
		account.updated = os.time();
5500
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
    90
		return accounts:set(username, account);
3994
42899d5efe3b mod_auth_internal_*: Support for delete_user method
Matthew Wild <mwild1@gmail.com>
parents: 3981
diff changeset
    91
	end
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    92
	return nil, "Account not available.";
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
    93
end
3994
42899d5efe3b mod_auth_internal_*: Support for delete_user method
Matthew Wild <mwild1@gmail.com>
parents: 3981
diff changeset
    94
12650
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
    95
function provider.get_account_info(username)
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
    96
	local account = accounts:get(username);
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
    97
	if not account then return nil, "Account not available"; end
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
    98
	return {
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
    99
		created = account.created;
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
   100
		password_updated = account.updated;
12906
0a0a251bcd6c mod_auth_internal_hashed: Implement is_enabled() method
Kim Alvefur <zash@zash.se>
parents: 12905
diff changeset
   101
		enabled = not account.disabled;
12650
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
   102
	};
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
   103
end
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
   104
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   105
function provider.user_exists(username)
5500
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
   106
	local account = accounts:get(username);
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   107
	if not account then
5784
02217725454b mod_auth_internal_hashed: Log calls to provider methods and be consistent with mod_auth_internal_plain
Kim Alvefur <zash@zash.se>
parents: 5783
diff changeset
   108
		log("debug", "account not found for username '%s'", username);
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   109
		return nil, "Auth failed. Invalid username";
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
   110
	end
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   111
	return true;
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   112
end
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   113
12904
5484debdfdfe mod_auth_internal_hashed: Refactor to prepare for disabling users
Kim Alvefur <zash@zash.se>
parents: 12673
diff changeset
   114
function provider.is_enabled(username) -- luacheck: ignore 212
12906
0a0a251bcd6c mod_auth_internal_hashed: Implement is_enabled() method
Kim Alvefur <zash@zash.se>
parents: 12905
diff changeset
   115
	local info, err = provider.get_account_info(username);
0a0a251bcd6c mod_auth_internal_hashed: Implement is_enabled() method
Kim Alvefur <zash@zash.se>
parents: 12905
diff changeset
   116
	if not info then return nil, err; end
0a0a251bcd6c mod_auth_internal_hashed: Implement is_enabled() method
Kim Alvefur <zash@zash.se>
parents: 12905
diff changeset
   117
	return info.enabled;
12904
5484debdfdfe mod_auth_internal_hashed: Refactor to prepare for disabling users
Kim Alvefur <zash@zash.se>
parents: 12673
diff changeset
   118
end
5484debdfdfe mod_auth_internal_hashed: Refactor to prepare for disabling users
Kim Alvefur <zash@zash.se>
parents: 12673
diff changeset
   119
12907
13950bf92802 mod_auth_internal_hashed: Implement methods to enable and disable users
Kim Alvefur <zash@zash.se>
parents: 12906
diff changeset
   120
function provider.enable(username)
13950bf92802 mod_auth_internal_hashed: Implement methods to enable and disable users
Kim Alvefur <zash@zash.se>
parents: 12906
diff changeset
   121
	-- TODO map store?
13950bf92802 mod_auth_internal_hashed: Implement methods to enable and disable users
Kim Alvefur <zash@zash.se>
parents: 12906
diff changeset
   122
	local account = accounts:get(username);
13950bf92802 mod_auth_internal_hashed: Implement methods to enable and disable users
Kim Alvefur <zash@zash.se>
parents: 12906
diff changeset
   123
	account.disabled = nil;
13950bf92802 mod_auth_internal_hashed: Implement methods to enable and disable users
Kim Alvefur <zash@zash.se>
parents: 12906
diff changeset
   124
	return accounts:set(username, account);
12905
b884ddb5a0e7 mod_auth_internal_hashed: Add stub methods for enabling and disabling users
Kim Alvefur <zash@zash.se>
parents: 12904
diff changeset
   125
end
b884ddb5a0e7 mod_auth_internal_hashed: Add stub methods for enabling and disabling users
Kim Alvefur <zash@zash.se>
parents: 12904
diff changeset
   126
12907
13950bf92802 mod_auth_internal_hashed: Implement methods to enable and disable users
Kim Alvefur <zash@zash.se>
parents: 12906
diff changeset
   127
function provider.disable(username)
13950bf92802 mod_auth_internal_hashed: Implement methods to enable and disable users
Kim Alvefur <zash@zash.se>
parents: 12906
diff changeset
   128
	local account = accounts:get(username);
13950bf92802 mod_auth_internal_hashed: Implement methods to enable and disable users
Kim Alvefur <zash@zash.se>
parents: 12906
diff changeset
   129
	account.disabled = true;
13950bf92802 mod_auth_internal_hashed: Implement methods to enable and disable users
Kim Alvefur <zash@zash.se>
parents: 12906
diff changeset
   130
	return accounts:set(username, account);
12905
b884ddb5a0e7 mod_auth_internal_hashed: Add stub methods for enabling and disabling users
Kim Alvefur <zash@zash.se>
parents: 12904
diff changeset
   131
end
b884ddb5a0e7 mod_auth_internal_hashed: Add stub methods for enabling and disabling users
Kim Alvefur <zash@zash.se>
parents: 12904
diff changeset
   132
5156
6b08c922a2e4 mod_auth_internal_{plain,hashed}: Add support for iterating over accounts
Kim Alvefur <zash@zash.se>
parents: 5117
diff changeset
   133
function provider.users()
5500
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
   134
	return accounts:users();
5156
6b08c922a2e4 mod_auth_internal_{plain,hashed}: Add support for iterating over accounts
Kim Alvefur <zash@zash.se>
parents: 5117
diff changeset
   135
end
6b08c922a2e4 mod_auth_internal_{plain,hashed}: Add support for iterating over accounts
Kim Alvefur <zash@zash.se>
parents: 5117
diff changeset
   136
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   137
function provider.create_user(username, password)
12673
aed38948791f mod_auth_internal_hashed: Allow creating disabled account without password
Kim Alvefur <zash@zash.se>
parents: 12650
diff changeset
   138
	local now = os.time();
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   139
	if password == nil then
12673
aed38948791f mod_auth_internal_hashed: Allow creating disabled account without password
Kim Alvefur <zash@zash.se>
parents: 12650
diff changeset
   140
		return accounts:set(username, { created = now; updated = now; disabled = true });
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   141
	end
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   142
	local salt = generate_uuid();
10222
e458578ddfd3 mod_auth_internal_hashed: Add support for optionally using SCRAM-SHA-256 instead of SHA-1
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
   143
	local valid, stored_key, server_key = get_auth_db(password, salt, default_iteration_count);
10526
b1ca849b8e3a mod_auth_internal_hashed: Pass on errors from password hash function (fixes #1477)
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
   144
	if not valid then
b1ca849b8e3a mod_auth_internal_hashed: Pass on errors from password hash function (fixes #1477)
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
   145
		return valid, stored_key;
b1ca849b8e3a mod_auth_internal_hashed: Pass on errors from password hash function (fixes #1477)
Kim Alvefur <zash@zash.se>
parents: 8195
diff changeset
   146
	end
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   147
	local stored_key_hex = to_hex(stored_key);
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   148
	local server_key_hex = to_hex(server_key);
8059
cacf14c218ab mod_auth_internal_hashed: Split long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8058
diff changeset
   149
	return accounts:set(username, {
cacf14c218ab mod_auth_internal_hashed: Split long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8058
diff changeset
   150
		stored_key = stored_key_hex, server_key = server_key_hex,
12650
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
   151
		salt = salt, iteration_count = default_iteration_count,
3f38f4735c7a usermanager, mod_auth_*: Add get_account_info() returning creation/update time
Matthew Wild <mwild1@gmail.com>
parents: 12359
diff changeset
   152
		created = now, updated = now;
8059
cacf14c218ab mod_auth_internal_hashed: Split long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8058
diff changeset
   153
	});
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
   154
end
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
   155
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   156
function provider.delete_user(username)
5500
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
   157
	return accounts:set(username, nil);
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   158
end
3164
db9def53fe9c Check in mod_hashpassauth -- works!
Jeff Mitchell <jeff@jefferai.org>
parents:
diff changeset
   159
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   160
function provider.get_sasl_handler()
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   161
	local testpass_authentication_profile = {
8058
b08d9295f036 mod_auth_internal_hashed: Rename unused 'self' to _ [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6710
diff changeset
   162
		plain_test = function(_, username, password, realm)
12904
5484debdfdfe mod_auth_internal_hashed: Refactor to prepare for disabling users
Kim Alvefur <zash@zash.se>
parents: 12673
diff changeset
   163
			return usermanager.test_password(username, realm, password), provider.is_enabled(username);
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   164
		end,
10223
d58925bb74ca mod_auth_internal_hashed: Precompute SCRAM authentication profile name (thanks MattJ)
Kim Alvefur <zash@zash.se>
parents: 10222
diff changeset
   165
		[scram_name] = function(_, username)
5500
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
   166
			local credentials = accounts:get(username);
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   167
			if not credentials then return; end
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   168
			if credentials.password then
8195
4354f556c5db core.usermanager, various modules: Disconnect other resources on password change (thanks waqas) (fixes #512)
Kim Alvefur <zash@zash.se>
parents: 8059
diff changeset
   169
				if provider.set_password(username, credentials.password) == nil then
4354f556c5db core.usermanager, various modules: Disconnect other resources on password change (thanks waqas) (fixes #512)
Kim Alvefur <zash@zash.se>
parents: 8059
diff changeset
   170
					return nil, "Auth failed. Could not set hashed password from plaintext.";
4354f556c5db core.usermanager, various modules: Disconnect other resources on password change (thanks waqas) (fixes #512)
Kim Alvefur <zash@zash.se>
parents: 8059
diff changeset
   171
				end
5500
eeea0eb2602a mod_auth_internal_hashed, mod_auth_internal_plain, mod_privacy, mod_private, mod_register, mod_vcard, mod_muc: Use module:open_store()
Kim Alvefur <zash@zash.se>
parents: 5302
diff changeset
   172
				credentials = accounts:get(username);
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   173
				if not credentials then return; end
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   174
			end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5500
diff changeset
   175
8059
cacf14c218ab mod_auth_internal_hashed: Split long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8058
diff changeset
   176
			local stored_key, server_key = credentials.stored_key, credentials.server_key;
cacf14c218ab mod_auth_internal_hashed: Split long lines [luacheck]
Kim Alvefur <zash@zash.se>
parents: 8058
diff changeset
   177
			local iteration_count, salt = credentials.iteration_count, credentials.salt;
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   178
			stored_key = stored_key and from_hex(stored_key);
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   179
			server_key = server_key and from_hex(server_key);
12906
0a0a251bcd6c mod_auth_internal_hashed: Implement is_enabled() method
Kim Alvefur <zash@zash.se>
parents: 12905
diff changeset
   180
			return stored_key, server_key, iteration_count, salt, not credentials.disabled;
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   181
		end
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   182
	};
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   183
	return new_sasl(host, testpass_authentication_profile);
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   184
end
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5500
diff changeset
   185
5117
2c7e1ce8f482 mod_auth_*: Use module:provides().
Waqas Hussain <waqas20@gmail.com>
parents: 5116
diff changeset
   186
module:provides("auth", provider);
5116
5f9066db1b4d mod_auth_internal_hashed: Get rid of useless wrapper function new_hashpass_provider.
Waqas Hussain <waqas20@gmail.com>
parents: 4764
diff changeset
   187