aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/certmanager.lua83
-rw-r--r--net/http/server.lua25
-rw-r--r--plugins/mod_admin_telnet.lua6
-rw-r--r--plugins/mod_c2s.lua14
-rw-r--r--plugins/mod_component.lua4
-rw-r--r--plugins/mod_compression.lua15
-rw-r--r--plugins/mod_http.lua8
-rw-r--r--plugins/mod_posix.lua8
-rw-r--r--plugins/mod_s2s/mod_s2s.lua16
-rw-r--r--plugins/mod_storage_sql2.lua2
-rwxr-xr-xprosody10
-rwxr-xr-xprosodyctl6
-rw-r--r--util/dependencies.lua8
-rw-r--r--util/prosodyctl.lua4
-rw-r--r--util/xmppstream.lua19
15 files changed, 152 insertions, 76 deletions
diff --git a/core/certmanager.lua b/core/certmanager.lua
index 9dfb8f3a..74da771e 100644
--- a/core/certmanager.lua
+++ b/core/certmanager.lua
@@ -15,6 +15,8 @@ local tostring = tostring;
local pairs = pairs;
local type = type;
local io_open = io.open;
+local t_concat = table.concat;
+local t_insert = table.insert;
local prosody = prosody;
local resolve_path = configmanager.resolve_relative_path;
@@ -33,11 +35,19 @@ module "certmanager"
-- Global SSL options if not overridden per-host
local global_ssl_config = configmanager.get("*", "ssl");
+-- Built-in defaults
local core_defaults = {
capath = "/etc/ssl/certs";
- protocol = "sslv23";
+ protocol = "tlsv1+";
verify = (ssl and ssl.x509 and { "peer", "client_once", }) or "none";
- options = { "no_sslv2", "no_sslv3", "cipher_server_preference", luasec_has_noticket and "no_ticket" or nil };
+ options = {
+ cipher_server_preference = true;
+ no_ticket = luasec_has_noticket;
+ no_compression = luasec_has_no_compression and configmanager.get("*", "ssl_compression") ~= true;
+ -- Has no_compression? Then it has these too...
+ single_dh_use = luasec_has_no_compression;
+ single_ecdh_use = luasec_has_no_compression;
+ };
verifyext = { "lsec_continue", "lsec_ignore_purpose" };
curve = "secp384r1";
ciphers = "HIGH+kEDH:HIGH+kEECDH:HIGH:!PSK:!SRP:!3DES:!aNULL";
@@ -45,6 +55,9 @@ local core_defaults = {
local path_options = { -- These we pass through resolve_path()
key = true, certificate = true, cafile = true, capath = true, dhparam = true
}
+local set_options = {
+ options = true, verify = true, verifyext = true
+}
if ssl and not luasec_has_verifyext and ssl.x509 then
-- COMPAT mw/luasec-hg
@@ -53,14 +66,21 @@ if ssl and not luasec_has_verifyext and ssl.x509 then
end
end
-if luasec_has_no_compression then -- Has no_compression? Then it has these too...
- core_defaults.options[#core_defaults.options+1] = "single_dh_use";
- core_defaults.options[#core_defaults.options+1] = "single_ecdh_use";
- if configmanager.get("*", "ssl_compression") ~= true then
- core_defaults.options[#core_defaults.options+1] = "no_compression";
+local function merge_set(t, o)
+ if type(t) ~= "table" then t = { t } end
+ for k,v in pairs(t) do
+ if v == true or v == false then
+ o[k] = v;
+ else
+ o[v] = true;
+ end
end
+ return o;
end
+local protocols = { "sslv2", "sslv3", "tlsv1", "tlsv1_1", "tlsv1_2" };
+for i = 1, #protocols do protocols[protocols[i] .. "+"] = i - 1; end
+
function create_context(host, mode, user_ssl_config)
user_ssl_config = user_ssl_config or {}
user_ssl_config.mode = mode;
@@ -69,25 +89,61 @@ function create_context(host, mode, user_ssl_config)
if global_ssl_config then
for option,default_value in pairs(global_ssl_config) do
- if not user_ssl_config[option] then
+ if user_ssl_config[option] == nil then
user_ssl_config[option] = default_value;
end
end
end
+
for option,default_value in pairs(core_defaults) do
- if not user_ssl_config[option] then
+ if user_ssl_config[option] == nil then
user_ssl_config[option] = default_value;
end
end
- user_ssl_config.password = user_ssl_config.password or function() log("error", "Encrypted certificate for %s requires 'ssl' 'password' to be set in config", host); end;
+
+ for option in pairs(set_options) do
+ local merged = {};
+ merge_set(core_defaults[option], merged);
+ if global_ssl_config then
+ merge_set(global_ssl_config[option], merged);
+ end
+ merge_set(user_ssl_config[option], merged);
+ local final_array = {};
+ for opt, enable in pairs(merged) do
+ if enable then
+ final_array[#final_array+1] = opt;
+ end
+ end
+ user_ssl_config[option] = final_array;
+ end
+
+ local min_protocol = protocols[user_ssl_config.protocol];
+ if min_protocol then
+ user_ssl_config.protocol = "sslv23";
+ for i = 1, min_protocol do
+ t_insert(user_ssl_config.options, "no_"..protocols[i]);
+ end
+ end
+
+ -- We can't read the password interactively when daemonized
+ user_ssl_config.password = user_ssl_config.password or
+ function() log("error", "Encrypted certificate for %s requires 'ssl' 'password' to be set in config", host); end;
+
for option in pairs(path_options) do
if type(user_ssl_config[option]) == "string" then
user_ssl_config[option] = resolve_path(config_path, user_ssl_config[option]);
end
end
- if not user_ssl_config.key then return nil, "No key present in SSL/TLS configuration for "..host; end
- if not user_ssl_config.certificate then return nil, "No certificate present in SSL/TLS configuration for "..host; end
+ -- Allow the cipher list to be a table
+ if type(user_ssl_config.ciphers) == "table" then
+ user_ssl_config.ciphers = t_concat(user_ssl_config.ciphers, ":")
+ end
+
+ if mode == "server" then
+ if not user_ssl_config.key then return nil, "No key present in SSL/TLS configuration for "..host; end
+ if not user_ssl_config.certificate then return nil, "No certificate present in SSL/TLS configuration for "..host; end
+ end
-- LuaSec expects dhparam to be a callback that takes two arguments.
-- We ignore those because it is mostly used for having a separate
@@ -141,6 +197,9 @@ end
function reload_ssl_config()
global_ssl_config = configmanager.get("*", "ssl");
+ if luasec_has_no_compression then
+ core_defaults.options.no_compression = configmanager.get("*", "ssl_compression") ~= true;
+ end
end
prosody.events.add_handler("config-reloaded", reload_ssl_config);
diff --git a/net/http/server.lua b/net/http/server.lua
index 5961169f..510b77fb 100644
--- a/net/http/server.lua
+++ b/net/http/server.lua
@@ -185,6 +185,7 @@ function handle_request(conn, request, finish_cb)
persistent = persistent;
conn = conn;
send = _M.send_response;
+ done = _M.finish_response;
finish_cb = finish_cb;
};
conn._http_open_response = response;
@@ -246,24 +247,30 @@ function handle_request(conn, request, finish_cb)
response.status_code = 404;
response:send(events.fire_event("http-error", { code = 404 }));
end
-function _M.send_response(response, body)
- if response.finished then return; end
- response.finished = true;
- response.conn._http_open_response = nil;
-
+local function prepare_header(response)
local status_line = "HTTP/"..response.request.httpversion.." "..(response.status or codes[response.status_code]);
local headers = response.headers;
- body = body or response.body or "";
- headers.content_length = #body;
-
local output = { status_line };
for k,v in pairs(headers) do
t_insert(output, headerfix[k]..v);
end
t_insert(output, "\r\n\r\n");
+ return output;
+end
+_M.prepare_header = prepare_header;
+function _M.send_response(response, body)
+ if response.finished then return; end
+ body = body or response.body or "";
+ response.headers.content_length = #body;
+ local output = prepare_header(response);
t_insert(output, body);
-
response.conn:write(t_concat(output));
+ response:done();
+end
+function _M.finish_response(response)
+ if response.finished then return; end
+ response.finished = true;
+ response.conn._http_open_response = nil;
if response.on_destroy then
response:on_destroy();
response.on_destroy = nil;
diff --git a/plugins/mod_admin_telnet.lua b/plugins/mod_admin_telnet.lua
index 2aa9bd9b..71dfa300 100644
--- a/plugins/mod_admin_telnet.lua
+++ b/plugins/mod_admin_telnet.lua
@@ -896,6 +896,9 @@ 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);
@@ -903,6 +906,9 @@ 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;
diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua
index 7a8af406..f0cdd7fb 100644
--- a/plugins/mod_c2s.lua
+++ b/plugins/mod_c2s.lua
@@ -174,19 +174,6 @@ local function session_close(session, reason)
end
end
-local function session_open_stream(session)
- local attr = {
- ["xmlns:stream"] = 'http://etherx.jabber.org/streams',
- xmlns = stream_callbacks.default_ns,
- version = "1.0",
- ["xml:lang"] = 'en',
- id = session.streamid or "",
- from = session.host
- };
- session.send("<?xml version='1.0'?>");
- session.send(st.stanza("stream:stream", attr):top_tag());
-end
-
module:hook_global("user-deleted", function(event)
local username, host = event.username, event.host;
local user = hosts[host].sessions[username];
@@ -234,7 +221,6 @@ function listener.onconnect(conn)
conn:setoption("keepalive", opt_keepalives);
end
- session.open_stream = session_open_stream;
session.close = session_close;
local stream = new_xmpp_stream(session, stream_callbacks);
diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua
index 1497b12f..297609d8 100644
--- a/plugins/mod_component.lua
+++ b/plugins/mod_component.lua
@@ -177,9 +177,7 @@ function stream_callbacks.streamopened(session, attr)
session.streamid = uuid_gen();
session.notopen = nil;
-- Return stream header
- session.send("<?xml version='1.0'?>");
- session.send(st.stanza("stream:stream", { xmlns=xmlns_component,
- ["xmlns:stream"]='http://etherx.jabber.org/streams', id=session.streamid, from=session.host }):top_tag());
+ session:open_stream();
end
function stream_callbacks.streamclosed(session)
diff --git a/plugins/mod_compression.lua b/plugins/mod_compression.lua
index 9da5254e..969172fd 100644
--- a/plugins/mod_compression.lua
+++ b/plugins/mod_compression.lua
@@ -26,7 +26,7 @@ end
module:hook("stream-features", function(event)
local origin, features = event.origin, event.features;
- if not origin.compressed and (origin.type == "c2s" or origin.type == "s2sin" or origin.type == "s2sout") then
+ if not origin.compressed and origin.type == "c2s" then
-- FIXME only advertise compression support when TLS layer has no compression enabled
features:add_child(compression_stream_feature);
end
@@ -35,7 +35,7 @@ end);
module:hook("s2s-stream-features", function(event)
local origin, features = event.origin, event.features;
-- FIXME only advertise compression support when TLS layer has no compression enabled
- if not origin.compressed and (origin.type == "c2s" or origin.type == "s2sin" or origin.type == "s2sout") then
+ if not origin.compressed and origin.type == "s2sin" then
features:add_child(compression_stream_feature);
end
end);
@@ -43,13 +43,13 @@ end);
-- Hook to activate compression if remote server supports it.
module:hook_stanza(xmlns_stream, "features",
function (session, stanza)
- if not session.compressed and (session.type == "c2s" or session.type == "s2sin" or session.type == "s2sout") then
+ if not session.compressed and session.type == "s2sout" then
-- does remote server support compression?
- local comp_st = stanza:child_with_name("compression");
+ local comp_st = stanza:get_child("compression", xmlns_compression_feature);
if comp_st then
-- do we support the mechanism
- for a in comp_st:children() do
- local algorithm = a[1]
+ for a in comp_st:childtags("method") do
+ local algorithm = a:get_text();
if algorithm == "zlib" then
session.sends2s(st.stanza("compress", {xmlns=xmlns_compression_protocol}):tag("method"):text("zlib"))
session.log("debug", "Enabled compression using zlib.")
@@ -160,8 +160,7 @@ module:hook("stanza/http://jabber.org/protocol/compress:compress", function(even
end
-- checking if the compression method is supported
- local method = stanza:child_with_name("method");
- method = method and (method[1] or "");
+ local method = stanza:get_child_text("method");
if method == "zlib" then
session.log("debug", "zlib compression enabled.");
diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua
index d987ef74..49529ea2 100644
--- a/plugins/mod_http.lua
+++ b/plugins/mod_http.lua
@@ -142,7 +142,13 @@ module:provides("net", {
listener = server.listener;
default_port = 5281;
encryption = "ssl";
- ssl_config = { verify = "none" };
+ ssl_config = {
+ verify = {
+ peer = false,
+ client_once = false,
+ "none",
+ }
+ };
multiplex = {
pattern = "^[A-Z]";
};
diff --git a/plugins/mod_posix.lua b/plugins/mod_posix.lua
index 69542c96..89d6d2b6 100644
--- a/plugins/mod_posix.lua
+++ b/plugins/mod_posix.lua
@@ -129,14 +129,6 @@ end
require "core.loggingmanager".register_sink_type("syslog", syslog_sink_maker);
local daemonize = module:get_option("daemonize", prosody.installed);
-if daemonize == nil then
- local no_daemonize = module:get_option("no_daemonize"); --COMPAT w/ 0.5
- daemonize = not no_daemonize;
- if no_daemonize ~= nil then
- module:log("warn", "The 'no_daemonize' option is now replaced by 'daemonize'");
- module:log("warn", "Update your config from 'no_daemonize = %s' to 'daemonize = %s'", tostring(no_daemonize), tostring(daemonize));
- end
-end
local function remove_log_sinks()
local lm = require "core.loggingmanager";
diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua
index 5531ca3e..73d95970 100644
--- a/plugins/mod_s2s/mod_s2s.lua
+++ b/plugins/mod_s2s/mod_s2s.lua
@@ -510,22 +510,10 @@ local function session_close(session, reason, remote_reason)
end
end
-function session_open_stream(session, from, to)
- local attr = {
- ["xmlns:stream"] = 'http://etherx.jabber.org/streams',
- xmlns = 'jabber:server',
- version = session.version and (session.version > 0 and "1.0" or nil),
- ["xml:lang"] = 'en',
- id = session.streamid,
- from = from, to = to,
- }
+function session_stream_attrs(session, from, to, attr)
if not from or (hosts[from] and hosts[from].modules.dialback) then
attr["xmlns:db"] = 'jabber:server:dialback';
end
-
- session.sends2s("<?xml version='1.0'?>");
- session.sends2s(st.stanza("stream:stream", attr):top_tag());
- return true;
end
-- Session initialization logic shared by incoming and outgoing
@@ -540,7 +528,7 @@ local function initialize_session(session)
session.stream:reset();
end
- session.open_stream = session_open_stream;
+ session.stream_attrs = session_stream_attrs;
local filter = session.filter;
function session.data(data)
diff --git a/plugins/mod_storage_sql2.lua b/plugins/mod_storage_sql2.lua
index 7a2ec4a7..7414e5ed 100644
--- a/plugins/mod_storage_sql2.lua
+++ b/plugins/mod_storage_sql2.lua
@@ -289,7 +289,7 @@ function archive_store:find(username, query)
-- Total matching
if query.total then
- local stats = engine:select(sql_query:gsub("^(SELECT).-(FROM)", "%1 COUNT(*) %2"):format(t_concat(where, " AND "), "DESC", ""), unpack(args));
+ local stats = engine:select("SELECT COUNT(*) FROM `prosodyarchive` WHERE " .. t_concat(where, " AND "), unpack(args));
if stats then
local _total = stats()
total = _total and _total[1];
diff --git a/prosody b/prosody
index b411370f..8fcee8e8 100755
--- a/prosody
+++ b/prosody
@@ -49,9 +49,6 @@ _G.prosody = prosody;
-- Check dependencies
local dependencies = require "util.dependencies";
-if not dependencies.check_dependencies() then
- os.exit(1);
-end
-- Load the config-parsing module
config = require "core.configmanager"
@@ -116,6 +113,12 @@ function read_config()
end
end
+function check_dependencies()
+ if not dependencies.check_dependencies() then
+ os.exit(1);
+ end
+end
+
function load_libraries()
-- Load socket framework
server = require "net.server"
@@ -382,6 +385,7 @@ init_logging();
sanity_check();
sandbox_require();
set_function_metatable();
+check_dependencies();
load_libraries();
init_global_state();
read_version();
diff --git a/prosodyctl b/prosodyctl
index c3adad4d..00aeac40 100755
--- a/prosodyctl
+++ b/prosodyctl
@@ -414,7 +414,11 @@ function commands.start(arg)
local ok, ret = prosodyctl.start();
if ok then
- if config.get("*", "daemonize") ~= false then
+ local daemonize = config.get("*", "daemonize");
+ if daemonize == nil then
+ daemonize = prosody.installed;
+ end
+ if daemonize then
local i=1;
while true do
local ok, running = prosodyctl.isrunning();
diff --git a/util/dependencies.lua b/util/dependencies.lua
index 9d80d241..ea19d9a8 100644
--- a/util/dependencies.lua
+++ b/util/dependencies.lua
@@ -49,6 +49,14 @@ package.preload["util.ztact"] = function ()
end;
function check_dependencies()
+ if _VERSION ~= "Lua 5.1" then
+ print "***********************************"
+ print("Unsupported Lua version: ".._VERSION);
+ print("Only Lua 5.1 is supported.");
+ print "***********************************"
+ return false;
+ end
+
local fatal;
local lxp = softreq "lxp"
diff --git a/util/prosodyctl.lua b/util/prosodyctl.lua
index fe862114..d59c163c 100644
--- a/util/prosodyctl.lua
+++ b/util/prosodyctl.lua
@@ -189,8 +189,8 @@ function getpid()
return false, "no-pidfile";
end
- local modules_enabled = set.new(config.get("*", "modules_enabled"));
- if not modules_enabled:contains("posix") then
+ local modules_enabled = set.new(config.get("*", "modules_disabled"));
+ if prosody.platform ~= "posix" or modules_enabled:contains("posix") then
return false, "no-posix";
end
diff --git a/util/xmppstream.lua b/util/xmppstream.lua
index 586ad5f9..6982aae3 100644
--- a/util/xmppstream.lua
+++ b/util/xmppstream.lua
@@ -241,6 +241,25 @@ function new(session, stream_callbacks, stanza_size_limit)
local parser = new_parser(handlers, ns_separator, false);
local parse = parser.parse;
+ function session.open_stream(session, from, to)
+ local send = session.sends2s or session.send;
+
+ local attr = {
+ ["xmlns:stream"] = "http://etherx.jabber.org/streams",
+ ["xml:lang"] = "en",
+ xmlns = stream_callbacks.default_ns,
+ version = session.version and (session.version > 0 and "1.0" or nil),
+ id = session.streamid or "",
+ from = from or session.host, to = to,
+ };
+ if session.stream_attrs then
+ session:stream_attrs(from, to, attr)
+ end
+ send("<?xml version='1.0'?>");
+ send(st.stanza("stream:stream", attr):top_tag());
+ return true;
+ end
+
return {
reset = function ()
parser = new_parser(handlers, ns_separator, false);