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
parents 35e74c1094a7
children 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