Comparison

mod_privacy/mod_privacy.lua @ 11:529819205379

do the first real blocking actions
author Thilo Cestonaro <thilo@cestona.ro>
date Sat, 26 Sep 2009 22:22:51 +0200
parent 10:7d70faba234c
child 15:14b18ef8b554
comparison
equal deleted inserted replaced
10:7d70faba234c 11:529819205379
5 -- 5 --
6 -- This project is MIT/X11 licensed. Please see the 6 -- This project is MIT/X11 licensed. Please see the
7 -- COPYING file in the source package for more information. 7 -- COPYING file in the source package for more information.
8 -- 8 --
9 9
10
11 local prosody = prosody; 10 local prosody = prosody;
12 local helpers = require "util/helpers"; 11 local helpers = require "util/helpers";
13 local st = require "util.stanza"; 12 local st = require "util.stanza";
14 local datamanager = require "util.datamanager"; 13 local datamanager = require "util.datamanager";
15 local bare_sessions = bare_sessions; 14 local bare_sessions = bare_sessions;
16 15 local util_Jid = require "util.jid";
16 local jid_bare = util_Jid.bare;
17 local jid_split = util_Jid.split;
17 18
18 function findNamedList (privacy_lists, name) 19 function findNamedList (privacy_lists, name)
19 local ret = nil 20 local ret = nil
20 if privacy_lists.lists == nil then return nil; end 21 if privacy_lists.lists == nil then
21 22 module:log("debug", "no lists loaded.")
23 return nil;
24 end
25
26 module:log("debug", "searching for list: %s", name);
22 for i=1, #privacy_lists.lists do 27 for i=1, #privacy_lists.lists do
23 if privacy_lists.lists[i].name == name then 28 if privacy_lists.lists[i].name == name then
24 ret = i; 29 ret = i;
25 break; 30 break;
26 end 31 end
141 end 146 end
142 ret = true; 147 ret = true;
143 end 148 end
144 else 149 else
145 local idx = findNamedList(privacy_lists, name); 150 local idx = findNamedList(privacy_lists, name);
146 log("debug", "list idx: %d", idx or -1); 151 module:log("debug", "list idx: %d", idx or -1);
147 if idx ~= nil then 152 if idx ~= nil then
148 list = privacy_lists.lists[idx]; 153 list = privacy_lists.lists[idx];
149 reply = reply:tag("list", {name=list.name}); 154 reply = reply:tag("list", {name=list.name});
150 for _,item in ipairs(list.items) do 155 for _,item in ipairs(list.items) do
151 reply:tag("item", {type=item.type, value=item.value, action=item.action, order=item.order}); 156 reply:tag("item", {type=item.type, value=item.value, action=item.action, order=item.order});
222 return true; 227 return true;
223 end 228 end
224 return false; 229 return false;
225 end, 500); 230 end, 500);
226 231
227 function checkIfNeedToBeBlocked(e) 232 function checkIfNeedToBeBlocked(e, node_, host_)
228 local origin, stanza = e.origin, e.stanza; 233 local origin, stanza = e.origin, e.stanza;
229 local privacy_lists = datamanager.load(origin.username, origin.host, "privacy") or {}; 234 local privacy_lists = datamanager.load(node_, host_, "privacy") or {};
230 if privacy_lists.lists ~= nil then 235 local bare_jid = node_.."@"..host_;
231 end 236
232 return false; 237 module:log("debug", "checkIfNeedToBeBlocked: username: %s, host: %s", node_, host_);
233 end 238 module:log("debug", "stanza: %s, to: %s, form: %s", stanza.name, stanza.attr.to or "nil", stanza.attr.from or "nil");
234 239
235 module:hook("pre-message/full", checkIfNeedToBeBlocked, 500); 240 if privacy_lists.lists ~= nil and stanza.attr.to ~= nil and stanza.attr.from ~= nil then
236 module:hook("pre-iq/bare", checkIfNeedToBeBlocked, 500); 241 if privacy_lists.active == nil and privacy_lists.default == nil then
237 module:hook("pre-presence/bare", checkIfNeedToBeBlocked, 500); 242 return; -- Nothing to block, default is Allow all
243 end
244
245 local idx;
246 local list;
247 local item;
248 local block = false;
249 local apply = false;
250 local listname = privacy_lists.active;
251 if listname == nil then
252 listname = privacy_lists.default; -- no active list selected, use default list
253 end
254 idx = findNamedList(privacy_lists, listname);
255 if idx == nil then
256 module:log("info", "given privacy listname not found.");
257 return;
258 end
259 list = privacy_lists.lists[idx];
260 if list == nil then
261 module:log("info", "privacy list index wrong.");
262 return;
263 end
264 for _,item in ipairs(list.items) do
265 local apply = false;
266 block = false;
267 if (stanza.name == "message" and item.message) or
268 (stanza.name == "iq" and item.iq) or
269 (stanza.name == "presence" and jid_bare(stanza.attr.to) == bare_jid and item["presence-in"]) or
270 (stanza.name == "presence" and jid_bare(stanza.attr.from) == bare_jid and item["presence-out"]) or
271 (item.message == false and item.iq == false and item["presence-in"] == false and item["presence-in"] == false) then
272 module:log("debug", "stanza type matched.");
273 apply = true;
274 end
275 if apply then
276 local evilJid = {};
277 apply = false;
278 if jid_bare(stanza.attr.to) == bare_jid then
279 evilJid.node, evilJid.host, evilJid.resource = jid_split(stanza.attr.from);
280 else
281 evilJid.node, evilJid.host, evilJid.resource = jid_split(stanza.attr.to);
282 end
283 if item.type == "jid" and
284 (evilJid.node and evilJid.host and evilJid.resource and item.value == evilJid.node.."@"..evilJid.host.."/"..evilJid.resource) or
285 (evilJid.node and evilJid.host and item.value == evilJid.node.."@"..evilJid.host) or
286 (evilJid.host and evilJid.resource and item.value == evilJid.host.."/"..evilJid.resource) or
287 (evilJid.host and item.value == evilJid.host) then
288 module:log("debug", "jid matched.");
289 apply = true;
290 block = (item.action == "deny");
291 elseif item.type == "group" then
292 local groups = origin.roster[jid_bare(stanza.from)].groups;
293 for _,group in ipairs(groups) do
294 if group == item.value then
295 module:log("debug", "group matched.");
296 apply = true;
297 block = (item.action == "deny");
298 break;
299 end
300 end
301 elseif item.type == "subscription" then
302 if origin.roster[jid_bare(stanza.from)].subscription == item.value then
303 module:log("debug", "subscription matched.");
304 apply = true;
305 block = (item.action == "deny");
306 end
307 elseif item.type == nil then
308 module:log("debug", "no item.type, so matched.");
309 apply = true;
310 block = (item.action == "deny");
311 end
312 end
313 if apply then
314 if block then
315 module:log("info", "stanza blocked: %s, to: %s, from: %s", stanza.name, stanza.attr.to or "nil", stanza.attr.from or "nil");
316 if stanza.name == "message" then
317 origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
318 elseif stanza.name == "iq" and (stanza.attr.type == "get" or stanza.attr.type == "set") then
319 origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
320 end
321 return true; -- stanza blocked !
322 else
323 module:log("info", "stanza explicit allowed!")
324 end
325 end
326 end
327 end
328 return;
329 end
330
331 function preCheckIncoming(e)
332 if e.stanza.attr.to ~= nil then
333 local node, host, resource = jid_split(e.stanza.attr.to);
334 if node == nil or host == nil then
335 return;
336 end
337 return checkIfNeedToBeBlocked(e, node, host);
338 end
339 return;
340 end
341
342 function preCheckOutgoing(e)
343 if e.stanza.attr.from ~= nil then
344 local node, host, resource = jid_split(e.stanza.attr.from);
345 if node == nil or host == nil then
346 return;
347 end
348 return checkIfNeedToBeBlocked(e, node, host);
349 end
350 return;
351 end
352
353
354 module:hook("pre-message/full", preCheckOutgoing, 500);
355 module:hook("pre-message/bare", preCheckOutgoing, 500);
356 module:hook("pre-message/host", preCheckOutgoing, 500);
357 module:hook("pre-iq/full", preCheckOutgoing, 500);
358 module:hook("pre-iq/bare", preCheckOutgoing, 500);
359 module:hook("pre-iq/host", preCheckOutgoing, 500);
360 module:hook("pre-presence/full", preCheckOutgoing, 500);
361 module:hook("pre-presence/bare", preCheckOutgoing, 500);
362 module:hook("pre-presence/host", preCheckOutgoing, 500);
363
364 module:hook("message/full", preCheckIncoming, 500);
365 module:hook("message/bare", preCheckIncoming, 500);
366 module:hook("message/host", preCheckIncoming, 500);
367 module:hook("iq/full", preCheckIncoming, 500);
368 module:hook("iq/bare", preCheckIncoming, 500);
369 module:hook("iq/host", preCheckIncoming, 500);
370 module:hook("presence/full", preCheckIncoming, 500);
371 module:hook("presence/bare", preCheckIncoming, 500);
372 module:hook("presence/host", preCheckIncoming, 500);
238 373
239 -- helpers.log_events(hosts["albastru.de"].events, "albastru.de"); 374 -- helpers.log_events(hosts["albastru.de"].events, "albastru.de");
240 -- helpers.log_events(prosody.events, "*"); 375 -- helpers.log_events(prosody.events, "*");
241 376
242 module:log("info", "mod_privacy loaded ..."); 377 module:log("info", "mod_privacy loaded ...");