aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/debug.lua58
-rw-r--r--util/prosodyctl.lua21
-rw-r--r--util/template.lua16
-rw-r--r--util/x509.lua109
-rw-r--r--util/xmppstream.lua33
5 files changed, 205 insertions, 32 deletions
diff --git a/util/debug.lua b/util/debug.lua
index aeb710d7..7caf21ce 100644
--- a/util/debug.lua
+++ b/util/debug.lua
@@ -7,7 +7,21 @@ local censored_names = {
pass = true;
pwd = true;
};
+local optimal_line_length = 65;
+local termcolours = require "util.termcolours";
+local getstring = termcolours.getstring;
+local styles;
+do
+ _ = termcolours.getstyle;
+ styles = {
+ boundary_padding = _("bright", "white");
+ filename = _("bright", "blue");
+ level_num = _("green");
+ funcname = _("yellow");
+ location = _("yellow");
+ };
+end
module("debugx", package.seeall);
function get_locals_table(level)
@@ -90,30 +104,51 @@ function get_traceback_table(thread, start_level)
return levels;
end
-function traceback(thread, message, level)
+function traceback(...)
+ local ok, ret = pcall(_traceback, ...);
+ if not ok then
+ return "Error in error handling: "..ret;
+ end
+ return ret;
+end
+
+local function build_source_boundary_marker(last_source_desc)
+ local padding = string.rep("-", math.floor(((optimal_line_length - 6) - #last_source_desc)/2));
+ return getstring(styles.boundary_padding, "v"..padding).." "..getstring(styles.filename, last_source_desc).." "..getstring(styles.boundary_padding, padding..(#last_source_desc%2==0 and "-v" or "v "));
+end
+
+function _traceback(thread, message, level)
+
if type(thread) ~= "thread" then
thread, message, level = coroutine.running(), thread, message;
end
if level and type(message) ~= "string" then
return nil, "invalid message";
elseif not level then
- level = message or 2;
+ if type(message) == "number" then
+ level, message = message, nil;
+ else
+ level = 2;
+ end
end
message = message and (message.."\n") or "";
local levels = get_traceback_table(thread, level+2);
+ local last_source_desc;
+
local lines = {};
for nlevel, level in ipairs(levels) do
local info = level.info;
local line = "...";
local func_type = info.namewhat.." ";
+ local source_desc = (info.short_src == "[C]" and "C code") or info.short_src or "Unknown";
if func_type == " " then func_type = ""; end;
if info.short_src == "[C]" then
- line = "[ C ] "..func_type.."C function "..(info.name and ("%q"):format(info.name) or "(unknown name)")
+ line = "[ C ] "..func_type.."C function "..getstring(styles.location, (info.name and ("%q"):format(info.name) or "(unknown name)"));
elseif info.what == "main" then
- line = "[Lua] "..info.short_src.." line "..info.currentline;
+ line = "[Lua] "..getstring(styles.location, info.short_src.." line "..info.currentline);
else
local name = info.name or " ";
if name ~= " " then
@@ -122,20 +157,27 @@ function traceback(thread, message, level)
if func_type == "global " or func_type == "local " then
func_type = func_type.."function ";
end
- line = "[Lua] "..info.short_src.." line "..info.currentline.." in "..func_type..name.." defined on line "..info.linedefined;
+ line = "[Lua] "..getstring(styles.location, info.short_src.." line "..info.currentline).." in "..func_type..getstring(styles.funcname, name).." (defined on line "..info.linedefined..")";
+ end
+ if source_desc ~= last_source_desc then -- Venturing into a new source, add marker for previous
+ last_source_desc = source_desc;
+ table.insert(lines, "\t "..build_source_boundary_marker(last_source_desc));
end
nlevel = nlevel-1;
- table.insert(lines, "\t"..(nlevel==0 and ">" or " ").."("..nlevel..") "..line);
+ table.insert(lines, "\t"..(nlevel==0 and ">" or " ")..getstring(styles.level_num, "("..nlevel..") ")..line);
local npadding = (" "):rep(#tostring(nlevel));
- local locals_str = string_from_var_table(level.locals, 65, "\t "..npadding);
+ local locals_str = string_from_var_table(level.locals, optimal_line_length, "\t "..npadding);
if locals_str then
table.insert(lines, "\t "..npadding.."Locals: "..locals_str);
end
- local upvalues_str = string_from_var_table(level.upvalues, 65, "\t "..npadding);
+ local upvalues_str = string_from_var_table(level.upvalues, optimal_line_length, "\t "..npadding);
if upvalues_str then
table.insert(lines, "\t "..npadding.."Upvals: "..upvalues_str);
end
end
+
+-- table.insert(lines, "\t "..build_source_boundary_marker(last_source_desc));
+
return message.."stack traceback:\n"..table.concat(lines, "\n");
end
diff --git a/util/prosodyctl.lua b/util/prosodyctl.lua
index d0045abc..439de551 100644
--- a/util/prosodyctl.lua
+++ b/util/prosodyctl.lua
@@ -16,6 +16,7 @@ local signal = require "util.signal";
local set = require "util.set";
local lfs = require "lfs";
local pcall = pcall;
+local type = type;
local nodeprep, nameprep = stringprep.nodeprep, stringprep.nameprep;
@@ -63,6 +64,13 @@ function getchar(n)
end
end
+function getline()
+ local ok, line = pcall(io.read, "*l");
+ if ok then
+ return line;
+ end
+end
+
function getpass()
local stty_ret = os.execute("stty -echo 2>/dev/null");
if stty_ret ~= 0 then
@@ -112,6 +120,13 @@ function read_password()
return password;
end
+function show_prompt(prompt)
+ io.write(prompt, " ");
+ local line = getline();
+ line = line and line:gsub("\n$","");
+ return (line and #line > 0) and line or nil;
+end
+
-- Server control
function adduser(params)
local user, host, password = nodeprep(params.user), nameprep(params.host), params.password;
@@ -121,7 +136,11 @@ function adduser(params)
return false, "invalid-hostname";
end
- local provider = prosody.hosts[host].users;
+ local host_session = prosody.hosts[host];
+ if not host_session then
+ return false, "no-such-host";
+ end
+ local provider = host_session.users;
if not(provider) or provider.name == "null" then
usermanager.initialize_host(host);
end
diff --git a/util/template.lua b/util/template.lua
index ebd8be14..5e9b479e 100644
--- a/util/template.lua
+++ b/util/template.lua
@@ -7,6 +7,7 @@ local ipairs = ipairs;
local error = error;
local loadstring = loadstring;
local debug = debug;
+local t_remove = table.remove;
module("template")
@@ -42,7 +43,6 @@ local parse_xml = (function()
stanza:tag(name, attr);
end
function handler:CharacterData(data)
- data = data:gsub("^%s*", ""):gsub("%s*$", "");
stanza:text(data);
end
function handler:EndElement(tagname)
@@ -60,6 +60,19 @@ local parse_xml = (function()
end;
end)();
+local function trim_xml(stanza)
+ for i=#stanza,1,-1 do
+ local child = stanza[i];
+ if child.name then
+ trim_xml(child);
+ else
+ child = child:gsub("^%s*", ""):gsub("%s*$", "");
+ stanza[i] = child;
+ if child == "" then t_remove(stanza, i); end
+ end
+ end
+end
+
local function create_string_string(str)
str = ("%q"):format(str);
str = str:gsub("{([^}]*)}", function(s)
@@ -118,6 +131,7 @@ local template_mt = { __tostring = function(t) return t.name end };
local function create_template(templates, text)
local stanza, err = parse_xml(text);
if not stanza then error(err); end
+ trim_xml(stanza);
local info = debug.getinfo(3, "Sl");
info = info and ("template(%s:%d)"):format(info.short_src:match("[^\\/]*$"), info.currentline) or "template(unknown)";
diff --git a/util/x509.lua b/util/x509.lua
index d3c55bb4..f106e6fa 100644
--- a/util/x509.lua
+++ b/util/x509.lua
@@ -21,6 +21,10 @@
local nameprep = require "util.encodings".stringprep.nameprep;
local idna_to_ascii = require "util.encodings".idna.to_ascii;
local log = require "util.logger".init("x509");
+local pairs, ipairs = pairs, ipairs;
+local s_format = string.format;
+local t_insert = table.insert;
+local t_concat = table.concat;
module "x509"
@@ -208,4 +212,109 @@ function verify_identity(host, service, cert)
return false
end
+-- TODO Rename? Split out subroutines?
+-- Also, this is probably openssl specific, what TODO about that?
+function genx509san(hosts, config, certhosts, raw) -- recive config through that or some better way?
+ local function utf8string(s)
+ -- This is how we tell openssl not to encode UTF-8 strings as Latin1
+ return s_format("FORMAT:UTF8,UTF8:%s", s);
+ end
+
+ local function ia5string(s)
+ return s_format("IA5STRING:%s", s);
+ end
+
+ local function dnsname(t, host)
+ t_insert(t.DNS, idna_to_ascii(host));
+ end
+
+ local function srvname(t, host, service)
+ t_insert(t.otherName, s_format("%s;%s", oid_dnssrv, ia5string("_" .. service .."." .. idna_to_ascii(host))));
+ end
+
+ local function xmppAddr(t, host)
+ t_insert(t.otherName, s_format("%s;%s", oid_xmppaddr, utf8string(host)));
+ end
+
+ -----------------------------
+
+ local san = {
+ DNS = {};
+ otherName = {};
+ };
+
+ local sslsanconf = { };
+
+ for i = 1,#certhosts do
+ local certhost = certhosts[i];
+ for name, host in pairs(hosts) do
+ if name == certhost or name:sub(-1-#certhost) == "."..certhost then
+ dnsname(san, name);
+ --print(name .. "#component_module: " .. (config.get(name, "core", "component_module") or "nil"));
+ if config.get(name, "core", "component_module") == nil then
+ srvname(san, name, "xmpp-client");
+ end
+ --print(name .. "#anonymous_login: " .. tostring(config.get(name, "core", "anonymous_login")));
+ if not (config.get(name, "core", "anonymous_login") or
+ config.get(name, "core", "authentication") == "anonymous") then
+ srvname(san, name, "xmpp-server");
+ end
+ xmppAddr(san, name);
+ end
+ end
+ end
+
+ for t, n in pairs(san) do
+ for i = 1,#n do
+ t_insert(sslsanconf, s_format("%s.%d = %s", t, i -1, n[i]));
+ end
+ end
+
+ return raw and sslsanconf or t_concat(sslsanconf, "\n");
+end
+
+function baseconf()
+ return {
+ req = {
+ distinguished_name = "distinguished_name",
+ req_extensions = "v3_extensions",
+ x509_extensions = "v3_extensions",
+ prompt = "no",
+ },
+ distinguished_name = {
+ commonName = "example.com",
+ countryName = "GB",
+ localityName = "The Internet",
+ organizationName = "Your Organisation",
+ organizationalUnitName = "XMPP Department",
+ emailAddress = "xmpp@example.com",
+ },
+ v3_extensions = {
+ basicConstraints = "CA:FALSE",
+ keyUsage = "digitalSignature,keyEncipherment",
+ extendedKeyUsage = "serverAuth,clientAuth",
+ subjectAltName = "@subject_alternative_name",
+ },
+ subject_alternative_name = { },
+ }
+end
+
+function serialize_conf(conf)
+ local s = "";
+ for k, t in pairs(conf) do
+ s = s .. ("[%s]\n"):format(k);
+ if t[1] then
+ for i, v in ipairs(t) do
+ s = s .. ("%s\n"):format(v);
+ end
+ else
+ for k, v in pairs(t) do
+ s = s .. ("%s = %s\n"):format(k, v);
+ end
+ end
+ s = s .. "\n";
+ end
+ return s;
+end
+
return _M;
diff --git a/util/xmppstream.lua b/util/xmppstream.lua
index 0f80742d..f1793b4f 100644
--- a/util/xmppstream.lua
+++ b/util/xmppstream.lua
@@ -25,8 +25,11 @@ module "xmppstream"
local new_parser = lxp.new;
-local ns_prefixes = {
- ["http://www.w3.org/XML/1998/namespace"] = "xml";
+local xml_namespace = {
+ ["http://www.w3.org/XML/1998/namespace\1lang"] = "xml:lang";
+ ["http://www.w3.org/XML/1998/namespace\1space"] = "xml:space";
+ ["http://www.w3.org/XML/1998/namespace\1base"] = "xml:base";
+ ["http://www.w3.org/XML/1998/namespace\1id"] = "xml:id";
};
local xmlns_streams = "http://etherx.jabber.org/streams";
@@ -73,17 +76,13 @@ function new_sax_handlers(session, stream_callbacks)
non_streamns_depth = non_streamns_depth + 1;
end
- -- FIXME !!!!!
for i=1,#attr do
local k = attr[i];
attr[i] = nil;
- local ns, nm = k:match(ns_pattern);
- if nm ~= "" then
- ns = ns_prefixes[ns];
- if ns then
- attr[ns..":"..nm] = attr[k];
- attr[k] = nil;
- end
+ local xmlk = xml_namespace[k];
+ if xmlk then
+ attr[xmlk] = attr[k];
+ attr[k] = nil;
end
end
@@ -140,19 +139,9 @@ function new_sax_handlers(session, stream_callbacks)
stanza = t_remove(stack);
end
else
- if tagname == stream_tag then
- if cb_streamclosed then
- cb_streamclosed(session);
- end
- else
- local curr_ns,name = tagname:match(ns_pattern);
- if name == "" then
- curr_ns, name = "", curr_ns;
- end
- cb_error(session, "parse-error", "unexpected-element-close", name);
+ if cb_streamclosed then
+ cb_streamclosed(session);
end
- stanza, chardata = nil, {};
- stack = {};
end
end