local iterators = require "util.iterators";
local keys, values = iterators.keys, iterators.values;
-local jid = require "util.jid";
-local jid_bare, jid_split = jid.bare, jid.split;
+local jid_bare, jid_split = import("util.jid", "bare", "prepped_split");
local set, array = require "util.set", require "util.array";
local cert_verify_identity = require "util.x509".verify_identity;
local envload = require "util.envload".envload;
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
end
end
+function console_listener.ondetach(conn)
+ sessions[conn] = nil;
+end
+
-- Console commands --
-- These are simple commands, not valid standalone in Lua
function commands.bye(session)
session.print("See you! :)");
+ session.closed = true;
session.disconnect();
end
commands.quit, commands.exit = commands.bye, commands.bye;
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
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
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()
+ local pposix = require("util.pposix");
+ 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)
-- I think there's going to be more confusion among operators if we
-- break from that.
local function print_errors(print, errors)
- for depth, t in ipairs(errors) do
+ for depth, t in pairs(errors) do
print(
(" %d: %s"):format(
depth-1,
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();
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_name then
+ return room_name, host;
+ end
+ 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);
+ if not room_name then
+ return room_name, host;
+ end
local room_obj = hosts[host].modules.muc.rooms[room_jid];
if not room_obj then
return nil, "No such room: "..room_jid;
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);
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 not um.user_exists(username, host) then
return nil, "No such user";
end
local ok, err = um.delete_user(username, host);
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 not um.user_exists(username, host) then
return nil, "No such user";
end
local ok, err = um.set_password(username, password, host);
return nil, "No such host";
end
local print = self.session.print;
- local count = 0;
+ local total, matches = 0, 0;
for user in um.users(host) do
if not pat or user:match(pat) then
print(user.."@"..host);
+ matches = matches + 1;
end
- count = count + 1;
+ total = total + 1;
end
- return true, count .. " users total";
+ return true, "Showing "..(pat and (matches.." of ") or "all " )..total.." users";
end
def_env.xmpp = {};
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._resolver:addnameserver(...)
+ return true
+end
+
+function def_env.dns:setnameserver(...)
+ dns._resolver: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
+
+def_env.http = {};
+
+function def_env.http:list()
+ local print = self.session.print;
+
+ for host in pairs(prosody.hosts) do
+ local http_apps = modulemanager.get_items("http-provider", host);
+ if #http_apps > 0 then
+ local http_host = module:context(host):get_option("http_host");
+ print("HTTP endpoints on "..host..(http_host and (" (using "..http_host.."):") or ":"));
+ for _, provider in ipairs(http_apps) do
+ local url = module:context(host):http_url(provider.name);
+ print("", url);
+ end
+ print("");
+ end
+ end
+
+ local default_host = module:get_option("http_default_host");
+ if not default_host then
+ print("HTTP requests to unknown hosts will return 404 Not Found");
+ else
+ print("HTTP requests to unknown hosts will be handled by "..default_host);
+ end
+ return true;
+end
+
-------------
function printbanner(session)