changeset 2044:06faf7a149e3

mod_poke_strangers: Log details about JIDs that look like they are spamming.
author Thijs Alkemade <me@thijsalkema.de>
date Fri, 05 Feb 2016 11:23:13 +0100
parents 4ad3f25ab004
children 0aa8aa6cdb1b
files mod_poke_strangers/README.markdown mod_poke_strangers/mod_poke_strangers.lua
diffstat 2 files changed, 79 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_poke_strangers/README.markdown	Fri Feb 05 11:23:13 2016 +0100
@@ -0,0 +1,24 @@
+---
+labels:
+- 'Stage-Alpha'
+summary: 'Query the features and version of JIDs sending messages to contacts they are not subscribed to.'
+...
+
+Introduction
+============
+
+In order to build heuristics for which messages are spam, it is necessary to
+log as many details as possible about the spammers. This module sends a
+version and disco query whenever a message is received from a JID to a user it
+is not subscribed to. The results are printed to Prosody's log file at the
+'info' level. Queried full JIDs are not queried again until Prosody restarts.
+
+The queries are sent regardless of whether the local user exists, so it does
+not reveal if an account is active.
+
+Compatibility
+=============
+
+  ----- -------
+  0.9   Works
+  ----- -------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mod_poke_strangers/mod_poke_strangers.lua	Fri Feb 05 11:23:13 2016 +0100
@@ -0,0 +1,55 @@
+local st = require"util.stanza";
+local jid_split = require "util.jid".split;
+local jid_bare = require "util.jid".bare;
+local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
+local uuid_generate = require "util.uuid".generate;
+local set = require "util.set";
+
+local recently_queried = set.new();
+
+function check_subscribed(event)
+	local stanza = event.stanza;
+	local local_user_jid = stanza.attr.to;
+	local to_user, to_host, to_resource = jid_split(local_user_jid);
+	local stranger_jid = stanza.attr.from;
+
+	if recently_queried:contains(stranger_jid) then
+		module:log("debug", "Not re-poking " .. stranger_jid);
+		return nil;
+	end
+
+	local from_jid = jid_bare(stranger_jid);
+
+	if to_user and not is_contact_subscribed(to_user, to_host, from_jid) then
+		if to_resource and stanza.attr.type == "groupchat" then
+			return nil;
+		end
+
+		recently_queried:add(stranger_jid);
+
+		local version_id = uuid_generate();
+
+		module:hook("iq-result/host/" .. version_id, function (event)
+			module:log("info", "Stranger " .. stranger_jid .. " version: " .. tostring(event.stanza));
+			return true;
+		end);
+
+		module:send(st.iq({ type = "get", to = stranger_jid, from = to_host, id = version_id }):query("jabber:iq:version"));
+
+
+		local disco_id = uuid_generate();
+
+		module:hook("iq-result/host/" .. disco_id, function (event)
+			module:log("info", "Stranger " .. stranger_jid .. " disco: " .. tostring(event.stanza));
+			return true;
+		end);
+
+		module:send(st.iq({ type = "get", to = stranger_jid, from = to_host, id = disco_id }):query("http://jabber.org/protocol/disco#info"));
+	end
+
+	return nil;
+end
+
+module:hook("message/bare", check_subscribed, 225);
+module:hook("message/full", check_subscribed, 225);
+-- Not hooking iqs, as that could turn into infinite loops!