X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;f=plugins%2Fmod_admin_telnet.lua;h=0af571eb0aef00300b245c1cd64b6b9dc3ce185d;hb=d631eea82c5144b9c2142b32affdb0ba4f878a43;hp=52e9823e243707e2a305ae9dd7d9882972284698;hpb=4cd2eb0948fe71f15936819c5f109f033f71aa56;p=prosody.git diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua index 52e9823e..0af571eb 100644 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@ -8,18 +8,19 @@ module:set_global(); +local hostmanager = require "core.hostmanager"; +local modulemanager = require "core.modulemanager"; +local s2smanager = require "core.s2smanager"; +local portmanager = require "core.portmanager"; + local _G = _G; local prosody = _G.prosody; local hosts = prosody.hosts; +local incoming_s2s = prosody.incoming_s2s; local console_listener = { default_port = 5582; default_mode = "*a"; interface = "127.0.0.1" }; -local hostmanager = require "core.hostmanager"; -local modulemanager = require "core.modulemanager"; -local s2smanager = require "core.s2smanager"; -local portmanager = require "core.portmanager"; - local iterators = require "util.iterators"; local keys, values = iterators.keys, iterators.values; local jid = require "util.jid"; @@ -71,6 +72,64 @@ function console:new_session(conn) return session; end +function console:process_line(session, line) + local useglobalenv; + + if line:match("^>") then + line = line:gsub("^>", ""); + useglobalenv = true; + elseif line == "\004" then + commands["bye"](session, line); + return; + else + local command = line:match("^%w+") or line:match("%p"); + if commands[command] then + commands[command](session, line); + return; + end + end + + session.env._ = line; + + local chunkname = "=console"; + local env = (useglobalenv and redirect_output(_G, session)) or session.env or nil + local chunk, err = envload("return "..line, chunkname, env); + if not chunk then + chunk, err = envload(line, chunkname, env); + if not chunk then + err = err:gsub("^%[string .-%]:%d+: ", ""); + err = err:gsub("^:%d+: ", ""); + err = err:gsub("''", "the end of the line"); + session.print("Sorry, I couldn't understand that... "..err); + return; + end + end + + local ranok, taskok, message = pcall(chunk); + + if not (ranok or message or useglobalenv) and commands[line:lower()] then + commands[line:lower()](session, line); + return; + end + + if not ranok then + session.print("Fatal error while running command, it did not complete"); + session.print("Error: "..taskok); + return; + end + + if not message then + session.print("Result: "..tostring(taskok)); + return; + elseif (not taskok) and message then + session.print("Command completed with a problem"); + session.print("Message: "..tostring(message)); + return; + end + + session.print("OK: "..tostring(message)); +end + local sessions = {}; function console_listener.onconnect(conn) @@ -90,65 +149,7 @@ function console_listener.onincoming(conn, data) end for line in data:gmatch("[^\n]*[\n\004]") do - -- Handle data (loop allows us to break to add \0 after response) - repeat - local useglobalenv; - - if line:match("^>") then - line = line:gsub("^>", ""); - useglobalenv = true; - elseif line == "\004" then - commands["bye"](session, line); - break; - else - local command = line:match("^%w+") or line:match("%p"); - if commands[command] then - commands[command](session, line); - break; - end - end - - session.env._ = line; - - local chunkname = "=console"; - local env = (useglobalenv and redirect_output(_G, session)) or session.env or nil - local chunk, err = envload("return "..line, chunkname, env); - if not chunk then - chunk, err = envload(line, chunkname, env); - if not chunk then - err = err:gsub("^%[string .-%]:%d+: ", ""); - err = err:gsub("^:%d+: ", ""); - err = err:gsub("''", "the end of the line"); - session.print("Sorry, I couldn't understand that... "..err); - break; - end - end - - local ranok, taskok, message = pcall(chunk); - - if not (ranok or message or useglobalenv) and commands[line:lower()] then - commands[line:lower()](session, line); - break; - end - - if not ranok then - session.print("Fatal error while running command, it did not complete"); - session.print("Error: "..taskok); - break; - end - - if not message then - session.print("Result: "..tostring(taskok)); - break; - elseif (not taskok) and message then - session.print("Command completed with a problem"); - session.print("Message: "..tostring(message)); - break; - end - - session.print("OK: "..tostring(message)); - until true - + console:process_line(session, line); session.send(string.char(0)); end session.partial_data = data:match("[^\n]+$"); @@ -226,7 +227,8 @@ function commands.help(session, data) elseif section == "user" then print [[user:create(jid, password) - Create the specified user account]] print [[user:password(jid, password) - Set the password for the specified user account]] - print [[user:delete(jid, password) - Permanently remove the specified user account]] + print [[user:delete(jid) - Permanently remove the specified user account]] + print [[user:list(hostname, pattern) - List users on the specified host, optionally filtering with a pattern]] elseif section == "server" then print [[server:version() - Show the server's version number]] print [[server:uptime() - Show how long the server has been running]] @@ -519,7 +521,7 @@ function def_env.c2s:show_secure(match_jid) end function def_env.c2s:close(match_jid) - local print, count = self.session.print, 0; + local count = 0; show_c2s(function (jid, session) if jid == match_jid or jid_bare(jid) == match_jid then count = count + 1; @@ -875,7 +877,7 @@ function def_env.port:close(close_port, close_interface) self.session.print("Closing ["..interface.."]:"..close_port.."..."); local ok, err = portmanager.close(interface, close_port) if not ok then - self.session.print("Failed to close "..interface.." "..port..": "..err); + self.session.print("Failed to close "..interface.." "..close_port..": "..err); else n_closed = n_closed + 1; end @@ -914,6 +916,9 @@ local um = require"core.usermanager"; def_env.user = {}; function def_env.user:create(jid, password) local username, host = jid_split(jid); + if um.user_exists(username, host) then + return nil, "User exists"; + end local ok, err = um.create_user(username, password, host); if ok then return true, "User created"; @@ -924,6 +929,9 @@ end function def_env.user:delete(jid) local username, host = jid_split(jid); + if not um.user_exists(username, host) then + return nil, "No such user"; + end local ok, err = um.delete_user(username, host); if ok then return true, "User deleted"; @@ -932,16 +940,36 @@ function def_env.user:delete(jid) end end -function def_env.user:passwd(jid, password) +function def_env.user:password(jid, password) local username, host = jid_split(jid); + if not um.user_exists(username, host) then + return nil, "No such user"; + end local ok, err = um.set_password(username, password, host); if ok then - return true, "User created"; + return true, "User password changed"; else return nil, "Could not change password for user: "..err; end end +function def_env.user:list(host, pat) + if not host then + return nil, "No host given"; + elseif not hosts[host] then + return nil, "No such host"; + end + local print = self.session.print; + local count = 0; + for user in um.users(host) do + if not pat or user:match(pat) then + print(user.."@"..host); + end + count = count + 1; + end + return true, count .. " users total"; +end + def_env.xmpp = {}; local st = require "util.stanza"; @@ -985,7 +1013,7 @@ function printbanner(session) end end -module:add_item("net-provider", { +module:provides("net", { name = "console"; listener = console_listener; default_port = 5582;