Comparison

plugins/mod_admin_telnet.lua @ 5024:d25e1b9332cc

Merge with Florob
author Matthew Wild <mwild1@gmail.com>
date Sat, 28 Jul 2012 01:14:31 +0100
parent 5023:dcc8e789df36
parent 5013:ab693eea0869
child 5025:e68d1b85ee3a
comparison
equal deleted inserted replaced
5023:dcc8e789df36 5024:d25e1b9332cc
11 local _G = _G; 11 local _G = _G;
12 12
13 local prosody = _G.prosody; 13 local prosody = _G.prosody;
14 local hosts = prosody.hosts; 14 local hosts = prosody.hosts;
15 15
16 local console_listener = { default_port = 5582; default_mode = "*l"; interface = "127.0.0.1" }; 16 local console_listener = { default_port = 5582; default_mode = "*a"; interface = "127.0.0.1" };
17 17
18 local hostmanager = require "core.hostmanager"; 18 local hostmanager = require "core.hostmanager";
19 local modulemanager = require "core.modulemanager"; 19 local modulemanager = require "core.modulemanager";
20 20
21 local iterators = require "util.iterators"; 21 local iterators = require "util.iterators";
28 local envloadfile = require "util.envload".envloadfile; 28 local envloadfile = require "util.envload".envloadfile;
29 29
30 local commands = module:shared("commands") 30 local commands = module:shared("commands")
31 local def_env = module:shared("env"); 31 local def_env = module:shared("env");
32 local default_env_mt = { __index = def_env }; 32 local default_env_mt = { __index = def_env };
33 local core_post_stanza = prosody.core_post_stanza;
33 34
34 local function redirect_output(_G, session) 35 local function redirect_output(_G, session)
35 local env = setmetatable({ print = session.print }, { __index = function (t, k) return rawget(_G, k); end }); 36 local env = setmetatable({ print = session.print }, { __index = function (t, k) return rawget(_G, k); end });
36 env.dofile = function(name) 37 env.dofile = function(name)
37 local f, err = envloadfile(name, env); 38 local f, err = envloadfile(name, env);
79 end 80 end
80 81
81 function console_listener.onincoming(conn, data) 82 function console_listener.onincoming(conn, data)
82 local session = sessions[conn]; 83 local session = sessions[conn];
83 84
84 -- Handle data 85 local partial = session.partial_data;
85 (function(session, data) 86 if partial then
86 local useglobalenv; 87 data = partial..data;
88 end
89
90 for line in data:gmatch("[^\n]*[\n\004]") do
91 -- Handle data (loop allows us to break to add \0 after response)
92 repeat
93 local useglobalenv;
94
95 if line:match("^>") then
96 line = line:gsub("^>", "");
97 useglobalenv = true;
98 elseif line == "\004" then
99 commands["bye"](session, line);
100 break;
101 else
102 local command = line:match("^%w+") or line:match("%p");
103 if commands[command] then
104 commands[command](session, line);
105 break;
106 end
107 end
108
109 session.env._ = line;
110
111 local chunkname = "=console";
112 local env = (useglobalenv and redirect_output(_G, session)) or session.env or nil
113 local chunk, err = envload("return "..line, chunkname, env);
114 if not chunk then
115 chunk, err = envload(line, chunkname, env);
116 if not chunk then
117 err = err:gsub("^%[string .-%]:%d+: ", "");
118 err = err:gsub("^:%d+: ", "");
119 err = err:gsub("'<eof>'", "the end of the line");
120 session.print("Sorry, I couldn't understand that... "..err);
121 break;
122 end
123 end
87 124
88 if data:match("^>") then 125 local ranok, taskok, message = pcall(chunk);
89 data = data:gsub("^>", ""); 126
90 useglobalenv = true; 127 if not (ranok or message or useglobalenv) and commands[line:lower()] then
91 elseif data == "\004" then 128 commands[line:lower()](session, line);
92 commands["bye"](session, data); 129 break;
93 return; 130 end
94 else 131
95 local command = data:lower(); 132 if not ranok then
96 command = data:match("^%w+") or data:match("%p"); 133 session.print("Fatal error while running command, it did not complete");
97 if commands[command] then 134 session.print("Error: "..taskok);
98 commands[command](session, data); 135 break;
99 return; 136 end
100 end 137
101 end 138 if not message then
102 139 session.print("Result: "..tostring(taskok));
103 session.env._ = data; 140 break;
141 elseif (not taskok) and message then
142 session.print("Command completed with a problem");
143 session.print("Message: "..tostring(message));
144 break;
145 end
146
147 session.print("OK: "..tostring(message));
148 until true
104 149
105 local chunkname = "=console"; 150 session.send(string.char(0));
106 local env = (useglobalenv and redirect_output(_G, session)) or session.env or nil 151 end
107 local chunk, err = envload("return "..data, chunkname, env); 152 session.partial_data = data:match("[^\n]+$");
108 if not chunk then
109 chunk, err = envload(data, chunkname, env);
110 if not chunk then
111 err = err:gsub("^%[string .-%]:%d+: ", "");
112 err = err:gsub("^:%d+: ", "");
113 err = err:gsub("'<eof>'", "the end of the line");
114 session.print("Sorry, I couldn't understand that... "..err);
115 return;
116 end
117 end
118
119 local ranok, taskok, message = pcall(chunk);
120
121 if not (ranok or message or useglobalenv) and commands[data:lower()] then
122 commands[data:lower()](session, data);
123 return;
124 end
125
126 if not ranok then
127 session.print("Fatal error while running command, it did not complete");
128 session.print("Error: "..taskok);
129 return;
130 end
131
132 if not message then
133 session.print("Result: "..tostring(taskok));
134 return;
135 elseif (not taskok) and message then
136 session.print("Command completed with a problem");
137 session.print("Message: "..tostring(message));
138 return;
139 end
140
141 session.print("OK: "..tostring(message));
142 end)(session, data);
143
144 session.send(string.char(0));
145 end 153 end
146 154
147 function console_listener.ondisconnect(conn, err) 155 function console_listener.ondisconnect(conn, err)
148 local session = sessions[conn]; 156 local session = sessions[conn];
149 if session then 157 if session then
189 print [[]] 197 print [[]]
190 print [[c2s - Commands to manage local client-to-server sessions]] 198 print [[c2s - Commands to manage local client-to-server sessions]]
191 print [[s2s - Commands to manage sessions between this server and others]] 199 print [[s2s - Commands to manage sessions between this server and others]]
192 print [[module - Commands to load/reload/unload modules/plugins]] 200 print [[module - Commands to load/reload/unload modules/plugins]]
193 print [[host - Commands to activate, deactivate and list virtual hosts]] 201 print [[host - Commands to activate, deactivate and list virtual hosts]]
202 print [[user - Commands to create and delete users, and change their passwords]]
194 print [[server - Uptime, version, shutting down, etc.]] 203 print [[server - Uptime, version, shutting down, etc.]]
195 print [[config - Reloading the configuration, etc.]] 204 print [[config - Reloading the configuration, etc.]]
196 print [[console - Help regarding the console itself]] 205 print [[console - Help regarding the console itself]]
197 elseif section == "c2s" then 206 elseif section == "c2s" then
198 print [[c2s:show(jid) - Show all client sessions with the specified JID (or all if no JID given)]] 207 print [[c2s:show(jid) - Show all client sessions with the specified JID (or all if no JID given)]]
200 print [[c2s:show_secure() - Show all encrypted client connections]] 209 print [[c2s:show_secure() - Show all encrypted client connections]]
201 print [[c2s:close(jid) - Close all sessions for the specified JID]] 210 print [[c2s:close(jid) - Close all sessions for the specified JID]]
202 elseif section == "s2s" then 211 elseif section == "s2s" then
203 print [[s2s:show(domain) - Show all s2s connections for the given domain (or all if no domain given)]] 212 print [[s2s:show(domain) - Show all s2s connections for the given domain (or all if no domain given)]]
204 print [[s2s:close(from, to) - Close a connection from one domain to another]] 213 print [[s2s:close(from, to) - Close a connection from one domain to another]]
214 print [[s2s:closeall(host) - Close all the incoming/outgoing s2s sessions to specified host]]
205 elseif section == "module" then 215 elseif section == "module" then
206 print [[module:load(module, host) - Load the specified module on the specified host (or all hosts if none given)]] 216 print [[module:load(module, host) - Load the specified module on the specified host (or all hosts if none given)]]
207 print [[module:reload(module, host) - The same, but unloads and loads the module (saving state if the module supports it)]] 217 print [[module:reload(module, host) - The same, but unloads and loads the module (saving state if the module supports it)]]
208 print [[module:unload(module, host) - The same, but just unloads the module from memory]] 218 print [[module:unload(module, host) - The same, but just unloads the module from memory]]
209 print [[module:list(host) - List the modules loaded on the specified host]] 219 print [[module:list(host) - List the modules loaded on the specified host]]
210 elseif section == "host" then 220 elseif section == "host" then
211 print [[host:activate(hostname) - Activates the specified host]] 221 print [[host:activate(hostname) - Activates the specified host]]
212 print [[host:deactivate(hostname) - Disconnects all clients on this host and deactivates]] 222 print [[host:deactivate(hostname) - Disconnects all clients on this host and deactivates]]
213 print [[host:list() - List the currently-activated hosts]] 223 print [[host:list() - List the currently-activated hosts]]
224 elseif section == "user" then
225 print [[user:create(jid, password) - Create the specified user account]]
226 print [[user:password(jid, password) - Set the password for the specified user account]]
227 print [[user:delete(jid, password) - Permanently remove the specified user account]]
214 elseif section == "server" then 228 elseif section == "server" then
215 print [[server:version() - Show the server's version number]] 229 print [[server:version() - Show the server's version number]]
216 print [[server:uptime() - Show how long the server has been running]] 230 print [[server:uptime() - Show how long the server has been running]]
217 print [[server:shutdown(reason) - Shut down the server, with an optional reason to be broadcast to all connections]] 231 print [[server:shutdown(reason) - Shut down the server, with an optional reason to be broadcast to all connections]]
218 elseif section == "config" then 232 elseif section == "config" then
677 end 691 end
678 end 692 end
679 end 693 end
680 local domain_certs = array.collect(values(cert_set)); 694 local domain_certs = array.collect(values(cert_set));
681 -- Phew. We now have a array of unique certificates presented by domain. 695 -- Phew. We now have a array of unique certificates presented by domain.
682 local print = self.session.print;
683 local n_certs = #domain_certs; 696 local n_certs = #domain_certs;
684 697
685 if n_certs == 0 then 698 if n_certs == 0 then
686 return "No certificates found for "..domain; 699 return "No certificates found for "..domain;
687 end 700 end
769 else 782 else
770 return false, "Neither of the hostnames you specified are being used on this server"; 783 return false, "Neither of the hostnames you specified are being used on this server";
771 end 784 end
772 785
773 return true, "Closed "..count.." s2s session"..((count == 1 and "") or "s"); 786 return true, "Closed "..count.." s2s session"..((count == 1 and "") or "s");
787 end
788
789 function def_env.s2s:closeall(host)
790 local count = 0;
791
792 if not host or type(host) ~= "string" then return false, "wrong syntax: please use s2s:closeall('hostname.tld')"; end
793 if hosts[host] then
794 for session in pairs(incoming_s2s) do
795 if session.to_host == host then
796 (session.close or s2smanager.destroy_session)(session);
797 count = count + 1;
798 end
799 end
800 for _, session in pairs(hosts[host].s2sout) do
801 (session.close or s2smanager.destroy_session)(session);
802 count = count + 1;
803 end
804 else
805 for session in pairs(incoming_s2s) do
806 if session.from_host == host then
807 (session.close or s2smanager.destroy_session)(session);
808 count = count + 1;
809 end
810 end
811 for _, h in pairs(hosts) do
812 if h.s2sout[host] then
813 (h.s2sout[host].close or s2smanager.destroy_session)(h.s2sout[host]);
814 count = count + 1;
815 end
816 end
817 end
818
819 if count == 0 then return false, "No sessions to close.";
820 else return true, "Closed "..count.." s2s session"..((count == 1 and "") or "s"); end
774 end 821 end
775 822
776 def_env.host = {}; def_env.hosts = def_env.host; 823 def_env.host = {}; def_env.hosts = def_env.host;
777 824
778 function def_env.host:activate(hostname, config) 825 function def_env.host:activate(hostname, config)
858 return nil, "No such room: "..room_jid; 905 return nil, "No such room: "..room_jid;
859 end 906 end
860 return setmetatable({ room = room_obj }, console_room_mt); 907 return setmetatable({ room = room_obj }, console_room_mt);
861 end 908 end
862 909
910 local um = require"core.usermanager";
911
912 def_env.user = {};
913 function def_env.user:create(jid, password)
914 local username, host = jid_split(jid);
915 local ok, err = um.create_user(username, password, host);
916 if ok then
917 return true, "User created";
918 else
919 return nil, "Could not create user: "..err;
920 end
921 end
922
923 function def_env.user:delete(jid)
924 local username, host = jid_split(jid);
925 local ok, err = um.delete_user(username, host);
926 if ok then
927 return true, "User deleted";
928 else
929 return nil, "Could not delete user: "..err;
930 end
931 end
932
933 function def_env.user:passwd(jid, password)
934 local username, host = jid_split(jid);
935 local ok, err = um.set_password(username, password, host);
936 if ok then
937 return true, "User created";
938 else
939 return nil, "Could not change password for user: "..err;
940 end
941 end
942
943 def_env.xmpp = {};
944
945 local st = require "util.stanza";
946 function def_env.xmpp:ping(localhost, remotehost)
947 if hosts[localhost] then
948 core_post_stanza(hosts[localhost],
949 st.iq{ from=localhost, to=remotehost, type="get", id="ping" }
950 :tag("ping", {xmlns="urn:xmpp:ping"}));
951 return true, "Sent ping";
952 else
953 return nil, "No such host";
954 end
955 end
956
863 ------------- 957 -------------
864 958
865 function printbanner(session) 959 function printbanner(session)
866 local option = config.get("*", "core", "console_banner"); 960 local option = config.get("*", "core", "console_banner");
867 if option == nil or option == "full" or option == "graphic" then 961 if option == nil or option == "full" or option == "graphic" then