2 -- Copyright (C) 2014 Matthew Wild
4 -- This project is MIT/X11 licensed. Please see the
5 -- COPYING file in the source package for more information.
8 local usermanager
= require
"core.usermanager";
9 local new_sasl
= require
"util.sasl".new
;
11 local nodeprep
= require
"util.encodings".stringprep
.nodeprep
;
12 local nameprep
= require
"util.encodings".stringprep
.nameprep
;
13 local md5
= require
"util.hashes".md5
;
15 local host
= module
.host
;
17 local auth_filename
= module
:get_option_string("auth_ha1_file", "auth.txt");
20 function reload_auth_data()
21 local f
, err
= io
.open(auth_filename
);
23 module
:log("error", "Failed to read from auth file: %s", err
);
27 local line_number
, imported_count
, not_authorized_count
= 0, 0, 0;
28 for line
in f
:lines() do
29 line_number
= line_number
+ 1;
30 local username
, hash
, realm
, state
= line
:match("^([^:]+):(%x+):([^:]+):(.+)$");
32 if line
:sub(1,1) ~= "#" then
33 module
:log("error", "Unable to parse line %d of auth file, skipping", line_number
);
36 username
, realm
= nodeprep(username
), nameprep(realm
);
38 module
:log("error", "Invalid username on line %d of auth file, skipping", line_number
);
40 module
:log("error", "Invalid hostname/realm on line %d of auth file, skipping", line_number
);
41 elseif state
~= "authorized" then
42 not_authorized_count
= not_authorized_count
+ 1;
43 elseif realm
== host
then
44 auth_data
[username
] = hash
;
45 imported_count
= imported_count
+ 1;
50 module
:log("debug", "Loaded %d accounts from auth file (%d authorized)", imported_count
, imported_count
-not_authorized_count
);
53 function module
.load()
57 module
:hook_global("config-reloaded", reload_auth_data
);
59 -- define auth provider
62 function provider
.test_password(username
, password
)
63 module
:log("debug", "test password for user %s at host %s, %s", username
, host
, password
);
65 local test_hash
= md5(username
..":"..host
..":"..password
, true);
67 if test_hash
== auth_data
[username
] then
70 return nil, "Auth failed. Invalid username or password.";
74 function provider
.set_password(username
, password
)
75 return nil, "Changing passwords not supported";
78 function provider
.user_exists(username
)
79 if not auth_data
[username
] then
80 module
:log("debug", "account not found for username '%s' at host '%s'", username
, host
);
81 return nil, "Auth failed. Invalid username";
86 function provider
.create_user(username
, password
)
87 return nil, "User creation not supported";
90 function provider
.delete_user(username
)
91 return nil , "User deletion not supported";
94 function provider
.get_sasl_handler()
95 return new_sasl(host
, {
96 plain_test
= function(sasl
, username
, password
, realm
)
97 return usermanager
.test_password(username
, realm
, password
), true;
102 module
:provides("auth", provider
);