Changeset

6145:69bc9dfcbd89

Merge daurnimator->trunk
author Matthew Wild <mwild1@gmail.com>
date Mon, 21 Apr 2014 17:42:44 +0100
parents 6090:61403eb023bf (diff) 6144:cb08bba0443a (current diff)
children 6150:5b59798c979a 6232:d7dc71d9171d
files
diffstat 15 files changed, 152 insertions(+), 76 deletions(-) [+]
line wrap: on
line diff
--- a/core/certmanager.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/core/certmanager.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -15,6 +15,8 @@
 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 @@
 -- 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 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 @@
 	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 @@
 
 	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 @@
 
 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);
--- a/net/http/server.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/net/http/server.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -185,6 +185,7 @@
 		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 @@
 	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;
--- a/plugins/mod_admin_telnet.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/plugins/mod_admin_telnet.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -896,6 +896,9 @@
 
 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 @@
 
 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;
--- a/plugins/mod_c2s.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/plugins/mod_c2s.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -174,19 +174,6 @@
 	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 @@
 		conn:setoption("keepalive", opt_keepalives);
 	end
 
-	session.open_stream = session_open_stream;
 	session.close = session_close;
 
 	local stream = new_xmpp_stream(session, stream_callbacks);
--- a/plugins/mod_component.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/plugins/mod_component.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -177,9 +177,7 @@
 	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)
--- a/plugins/mod_compression.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/plugins/mod_compression.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -26,7 +26,7 @@
 
 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 @@
 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 @@
 -- 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 @@
 		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.");
 
--- a/plugins/mod_http.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/plugins/mod_http.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -142,7 +142,13 @@
 	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]";
 	};
--- a/plugins/mod_posix.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/plugins/mod_posix.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -129,14 +129,6 @@
 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";
--- a/plugins/mod_s2s/mod_s2s.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/plugins/mod_s2s/mod_s2s.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -510,22 +510,10 @@
 	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 @@
 		session.stream:reset();
 	end
 
-	session.open_stream = session_open_stream;
+	session.stream_attrs = session_stream_attrs;
 
 	local filter = session.filter;
 	function session.data(data)
--- a/plugins/mod_storage_sql2.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/plugins/mod_storage_sql2.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -289,7 +289,7 @@
 
 		-- 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];
--- a/prosody	Thu Apr 17 09:01:32 2014 +0100
+++ b/prosody	Mon Apr 21 17:42:44 2014 +0100
@@ -49,9 +49,6 @@
 
 -- 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 @@
 	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 @@
 sanity_check();
 sandbox_require();
 set_function_metatable();
+check_dependencies();
 load_libraries();
 init_global_state();
 read_version();
--- a/prosodyctl	Thu Apr 17 09:01:32 2014 +0100
+++ b/prosodyctl	Mon Apr 21 17:42:44 2014 +0100
@@ -414,7 +414,11 @@
 	
 	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();
--- a/util/dependencies.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/util/dependencies.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -49,6 +49,14 @@
 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"
--- a/util/prosodyctl.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/util/prosodyctl.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -189,8 +189,8 @@
 		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
 
--- a/util/xmppstream.lua	Thu Apr 17 09:01:32 2014 +0100
+++ b/util/xmppstream.lua	Mon Apr 21 17:42:44 2014 +0100
@@ -241,6 +241,25 @@
 	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);