Software /
code /
prosody-modules
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 ..."); |