view mod_watchuntrusted/mod_watchuntrusted.lua @ 1268:854a3933cfcd

mod_muc_log_http: URL-encode room names. This allows special characters in room names to work. Ideally this escaping shouldn’t be done in the user visible content, but the module’s template system doesn’t currently allow that.
author Waqas Hussain <waqas20@gmail.com>
date Sat, 04 Jan 2014 16:50:57 -0500
parents 5eaecb7f680d
children 116488cced16
line wrap: on
line source

local jid_prep = require "util.jid".prep;

local secure_auth = module:get_option_boolean("s2s_secure_auth", false);
local secure_domains, insecure_domains =
	module:get_option_set("s2s_secure_domains", {})._items, module:get_option_set("s2s_insecure_domains", {})._items;

local untrusted_fail_watchers = module:get_option_set("untrusted_fail_watchers", module:get_option("admins", {})) / jid_prep;
local untrusted_fail_notification = module:get_option("untrusted_fail_notification", "Establishing a secure connection from $from_host to $to_host failed. Certificate hash: $sha1. $errors");

local st = require "util.stanza";

module:hook_global("s2s-check-certificate", function (event)
    local session, host = event.session, event.host;
    local conn = session.conn:socket();
    local local_host = session.direction == "outgoing" and session.from_host or session.to_host;

    if not (local_host == module:get_host()) then return end

    module:log("debug", "Checking certificate...");
    local must_secure = secure_auth;

    if not must_secure and secure_domains[host] then
            must_secure = true;
    elseif must_secure and insecure_domains[host] then
            must_secure = false;
    end

    if must_secure and (session.cert_chain_status ~= "valid" or session.cert_identity_status ~= "valid") then
		local _, errors = conn:getpeerverification();
		local error_message = "";

		for depth, t in pairs(errors or {}) do
			if #t > 0 then
				error_message = error_message .. "Error with certificate " .. (depth - 1) .. ": " .. table.concat(t, ", ") .. ". ";
			end
		end

		if session.cert_identity_status then
			error_message = error_message .. "This certificate is " .. session.cert_identity_status .. " for " .. host .. ".";
		end

		local replacements = { sha1 = event.cert and event.cert:digest("sha1"), errors = error_message };

		local message = st.message{ type = "chat", from = local_host }
			:tag("body")
				:text(untrusted_fail_notification:gsub("%$([%w_]+)", function (v)
					return event[v] or session and session[v] or replacements and replacements[v] or nil;
				end));
		for jid in untrusted_fail_watchers do
			module:log("debug", "Notifying %s", jid);
			message.attr.to = jid;
			module:send(message);
		end
	end
end, -0.5);