aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2015-05-19 16:33:47 +0200
committerKim Alvefur <zash@zash.se>2015-05-19 16:33:47 +0200
commit98d695f3a199cdf07d26f9c0ae7d23a56da157a1 (patch)
tree14a722959d1179338adec58efd9e5d7fcfa58ada
parent879862c536a5fba488307eb9e8a2f4f6523dbf09 (diff)
parent9ef666506252bd82ae729d0a69235f4c9ea818f2 (diff)
downloadprosody-98d695f3a199cdf07d26f9c0ae7d23a56da157a1.tar.gz
prosody-98d695f3a199cdf07d26f9c0ae7d23a56da157a1.zip
Merge 0.10->trunk
-rw-r--r--core/configmanager.lua84
-rw-r--r--core/hostmanager.lua15
-rw-r--r--core/loggingmanager.lua16
-rw-r--r--plugins/mod_auth_internal_hashed.lua21
-rw-r--r--plugins/mod_tls.lua5
-rwxr-xr-xprosodyctl2
-rw-r--r--util/interpolation.lua77
-rw-r--r--util/x509.lua3
8 files changed, 151 insertions, 72 deletions
diff --git a/core/configmanager.lua b/core/configmanager.lua
index 48f039ea..5ee131ad 100644
--- a/core/configmanager.lua
+++ b/core/configmanager.lua
@@ -28,7 +28,7 @@ _M.resolve_relative_path = resolve_relative_path; -- COMPAT
local parsers = {};
-local config_mt = { __index = function (t, k) return rawget(t, "*"); end};
+local config_mt = { __index = function (t, _) return rawget(t, "*"); end};
local config = setmetatable({ ["*"] = { } }, config_mt);
-- When host not found, use global
@@ -54,11 +54,11 @@ function _M.rawget(host, key, _oldkey)
end
end
-local function set(config, host, key, value)
+local function set(config_table, host, key, value)
if host and key then
- local hostconfig = rawget(config, host);
+ local hostconfig = rawget(config_table, host);
if not hostconfig then
- hostconfig = rawset(config, host, setmetatable({}, host_mt))[host];
+ hostconfig = rawset(config_table, host, setmetatable({}, host_mt))[host];
end
hostconfig[key] = value;
return true;
@@ -73,20 +73,20 @@ function _M.set(host, key, value, _oldvalue)
return set(config, host, key, value);
end
-function load(filename, format)
- format = format or filename:match("%w+$");
+function load(filename, config_format)
+ config_format = config_format or filename:match("%w+$");
- if parsers[format] and parsers[format].load then
+ if parsers[config_format] and parsers[config_format].load then
local f, err = io.open(filename);
if f then
local new_config = setmetatable({ ["*"] = { } }, config_mt);
- local ok, err = parsers[format].load(f:read("*a"), filename, new_config);
+ local ok, err = parsers[config_format].load(f:read("*a"), filename, new_config);
f:close();
if ok then
config = new_config;
fire_event("config-reloaded", {
filename = filename,
- format = format,
+ format = config_format,
config = config
});
end
@@ -95,65 +95,61 @@ function load(filename, format)
return f, "file", err;
end
- if not format then
+ if not config_format then
return nil, "file", "no parser specified";
else
- return nil, "file", "no parser for "..(format);
+ return nil, "file", "no parser for "..(config_format);
end
end
-function save(filename, format)
-end
-
-function addparser(format, parser)
- if format and parser then
- parsers[format] = parser;
+function addparser(config_format, parser)
+ if config_format and parser then
+ parsers[config_format] = parser;
end
end
-- _M needed to avoid name clash with local 'parsers'
function _M.parsers()
local p = {};
- for format in pairs(parsers) do
- table.insert(p, format);
+ for config_format in pairs(parsers) do
+ table.insert(p, config_format);
end
return p;
end
-- Built-in Lua parser
do
- local pcall, setmetatable = _G.pcall, _G.setmetatable;
- local rawget = _G.rawget;
+ local pcall = _G.pcall;
parsers.lua = {};
- function parsers.lua.load(data, config_file, config)
+ function parsers.lua.load(data, config_file, config_table)
local env;
-- The ' = true' are needed so as not to set off __newindex when we assign the functions below
env = setmetatable({
Host = true, host = true, VirtualHost = true,
Component = true, component = true,
Include = true, include = true, RunScript = true }, {
- __index = function (t, k)
+ __index = function (_, k)
return rawget(_G, k);
end,
- __newindex = function (t, k, v)
- set(config, env.__currenthost or "*", k, v);
+ __newindex = function (_, k, v)
+ set(config_table, env.__currenthost or "*", k, v);
end
});
rawset(env, "__currenthost", "*") -- Default is global
function env.VirtualHost(name)
name = nameprep(name);
- if rawget(config, name) and rawget(config[name], "component_module") then
+ if rawget(config_table, name) and rawget(config_table[name], "component_module") then
error(format("Host %q clashes with previously defined %s Component %q, for services use a sub-domain like conference.%s",
- name, config[name].component_module:gsub("^%a+$", { component = "external", muc = "MUC"}), name, name), 0);
+ name, config_table[name].component_module:gsub("^%a+$", { component = "external", muc = "MUC"}), name, name), 0);
end
rawset(env, "__currenthost", name);
-- Needs at least one setting to logically exist :)
- set(config, name or "*", "defined", true);
+ set(config_table, name or "*", "defined", true);
return function (config_options)
rawset(env, "__currenthost", "*"); -- Return to global scope
for option_name, option_value in pairs(config_options) do
- set(config, name or "*", option_name, option_value);
+ set(config_table, name or "*", option_name, option_value);
end
end;
end
@@ -161,24 +157,24 @@ do
function env.Component(name)
name = nameprep(name);
- if rawget(config, name) and rawget(config[name], "defined") and not rawget(config[name], "component_module") then
+ if rawget(config_table, name) and rawget(config_table[name], "defined") and not rawget(config_table[name], "component_module") then
error(format("Component %q clashes with previously defined Host %q, for services use a sub-domain like conference.%s",
name, name, name), 0);
end
- set(config, name, "component_module", "component");
+ set(config_table, name, "component_module", "component");
-- Don't load the global modules by default
- set(config, name, "load_global_modules", false);
+ set(config_table, name, "load_global_modules", false);
rawset(env, "__currenthost", name);
local function handle_config_options(config_options)
rawset(env, "__currenthost", "*"); -- Return to global scope
for option_name, option_value in pairs(config_options) do
- set(config, name or "*", option_name, option_value);
+ set(config_table, name or "*", option_name, option_value);
end
end
return function (module)
if type(module) == "string" then
- set(config, name, "component_module", module);
+ set(config_table, name, "component_module", module);
return handle_config_options;
end
return handle_config_options(module);
@@ -187,6 +183,7 @@ do
env.component = env.Component;
function env.Include(file)
+ -- Check whether this is a wildcard Include
if file:match("[*?]") then
local lfs = deps.softreq "lfs";
if not lfs then
@@ -206,16 +203,17 @@ do
env.Include(path..path_sep..f);
end
end
- else
- local file = resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), file);
- local f, err = io.open(file);
- if f then
- local ret, err = parsers.lua.load(f:read("*a"), file, config);
- if not ret then error(err:gsub("%[string.-%]", file), 0); end
- end
- if not f then error("Error loading included "..file..": "..err, 0); end
- return f, err;
+ return;
+ end
+ -- Not a wildcard, so resolve (potentially) relative path and run through config parser
+ file = resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), file);
+ local f, err = io.open(file);
+ if f then
+ local ret, err = parsers.lua.load(f:read("*a"), file, config_table);
+ if not ret then error(err:gsub("%[string.-%]", file), 0); end
end
+ if not f then error("Error loading included "..file..": "..err, 0); end
+ return f, err;
end
env.include = env.Include;
diff --git a/core/hostmanager.lua b/core/hostmanager.lua
index b13b1944..3d581418 100644
--- a/core/hostmanager.lua
+++ b/core/hostmanager.lua
@@ -26,9 +26,23 @@ local core_route_stanza = _G.prosody.core_route_stanza;
local pairs, select, rawget = pairs, select, rawget;
local tostring, type = tostring, type;
+local setmetatable = setmetatable;
module "hostmanager"
+local host_mt = { }
+function host_mt:__tostring()
+ if self.type == "component" then
+ local typ = configmanager.get(self.host, "component_module");
+ if typ == "component" then
+ return ("Component %q"):format(self.host);
+ end
+ return ("Component %q %q"):format(self.host, typ);
+ elseif self.type == "local" then
+ return ("VirtualHost %q"):format(self.host);
+ end
+end
+
local hosts_loaded_once;
local function load_enabled_hosts(config)
@@ -69,6 +83,7 @@ function activate(host, host_config)
send = host_send;
modules = {};
};
+ setmetatable(host_session, host_mt);
if not host_config.component_module then -- host
host_session.type = "local";
host_session.sessions = {};
diff --git a/core/loggingmanager.lua b/core/loggingmanager.lua
index f348dbdf..57ed8687 100644
--- a/core/loggingmanager.lua
+++ b/core/loggingmanager.lua
@@ -177,8 +177,8 @@ end
-- Column width for "source" (used by stdout and console)
local sourcewidth = 20;
-function log_sink_types.stdout(config)
- local timestamps = config.timestamps;
+function log_sink_types.stdout(sink_config)
+ local timestamps = sink_config.timestamps;
if timestamps == true then
timestamps = default_timestamp; -- Default format
@@ -207,13 +207,13 @@ do
logstyles["warn"] = getstyle("bold", "yellow");
logstyles["error"] = getstyle("bold", "red");
end
- function log_sink_types.console(config)
+ function log_sink_types.console(sink_config)
-- Really if we don't want pretty colours then just use plain stdout
if not do_pretty_printing then
- return log_sink_types.stdout(config);
+ return log_sink_types.stdout(sink_config);
end
- local timestamps = config.timestamps;
+ local timestamps = sink_config.timestamps;
if timestamps == true then
timestamps = default_timestamp; -- Default format
@@ -240,15 +240,15 @@ do
end
local empty_function = function () end;
-function log_sink_types.file(config)
- local log = config.filename;
+function log_sink_types.file(sink_config)
+ local log = sink_config.filename;
local logfile = io_open(log, "a+");
if not logfile then
return empty_function;
end
local write, flush = logfile.write, logfile.flush;
- local timestamps = config.timestamps;
+ local timestamps = sink_config.timestamps;
if timestamps == nil or timestamps == true then
timestamps = default_timestamp; -- Default format
diff --git a/plugins/mod_auth_internal_hashed.lua b/plugins/mod_auth_internal_hashed.lua
index 954392c9..78abe50d 100644
--- a/plugins/mod_auth_internal_hashed.lua
+++ b/plugins/mod_auth_internal_hashed.lua
@@ -13,31 +13,14 @@ local getAuthenticationDatabaseSHA1 = require "util.sasl.scram".getAuthenticatio
local usermanager = require "core.usermanager";
local generate_uuid = require "util.uuid".generate;
local new_sasl = require "util.sasl".new;
+local hex = require"util.hex";
+local to_hex, from_hex = hex.to, hex.from;
local log = module._log;
local host = module.host;
local accounts = module:open_store("accounts");
-local to_hex;
-do
- local function replace_byte_with_hex(byte)
- return ("%02x"):format(byte:byte());
- end
- function to_hex(binary_string)
- return binary_string:gsub(".", replace_byte_with_hex);
- end
-end
-
-local from_hex;
-do
- local function replace_hex_with_byte(hex)
- return string.char(tonumber(hex, 16));
- end
- function from_hex(hex_string)
- return hex_string:gsub("..", replace_hex_with_byte);
- end
-end
-- Default; can be set per-user
diff --git a/plugins/mod_tls.lua b/plugins/mod_tls.lua
index f9d2cee9..d1138e1c 100644
--- a/plugins/mod_tls.lua
+++ b/plugins/mod_tls.lua
@@ -21,6 +21,7 @@ end
local xmlns_starttls = 'urn:ietf:params:xml:ns:xmpp-tls';
local starttls_attr = { xmlns = xmlns_starttls };
+local starttls_initiate= st.stanza("starttls", starttls_attr);
local starttls_proceed = st.stanza("proceed", starttls_attr);
local starttls_failure = st.stanza("failure", starttls_attr);
local c2s_feature = st.stanza("starttls", starttls_attr);
@@ -60,7 +61,7 @@ do
end
local function can_do_tls(session)
- if not session.conn.starttls then
+ if session.ssl_ctx == false or not session.conn.starttls then
return false;
elseif session.ssl_ctx then
return true;
@@ -116,7 +117,7 @@ module:hook_stanza("http://etherx.jabber.org/streams", "features", function (ses
module:log("debug", "Received features element");
if can_do_tls(session) and stanza:get_child("starttls", xmlns_starttls) then
module:log("debug", "%s is offering TLS, taking up the offer...", session.to_host);
- session.sends2s("<starttls xmlns='"..xmlns_starttls.."'/>");
+ session.sends2s(starttls_initiate);
return true;
end
end, 500);
diff --git a/prosodyctl b/prosodyctl
index ef436106..6c4b148a 100755
--- a/prosodyctl
+++ b/prosodyctl
@@ -578,6 +578,8 @@ function commands.about(arg)
print("");
print("# Lua module versions");
local module_versions, longest_name = {}, 8;
+ local luaevent =dependencies.softreq"luaevent";
+ local ssl = dependencies.softreq"ssl";
for name, module in pairs(package.loaded) do
if type(module) == "table" and rawget(module, "_VERSION")
and name ~= "_G" and not name:match("%.") then
diff --git a/util/interpolation.lua b/util/interpolation.lua
new file mode 100644
index 00000000..b78bdfd1
--- /dev/null
+++ b/util/interpolation.lua
@@ -0,0 +1,77 @@
+-- Simple template language
+--
+-- The new() function takes a pattern and an escape function and returns
+-- a render() function. Both are required.
+--
+-- The function render() takes a string template and a table of values.
+-- Sequences like {name} in the template string are substituted
+-- with values from the table, optionally depending on a modifier
+-- symbol.
+--
+-- Variants are:
+-- {name} is substituted for values["name"] and is escaped using the
+-- second argument to new_render(). To disable the escaping, use {name!}.
+-- {name.item} can be used to access table items.
+-- To renter lists of items: {name# item number {idx} is {item} }
+-- Or key-value pairs: {name% t[ {idx} ] = {item} }
+-- To show a defaults for missing values {name? sub-template } can be used,
+-- which renders a sub-template if values["name"] is false-ish.
+-- {name& sub-template } does the opposite, the sub-template is rendered
+-- if the selected value is anything but false or nil.
+
+local type, tostring = type, tostring;
+local pairs, ipairs = pairs, ipairs;
+local s_sub, s_gsub, s_match = string.sub, string.gsub, string.match;
+local t_concat = table.concat;
+
+local function new_render(pat, escape)
+ -- assert(type(pat) == "string", "bad argument #1 to 'new_render' (string expected)");
+ -- assert(type(escape) == "function", "bad argument #2 to 'new_render' (function expected)");
+ local function render(template, values)
+ -- assert(type(template) == "string", "bad argument #1 to 'render' (string expected)");
+ -- assert(type(values) == "table", "bad argument #2 to 'render' (table expected)");
+ return (s_gsub(template, pat, function (block)
+ block = s_sub(block, 2, -2);
+ local name, opt, e = s_match(block, "^([%a_][%w_.]*)(%p?)()");
+ if not name then return end
+ local value = values[name];
+ if not value and name:find(".", 2, true) then
+ value = values;
+ for word in name:gmatch"[^.]+" do
+ value = value[word];
+ if not value then break; end
+ end
+ end
+ if opt == '#' or opt == '%' then
+ if type(value) ~= "table" then return ""; end
+ local iter = opt == '#' and ipairs or pairs;
+ local out, i, subtpl = {}, 1, s_sub(block, e);
+ local subvalues = setmetatable({}, { __index = values });
+ for idx, item in iter(value) do
+ subvalues.idx = idx;
+ subvalues.item = item;
+ out[i], i = render(subtpl, subvalues), i+1;
+ end
+ return t_concat(out);
+ elseif opt == '&' then
+ if not value then return ""; end
+ return render(s_sub(block, e), values);
+ elseif opt == '?' and not value then
+ return render(s_sub(block, e), values);
+ elseif value ~= nil then
+ if type(value) ~= "string" then
+ value = tostring(value);
+ end
+ if opt ~= '!' then
+ return escape(value);
+ end
+ return value;
+ end
+ end));
+ end
+ return render;
+end
+
+return {
+ new = new_render;
+};
diff --git a/util/x509.lua b/util/x509.lua
index 5e1b49e5..bf8d3906 100644
--- a/util/x509.lua
+++ b/util/x509.lua
@@ -148,6 +148,9 @@ local function compare_srvname(host, service, asserted_names)
end
function verify_identity(host, service, cert)
+ if cert.setencode then
+ cert:setencode("utf8");
+ end
local ext = cert:extensions()
if ext[oid_subjectaltname] then
local sans = ext[oid_subjectaltname];