comparison mod_extauth/mod_extauth.lua @ 158:1a5d5d4f08fe

Add "generic" script support to mod_extauth, as well as lpc support until waqas fixes process
author Jeff Mitchell <jeff@jefferai.org>
date Fri, 28 May 2010 16:19:27 -0400
parents 4ca382e8a4c5
children 75a85eac3c27
comparison
equal deleted inserted replaced
157:86c28405c5da 158:1a5d5d4f08fe
1 --
2 -- NOTE: currently this uses lpc; when waqas fixes process, it can go back to that
3 --
4 -- Prosody IM
5 -- Copyright (C) 2010 Waqas Hussain
6 -- Copyright (C) 2010 Jeff Mitchell
7 --
8 -- This project is MIT/X11 licensed. Please see the
9 -- COPYING file in the source package for more information.
10 --
1 11
2 12
3 local nodeprep = require "util.encodings".stringprep.nodeprep; 13 local nodeprep = require "util.encodings".stringprep.nodeprep;
4 local process = require "process"; 14 --local process = require "process";
15 local lpc = require "lpc";
5 16
6 local script_type = module:get_option("extauth_type"); 17 local config = require "core.configmanager";
7 assert(script_type == "ejabberd"); 18 local log = require "util.logger".init("usermanager");
8 local command = module:get_option("extauth_command"); 19 local host = module.host;
20 local script_type = config.get(host, "core", "extauth_type") or "generic";
21 assert(script_type == "ejabberd" or script_type == "generic");
22 local command = config.get(host, "core", "extauth_command") or "";
9 assert(type(command) == "string"); 23 assert(type(command) == "string");
10 local host = module.host;
11 assert(not host:find(":")); 24 assert(not host:find(":"));
25 local usermanager = require "core.usermanager";
26 local jid_bare = require "util.jid".bare;
12 27
13 local proc; 28 --local proc;
29 local pid;
30 local readfile;
31 local writefile;
14 local function send_query(text) 32 local function send_query(text)
15 if not proc then 33 -- if not proc then
16 proc = process.popen(command); 34 if not pid then
35 log("debug", "EXTAUTH: Opening process");
36 -- proc = process.popen(command);
37 pid, writefile, readfile = lpc.run(command);
17 end 38 end
18 proc:write(text); 39 -- if not proc then
19 proc:flush(); 40 if not pid then
20 return proc:read(4); -- FIXME do properly 41 log("debug", "EXTAUTH: Process failed to open");
42 return nil;
43 end
44 -- proc:write(text);
45 -- proc:flush();
46 writefile:write(text);
47 writefile:flush();
48 if script_type == "ejabberd" then
49 -- return proc:read(4); -- FIXME do properly
50 return readfile:read(4); -- FIXME do properly
51 elseif script_type == "generic" then
52 -- return proc:read(1);
53 return readfile:read();
54 end
21 end 55 end
22 56
23 function do_query(kind, username, password) 57 function do_query(kind, username, password)
24 if not username then return nil, "not-acceptable"; end 58 if not username then return nil, "not-acceptable"; end
25 username = nodeprep(username); 59 username = nodeprep(username);
27 61
28 local query = (password and "%s:%s:%s:%s" or "%s:%s:%s"):format(kind, username, host, password); 62 local query = (password and "%s:%s:%s:%s" or "%s:%s:%s"):format(kind, username, host, password);
29 local len = #query 63 local len = #query
30 if len > 1000 then return nil, "policy-violation"; end 64 if len > 1000 then return nil, "policy-violation"; end
31 65
32 local lo = len % 256; 66 if script_type == "ejabberd" then
33 local hi = (len - lo) / 256; 67 local lo = len % 256;
34 query = string.char(hi, lo)..query; 68 local hi = (len - lo) / 256;
69 query = string.char(hi, lo)..query;
70 end
71 if script_type == "generic" then
72 query = query..'\n';
73 end
35 74
36 local response = send_query(query); 75 local response = send_query(query);
37 if response == "\0\2\0\0" then 76 if (script_type == "ejabberd" and response == "\0\2\0\0") or
38 return nil, "not-authorized"; 77 (script_type == "generic" and response == "0") then
39 elseif response == "\0\2\0\1" then 78 return nil, "not-authorized";
40 return true; 79 elseif (script_type == "ejabberd" and response == "\0\2\0\1") or
80 (script_type == "generic" and response == "1") then
81 return true;
41 else 82 else
42 proc = nil; -- TODO kill proc 83 log("debug", "EXTAUTH: Nonsense back");
84 --proc:close();
85 --proc = nil;
43 return nil, "internal-server-error"; 86 return nil, "internal-server-error";
44 end 87 end
45 end 88 end
46 89
47 local provider = { name = "extauth" }; 90 function new_extauth_provider(host)
91 local provider = { name = "extauth" };
48 92
49 function provider.test_password(username, password) 93 function provider.test_password(username, password)
50 return do_query("auth", username, password); 94 return do_query("auth", username, password);
95 end
96
97 function provider.set_password(username, password)
98 return do_query("setpass", username, password);
99 end
100
101 function provider.user_exists(username)
102 return do_query("isuser", username);
103 end
104
105 function provider.create_user(username, password) return nil, "Account creation/modification not available."; end
106
107 function provider.get_supported_methods() return {["PLAIN"] = true}; end
108
109 function provider.is_admin(jid)
110 local admins = config.get(host, "core", "admins");
111 if admins ~= config.get("*", "core", "admins") then
112 if type(admins) == "table" then
113 jid = jid_bare(jid);
114 for _,admin in ipairs(admins) do
115 if admin == jid then return true; end
116 end
117 elseif admins then
118 log("error", "Option 'admins' for host '%s' is not a table", host);
119 end
120 end
121 return usermanager.is_admin(jid); -- Test whether it's a global admin instead
122 end
123
124 return provider;
51 end 125 end
52 126
53 function provider.set_password(username, password) 127 module:add_item("auth-provider", new_extauth_provider(module.host));
54 return do_query("setpass", username, password);
55 end
56
57 function provider.user_exists(username)
58 return do_query("isuser", username);
59 end
60
61 function provider.get_password() return nil, "Passwords not available."; end
62 function provider.create_user(username, password) return nil, "Account creation/modification not available."; end
63 function provider.get_supported_methods() return {["PLAIN"] = true}; end
64 local config = require "core.configmanager";
65 local usermanager = require "core.usermanager";
66 local jid_bare = require "util.jid".bare;
67 function provider.is_admin(jid)
68 local admins = config.get(host, "core", "admins");
69 if admins ~= config.get("*", "core", "admins") then
70 if type(admins) == "table" then
71 jid = jid_bare(jid);
72 for _,admin in ipairs(admins) do
73 if admin == jid then return true; end
74 end
75 elseif admins then
76 log("error", "Option 'admins' for host '%s' is not a table", host);
77 end
78 end
79 return usermanager.is_admin(jid); -- Test whether it's a global admin instead
80 end
81
82
83 module:add_item("auth-provider", provider);