mod_bosh: rename variable for clarity
[prosody.git] / plugins / mod_admin_telnet.lua
index a56f299277e42ccfe630c1894938e4b67cc87e6c..3b8fedbdcb943da7e7ef94e449cee106ee141f02 100644 (file)
@@ -149,6 +149,7 @@ function console_listener.onincoming(conn, data)
        end
 
        for line in data:gmatch("[^\n]*[\n\004]") do
+               if session.closed then return end
                console:process_line(session, line);
                session.send(string.char(0));
        end
@@ -168,6 +169,7 @@ end
 
 function commands.bye(session)
        session.print("See you! :)");
+       session.closed = true;
        session.disconnect();
 end
 commands.quit, commands.exit = commands.bye, commands.bye;
@@ -204,6 +206,8 @@ function commands.help(session, data)
                print [[host - Commands to activate, deactivate and list virtual hosts]]
                print [[user - Commands to create and delete users, and change their passwords]]
                print [[server - Uptime, version, shutting down, etc.]]
+               print [[port - Commands to manage ports the server is listening on]]
+               print [[dns - Commands to manage and inspect the internal DNS resolver]]
                print [[config - Reloading the configuration, etc.]]
                print [[console - Help regarding the console itself]]
        elseif section == "c2s" then
@@ -232,7 +236,17 @@ function commands.help(session, data)
        elseif section == "server" then
                print [[server:version() - Show the server's version number]]
                print [[server:uptime() - Show how long the server has been running]]
+               print [[server:memory() - Show details about the server's memory usage]]
                print [[server:shutdown(reason) - Shut down the server, with an optional reason to be broadcast to all connections]]
+       elseif section == "port" then
+               print [[port:list() - Lists all network ports prosody currently listens on]]
+               print [[port:close(port, interface) - Close a port]]
+       elseif section == "dns" then
+               print [[dns:lookup(name, type, class) - Do a DNS lookup]]
+               print [[dns:addnameserver(nameserver) - Add a nameserver to the list]]
+               print [[dns:setnameserver(nameserver) - Replace the list of name servers with the supplied one]]
+               print [[dns:purge() - Clear the DNS cache]]
+               print [[dns:cache() - Show cached records]]
        elseif section == "config" then
                print [[config:reload() - Reload the server configuration. Modules may need to be reloaded for changes to take effect.]]
        elseif section == "console" then
@@ -287,6 +301,26 @@ function def_env.server:shutdown(reason)
        return true, "Shutdown initiated";
 end
 
+local function human(kb)
+       local unit = "K";
+       if kb > 1024 then
+               kb, unit = kb/1024, "M";
+       end
+       return ("%0.2f%sB"):format(kb, unit);
+end
+
+function def_env.server:memory()
+       if not pposix.meminfo then
+               return true, "Lua is using "..collectgarbage("count");
+       end
+       local mem, lua_mem = pposix.meminfo(), collectgarbage("count");
+       local print = self.session.print;
+       print("Process: "..human((mem.allocated+mem.allocated_mmap)/1024));
+       print("   Used: "..human(mem.used/1024).." ("..human(lua_mem).." by Lua)");
+       print("   Free: "..human(mem.unused/1024).." ("..human(mem.returnable/1024).." returnable)");
+       return true, "OK";
+end
+
 def_env.module = {};
 
 local function get_hosts_set(hosts, module)
@@ -450,6 +484,25 @@ end
 function def_env.hosts:add(name)
 end
 
+local function session_flags(session, line)
+       line = line or {};
+       if session.cert_identity_status == "valid" then
+               line[#line+1] = "(secure)";
+       elseif session.secure then
+               line[#line+1] = "(encrypted)";
+       end
+       if session.compressed then
+               line[#line+1] = "(compressed)";
+       end
+       if session.smacks then
+               line[#line+1] = "(sm)";
+       end
+       if (session.ip or session.conn and session.conn:ip()):match(":") then
+               line[#line+1] = "(IPv6)";
+       end
+       return table.concat(line, " ");
+end
+
 def_env.c2s = {};
 
 local function show_c2s(callback)
@@ -485,14 +538,9 @@ function def_env.c2s:show(match_jid)
                        count = count + 1;
                        local status, priority = "unavailable", tostring(session.priority or "-");
                        if session.presence then
-                               status = session.presence:child_with_name("show");
-                               if status then
-                                       status = status:get_text() or "[invalid!]";
-                               else
-                                       status = "available";
-                               end
+                               status = session.presence:get_child_text("show") or "available";
                        end
-                       print("   "..jid.." - "..status.."("..priority..")");
+                       print(session_flags(session, { "   "..jid.." - "..status.."("..priority..")" }));
                end             
        end);
        return true, "Total: "..count.." clients";
@@ -531,23 +579,6 @@ function def_env.c2s:close(match_jid)
        return true, "Total: "..count.." sessions closed";
 end
 
-local function session_flags(session, line)
-       if session.cert_identity_status == "valid" then
-               line[#line+1] = "(secure)";
-       elseif session.secure then
-               line[#line+1] = "(encrypted)";
-       end
-       if session.compressed then
-               line[#line+1] = "(compressed)";
-       end
-       if session.smacks then
-               line[#line+1] = "(sm)";
-       end
-       if session.conn and session.conn:ip():match(":") then
-               line[#line+1] = "(IPv6)";
-       end
-       return table.concat(line, " ");
-end
 
 def_env.s2s = {};
 function def_env.s2s:show(match_jid)
@@ -669,9 +700,9 @@ function def_env.s2s:showcert(domain)
                                error("This version of LuaSec does not support certificate viewing");
                        end
                else
-                       local certs = conn:getpeerchain();
-                       local cert = certs[1];
+                       local cert = conn:getpeercertificate();
                        if cert then
+                               local certs = conn:getpeerchain();
                                local digest = cert:digest("sha1");
                                if not cert_set[digest] then
                                        local chain_valid, chain_errors = conn:getpeerverification();
@@ -897,13 +928,25 @@ local console_room_mt = {
        end;
 };
 
-function def_env.muc:room(room_jid)
-       local room_name, host = jid_split(room_jid);
+local function check_muc(jid)
+       local room_name, host = jid_split(jid);
        if not hosts[host] then
                return nil, "No such host: "..host;
        elseif not hosts[host].modules.muc then
                return nil, "Host '"..host.."' is not a MUC service";
        end
+       return room_name, host;
+end
+
+function def_env.muc:create(room_jid)
+       local room, host = check_muc(room_jid);
+       if not room then return nil, host end
+       if hosts[host].modules.muc.rooms[room_jid] then return nil, "Room exists already" end
+       return hosts[host].modules.muc.create_room(room_jid);
+end
+
+function def_env.muc:room(room_jid)
+       local room_name, host = check_muc(room_jid);
        local room_obj = hosts[host].modules.muc.rooms[room_jid];
        if not room_obj then
                return nil, "No such room: "..room_jid;
@@ -916,7 +959,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
+       if not hosts[host] then
+               return nil, "No such host: "..host;
+       elseif um.user_exists(username, host) then
                return nil, "User exists";
        end
        local ok, err = um.create_user(username, password, host);
@@ -929,7 +974,9 @@ end
 
 function def_env.user:delete(jid)
        local username, host = jid_split(jid);
-       if not um.user_exists(username, host) then
+       if not hosts[host] then
+               return nil, "No such host: "..host;
+       elseif um.user_exists(username, host) then
                return nil, "No such user";
        end
        local ok, err = um.delete_user(username, host);
@@ -942,7 +989,9 @@ end
 
 function def_env.user:password(jid, password)
        local username, host = jid_split(jid);
-       if not um.user_exists(username, host) then
+       if not hosts[host] then
+               return nil, "No such host: "..host;
+       elseif um.user_exists(username, host) then
                return nil, "No such user";
        end
        local ok, err = um.set_password(username, password, host);
@@ -985,6 +1034,40 @@ function def_env.xmpp:ping(localhost, remotehost)
        end
 end
 
+def_env.dns = {};
+local adns = require"net.adns";
+local dns = require"net.dns";
+
+function def_env.dns:lookup(name, typ, class)
+       local ret = "Query sent";
+       local print = self.session.print;
+       local function handler(...)
+               ret = "Got response";
+               print(...);
+       end
+       adns.lookup(handler, name, typ, class);
+       return true, ret;
+end
+
+function def_env.dns:addnameserver(...)
+       dns.addnameserver(...)
+       return true
+end
+
+function def_env.dns:setnameserver(...)
+       dns.setnameserver(...)
+       return true
+end
+
+function def_env.dns:purge()
+       dns.purge()
+       return true
+end
+
+function def_env.dns:cache()
+       return true, "Cache:\n"..tostring(dns.cache())
+end
+
 -------------
 
 function printbanner(session)