comparison plugins/mod_hashpassauth.lua @ 3166:3c46cb94caed

Add mechanism for upgrading to hashed passwords from default. Remove some extra debug.
author Jeff Mitchell <jeff@jefferai.org>
date Thu, 27 May 2010 10:54:11 -0400
parents db9def53fe9c
children 546695e80e0a
comparison
equal deleted inserted replaced
3165:4ffb5469c1f6 3166:3c46cb94caed
30 function new_hashpass_provider(host) 30 function new_hashpass_provider(host)
31 local provider = { name = "hashpass" }; 31 local provider = { name = "hashpass" };
32 log("debug", "initializing hashpass authentication provider for host '%s'", host); 32 log("debug", "initializing hashpass authentication provider for host '%s'", host);
33 33
34 function provider.test_password(username, password) 34 function provider.test_password(username, password)
35 log("debug", "test password for user %s at host %s", username, module.host);
36 if is_cyrus(host) then return nil, "Legacy auth not supported with Cyrus SASL."; end 35 if is_cyrus(host) then return nil, "Legacy auth not supported with Cyrus SASL."; end
37 local credentials = datamanager.load(username, host, "accounts") or {}; 36 local credentials = datamanager.load(username, host, "accounts") or {};
38 37
39 if credentials.hashpass == nil or credentials.iteration_count == nil or credentials.salt == nil then 38 if credentials.iteration_count == nil or credentials.salt == nil or string.len(credentials.salt) == 0 then
40 return nil, "Auth failed. Stored credential information is not complete."; 39 return nil, "Auth failed. Stored salt and iteration count information is not complete.";
40 end
41
42 if credentials.password ~= nil and string.len(credentials.password) ~= 0 then
43 if credentials.password ~= password then
44 return nil, "Auth failed. Provided password is incorrect.";
45 end
46
47 if provider.set_password(username, credentials.password) == nil then
48 return nil, "Auth failed. Could not set hashed password from plaintext.";
49 else
50 return true;
51 end
41 end 52 end
42 53
43 local valid, binpass = saltedPasswordSHA1(password, credentials.salt, credentials.iteration_count); 54 local valid, binpass = saltedPasswordSHA1(password, credentials.salt, credentials.iteration_count);
44 local hexpass = binpass:gsub(".", function (c) return ("%02x"):format(c:byte()); end); 55 local hexpass = binpass:gsub(".", function (c) return ("%02x"):format(c:byte()); end);
45 if valid then 56
46 log("debug", "salted password returned valid");
47 else
48 log("debug", "salted password returned not valid");
49 end
50 log("debug", "hexpass is '%s', stored pass is '%s'", hexpass, credentials.hashpass);
51 if valid and hexpass == credentials.hashpass then 57 if valid and hexpass == credentials.hashpass then
52 return true; 58 return true;
53 else 59 else
54 return nil, "Auth failed. Invalid username, password, or password hash information."; 60 return nil, "Auth failed. Invalid username, password, or password hash information.";
55 end 61 end
56 end 62 end
57 63
58 function provider.get_password(username) 64 function provider.get_password(username)
59 log("debug", "get_password for username '%s' at host '%s'", username, module.host);
60 if is_cyrus(host) then return nil, "Passwords unavailable for Cyrus SASL."; end 65 if is_cyrus(host) then return nil, "Passwords unavailable for Cyrus SASL."; end
61 return (datamanager.load(username, host, "accounts") or {}).hashpass; 66 local credentials = datamanager.load(username, host, "accounts") or {};
67 if(credentials.password ~= nil or (credentials.password ~= nil and string.len(credentials.password) ~= 0)) then
68 if provider.set_password(username, credentials.password) == nil then
69 return nil, "Problem setting plaintext password to hashed password.";
70 end
71 credentials = datamanager.load(username, host, "accounts");
72 return credentials.hashpass;
73 end
74 return credentials.hashpass;
62 end 75 end
63 76
64 function provider.set_password(username, password) 77 function provider.set_password(username, password)
65 if is_cyrus(host) then return nil, "Passwords unavailable for Cyrus SASL."; end 78 if is_cyrus(host) then return nil, "Passwords unavailable for Cyrus SASL."; end
66 local account = datamanager.load(username, host, "accounts"); 79 local account = datamanager.load(username, host, "accounts");
75 88
76 local valid, binpass = saltedPasswordSHA1(password, account.salt, account.iteration_count); 89 local valid, binpass = saltedPasswordSHA1(password, account.salt, account.iteration_count);
77 local hexpass = binpass:gsub(".", function (c) return ("%02x"):format(c:byte()); end); 90 local hexpass = binpass:gsub(".", function (c) return ("%02x"):format(c:byte()); end);
78 account.hashpass = hexpass; 91 account.hashpass = hexpass;
79 92
93 account.password = nil;
80 return datamanager.store(username, host, "accounts", account); 94 return datamanager.store(username, host, "accounts", account);
81 end 95 end
82 return nil, "Account not available."; 96 return nil, "Account not available.";
83 end 97 end
84 98
87 local account = datamanager.load(username, host, "accounts"); 101 local account = datamanager.load(username, host, "accounts");
88 if not account then 102 if not account then
89 log("debug", "account not found for username '%s' at host '%s'", username, module.host); 103 log("debug", "account not found for username '%s' at host '%s'", username, module.host);
90 return nil, "Auth failed. Invalid username"; 104 return nil, "Auth failed. Invalid username";
91 end 105 end
92 if account.hashpass == nil or string.len(account.hashpass) == 0 then 106 if (account.hashpass == nil or string.len(account.hashpass) == 0) and (account.password == nil or string.len(account.password) == 0) then
93 log("debug", "account password not set or zero-length for username '%s' at host '%s'", username, module.host); 107 log("debug", "account password not set or zero-length for username '%s' at host '%s'", username, module.host);
94 return nil, "Auth failed. Password invalid."; 108 return nil, "Auth failed. Password invalid.";
95 end 109 end
96 return true; 110 return true;
97 end 111 end