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 ..."); |