Software /
code /
prosody-modules
Comparison
mod_privacy/mod_privacy.lua @ 17:ccb07c0efc7e
mod_privacy: prepare everything for the "is used" checking stuff...
author | Thilo Cestonaro <thilo@cestona.ro> |
---|---|
date | Mon, 28 Sep 2009 22:22:22 +0200 |
parent | 16:35e74c1094a7 |
child | 18:2df11ec081fe |
comparison
equal
deleted
inserted
replaced
16:35e74c1094a7 | 17:ccb07c0efc7e |
---|---|
35 return ret; | 35 return ret; |
36 end | 36 end |
37 | 37 |
38 function declineList (privacy_lists, origin, stanza, which) | 38 function declineList (privacy_lists, origin, stanza, which) |
39 module:log("info", "User requests to decline the use of privacy list: %s", which); | 39 module:log("info", "User requests to decline the use of privacy list: %s", which); |
40 privacy_lists[which] = nil; | 40 if which == "default" then |
41 privacy_lists.default = nil; -- TODO check if used! | |
42 elseif which == "active" then | |
43 origin.activePrivacyList = nil; | |
44 end | |
41 origin.send(st.reply(stanza)); | 45 origin.send(st.reply(stanza)); |
42 return true; | 46 return true; |
43 end | 47 end |
44 | 48 |
45 function activateList (privacy_lists, origin, stanza, which, name) | 49 function activateList (privacy_lists, origin, stanza, which, name) |
49 | 53 |
50 if privacy_lists[which] == nil then | 54 if privacy_lists[which] == nil then |
51 privacy_lists[which] = ""; | 55 privacy_lists[which] = ""; |
52 end | 56 end |
53 | 57 |
54 if privacy_lists[which] ~= name and idx ~= nil then | 58 if which == "default" and privacy_lists.default ~= name and idx ~= nil then |
55 privacy_lists[which] = name; | 59 privacy_lists.default = name; -- TODO check if used! |
60 ret = true; | |
61 elseif which == "active" and origin.activePrivacyList ~= name and idx ~= nil then | |
62 origin.activePrivacyList = name; | |
63 ret = true; | |
64 end | |
65 if ret == true then | |
56 origin.send(st.reply(stanza)); | 66 origin.send(st.reply(stanza)); |
57 ret = true; | |
58 end | 67 end |
59 return ret; | 68 return ret; |
60 end | 69 end |
61 | 70 |
62 function deleteList (privacy_lists, origin, stanza, name) | 71 function deleteList (privacy_lists, origin, stanza, name) |
63 module:log("info", "User requests to delete privacy list: %s", name); | 72 module:log("info", "User requests to delete privacy list: %s", name); |
64 local ret = false; | 73 local ret = false; |
65 local idx = findNamedList(privacy_lists, name); | 74 local idx = findNamedList(privacy_lists, name); |
66 | 75 |
67 if idx ~= nil then | 76 if idx ~= nil then |
68 table.remove(privacy_lists.lists, idx); | 77 table.remove(privacy_lists.lists, idx); -- TODO check if used! |
69 origin.send(st.reply(stanza)); | 78 origin.send(st.reply(stanza)); |
70 ret = true; | 79 ret = true; |
71 end | 80 end |
72 return ret; | 81 return ret; |
73 end | 82 end |
173 local ret = false; | 182 local ret = false; |
174 local reply = st.reply(stanza); | 183 local reply = st.reply(stanza); |
175 reply:tag("query", {xmlns="jabber:iq:privacy"}); | 184 reply:tag("query", {xmlns="jabber:iq:privacy"}); |
176 | 185 |
177 if name == nil then | 186 if name == nil then |
178 reply:tag("active", {name=privacy_lists.active or ""}):up(); | 187 reply:tag("active", {name=origin.activePrivacyList or ""}):up(); |
179 reply:tag("default", {name=privacy_lists.default or ""}):up(); | 188 reply:tag("default", {name=privacy_lists.default or ""}):up(); |
180 if privacy_lists.lists then | 189 if privacy_lists.lists then |
181 for _,list in ipairs(privacy_lists.lists) do | 190 for _,list in ipairs(privacy_lists.lists) do |
182 reply:tag("list", {name=list.name}):up(); | 191 reply:tag("list", {name=list.name}):up(); |
183 end | 192 end |
205 origin.send(reply); | 214 origin.send(reply); |
206 end | 215 end |
207 return ret; | 216 return ret; |
208 end | 217 end |
209 | 218 |
210 -- "[tagname]/[target-type]/[payload-namespace]:[payload-tagname]" | |
211 module:hook("iq/bare/jabber:iq:privacy:query", function(data) | 219 module:hook("iq/bare/jabber:iq:privacy:query", function(data) |
212 local origin, stanza = data.origin, data.stanza; | 220 local origin, stanza = data.origin, data.stanza; |
213 | 221 |
214 if stanza.attr.to == nil then -- only service requests to own bare JID | 222 if stanza.attr.to == nil then -- only service requests to own bare JID |
215 local err_reply = nil; | 223 local err_reply = nil; |
216 local query = stanza.tags[1]; -- the query element | 224 local query = stanza.tags[1]; -- the query element |
217 local valid = false; | 225 local valid = false; |
218 local privacy_lists = datamanager.load(origin.username, origin.host, "privacy") or {}; | 226 local privacy_lists = datamanager.load(origin.username, origin.host, "privacy") or {}; |
219 | 227 |
220 if stanza.attr.type == "set" then | 228 if stanza.attr.type == "set" then |
221 if #query.tags >= 1 then | 229 if #query.tags == 1 then -- the <query/> element MUST NOT include more than one child element |
222 for _,tag in ipairs(query.tags) do | 230 for _,tag in ipairs(query.tags) do |
223 if tag.name == "active" or tag.name == "default" then | 231 if tag.name == "active" or tag.name == "default" then |
224 if tag.attr.name == nil then -- Client declines the use of active / default list | 232 if tag.attr.name == nil then -- Client declines the use of active / default list |
225 valid = declineList(privacy_lists, origin, stanza, tag.name); | 233 valid = declineList(privacy_lists, origin, stanza, tag.name); |
226 else -- Client requests change of active / default list | 234 else -- Client requests change of active / default list |
227 valid = activateList(privacy_lists, origin, stanza, tag.name, tag.attr.name); | 235 valid = activateList(privacy_lists, origin, stanza, tag.name, tag.attr.name); |
228 err_reply = st.error_reply(stanza, "cancel", "item-not-found"); | 236 if valid ~= true and valid ~= false then |
237 err_reply = st.error_reply(stanza, "cancel", valid); | |
238 valid = false; | |
239 end | |
229 end | 240 end |
230 elseif tag.name == "list" and tag.attr.name then -- Client adds / edits a privacy list | 241 elseif tag.name == "list" and tag.attr.name then -- Client adds / edits a privacy list |
231 if #tag.tags == 0 then -- Client removes a privacy list | 242 if #tag.tags == 0 then -- Client removes a privacy list |
232 valid = deleteList(privacy_lists, origin, stanza, tag.attr.name); | 243 valid = deleteList(privacy_lists, origin, stanza, tag.attr.name); |
233 else -- Client edits a privacy list | 244 else -- Client edits a privacy list |
234 valid = createOrReplaceList(privacy_lists, origin, stanza, tag.attr.name, tag.tags) | 245 valid = createOrReplaceList(privacy_lists, origin, stanza, tag.attr.name, tag.tags); -- TODO check if used! |
235 if valid ~= true then | 246 if valid ~= true and valid ~= false then |
236 err_reply = st.error_reply(stanza, "cancel", valid); | 247 err_reply = st.error_reply(stanza, "cancel", valid); |
237 valid = false; | 248 valid = false; |
238 end | 249 end |
239 end | 250 end |
240 end | 251 end |
268 return true; | 279 return true; |
269 end | 280 end |
270 return false; | 281 return false; |
271 end, 500); | 282 end, 500); |
272 | 283 |
273 function checkIfNeedToBeBlocked(e, node_, host_) | 284 function checkIfNeedToBeBlocked(e, session) |
274 local origin, stanza = e.origin, e.stanza; | 285 local origin, stanza = e.origin, e.stanza; |
275 local privacy_lists = datamanager.load(node_, host_, "privacy") or {}; | 286 local privacy_lists = datamanager.load(session.username, session.host, "privacy") or {}; |
276 local bare_jid = node_.."@"..host_; | 287 local bare_jid = session.username.."@"..session.host; |
277 | 288 |
278 module:log("debug", "checkIfNeedToBeBlocked: username: %s, host: %s", node_, host_); | 289 module:log("debug", "checkIfNeedToBeBlocked: username: %s, host: %s", session.username, session.host); |
279 module:log("debug", "stanza: %s, to: %s, form: %s", stanza.name, stanza.attr.to or "nil", stanza.attr.from or "nil"); | 290 module:log("debug", "stanza: %s, to: %s, form: %s", stanza.name, stanza.attr.to or "nil", stanza.attr.from or "nil"); |
280 | 291 |
281 if privacy_lists.lists ~= nil and stanza.attr.to ~= nil and stanza.attr.from ~= nil then | 292 if privacy_lists.lists ~= nil and stanza.attr.to ~= nil and stanza.attr.from ~= nil then |
282 if privacy_lists.active == nil and privacy_lists.default == nil then | 293 if session.activePrivacyList == nil and privacy_lists.default == nil then |
283 return; -- Nothing to block, default is Allow all | 294 return; -- Nothing to block, default is Allow all |
284 end | 295 end |
285 | 296 |
286 local idx; | 297 local idx; |
287 local list; | 298 local list; |
288 local item; | 299 local item; |
289 local block = false; | 300 local listname = session.activePrivacyList; |
290 local apply = false; | |
291 local listname = privacy_lists.active; | |
292 if listname == nil then | 301 if listname == nil then |
293 listname = privacy_lists.default; -- no active list selected, use default list | 302 listname = privacy_lists.default; -- no active list selected, use default list |
294 end | 303 end |
295 idx = findNamedList(privacy_lists, listname); | 304 idx = findNamedList(privacy_lists, listname); |
296 if idx == nil then | 305 if idx == nil then |
302 module:log("info", "privacy list index wrong."); | 311 module:log("info", "privacy list index wrong."); |
303 return; | 312 return; |
304 end | 313 end |
305 for _,item in ipairs(list.items) do | 314 for _,item in ipairs(list.items) do |
306 local apply = false; | 315 local apply = false; |
307 block = false; | 316 local block = false; |
308 if (stanza.name == "message" and item.message) or | 317 if (stanza.name == "message" and item.message) or |
309 (stanza.name == "iq" and item.iq) or | 318 (stanza.name == "iq" and item.iq) or |
310 (stanza.name == "presence" and jid_bare(stanza.attr.to) == bare_jid and item["presence-in"]) or | 319 (stanza.name == "presence" and jid_bare(stanza.attr.to) == bare_jid and item["presence-in"]) or |
311 (stanza.name == "presence" and jid_bare(stanza.attr.from) == bare_jid and item["presence-out"]) or | 320 (stanza.name == "presence" and jid_bare(stanza.attr.from) == bare_jid and item["presence-out"]) or |
312 (item.message == false and item.iq == false and item["presence-in"] == false and item["presence-in"] == false) then | 321 (item.message == false and item.iq == false and item["presence-in"] == false and item["presence-in"] == false) then |
313 module:log("debug", "stanza type matched."); | 322 module:log("debug", "stanza type matched."); |
314 apply = true; | 323 apply = true; |
315 end | 324 end |
316 if apply then | 325 if apply then |
317 local evilJid = {}; | 326 local evilJid = {}; |
318 apply = false; | 327 apply = false; |
319 if jid_bare(stanza.attr.to) == bare_jid then | 328 if jid_bare(stanza.attr.to) == bare_jid then |
328 (evilJid.host and item.value == evilJid.host) then | 337 (evilJid.host and item.value == evilJid.host) then |
329 module:log("debug", "jid matched."); | 338 module:log("debug", "jid matched."); |
330 apply = true; | 339 apply = true; |
331 block = (item.action == "deny"); | 340 block = (item.action == "deny"); |
332 elseif item.type == "group" then | 341 elseif item.type == "group" then |
333 local roster = load_roster(node_, host_); | 342 local roster = load_roster(session.username, session.host); |
334 local groups = roster.groups; | 343 local groups = roster.groups; |
335 for _,group in ipairs(groups) do | 344 for _,group in ipairs(groups) do |
336 if group == item.value then | 345 if group == item.value then |
337 module:log("debug", "group matched."); | 346 module:log("debug", "group matched."); |
338 apply = true; | 347 apply = true; |
369 end | 378 end |
370 return; | 379 return; |
371 end | 380 end |
372 | 381 |
373 function preCheckIncoming(e) | 382 function preCheckIncoming(e) |
383 local session; | |
374 if e.stanza.attr.to ~= nil then | 384 if e.stanza.attr.to ~= nil then |
375 local node, host, resource = jid_split(e.stanza.attr.to); | 385 local node, host, resource = jid_split(e.stanza.attr.to); |
376 if node == nil or host == nil then | 386 if node == nil or host == nil then |
377 return; | 387 return; |
378 end | 388 end |
379 return checkIfNeedToBeBlocked(e, node, host); | 389 if resource == nil then |
390 local prio = 0; | |
391 local session_; | |
392 for _,session_ in ipairs(bare_sessions[node.."@"..host].sessions) do | |
393 if session_.priority > prio then | |
394 session = session_; | |
395 prio = session_.priority; | |
396 end | |
397 end | |
398 else | |
399 session = full_sessions[node.."@"..host.."/"..resource]; | |
400 end | |
401 return checkIfNeedToBeBlocked(e, session); | |
380 end | 402 end |
381 return; | 403 return; |
382 end | 404 end |
383 | 405 |
384 function preCheckOutgoing(e) | 406 function preCheckOutgoing(e) |
407 local session; | |
385 if e.stanza.attr.from ~= nil then | 408 if e.stanza.attr.from ~= nil then |
386 local node, host, resource = jid_split(e.stanza.attr.from); | 409 local node, host, resource = jid_split(e.stanza.attr.from); |
387 if node == nil or host == nil then | 410 if node == nil or host == nil then |
388 return; | 411 return; |
389 end | 412 end |
390 return checkIfNeedToBeBlocked(e, node, host); | 413 if resource == nil then |
414 local prio = 0; | |
415 local session_; | |
416 for _,session_ in ipairs(bare_sessions[node.."@"..host].sessions) do | |
417 if session_.priority > prio then | |
418 session = session_; | |
419 prio = session_.priority; | |
420 end | |
421 end | |
422 else | |
423 session = full_sessions[node.."@"..host.."/"..resource]; | |
424 end | |
425 return checkIfNeedToBeBlocked(e, session); | |
391 end | 426 end |
392 return; | 427 return; |
393 end | 428 end |
394 | 429 |
395 | 430 |