mod_privilege/mod_privilege.lua
author Matthew Wild <mwild1@gmail.com>
Thu, 07 Dec 2023 15:46:50 +0000
changeset 5791 e79f9dec35c0
parent 4998 cce12a660b98
child 5877 a88c43de648c
permissions -rw-r--r--
mod_c2s_conn_throttle: Reduce log level from error->info Our general policy is that "error" should never be triggerable by remote entities, and that it is always about something that requires admin intervention. This satisfies neither condition. The "warn" level can be used for unexpected events/behaviour triggered by remote entities, and this could qualify. However I don't think failed auth attempts are unexpected enough. I selected "info" because it is what is also used for other notable session lifecycle events.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
     1
-- XEP-0356 (Privileged Entity)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
     2
-- Copyright (C) 2015-2022 Jérôme Poisson
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
     3
--
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
     4
-- This module is MIT/X11 licensed. Please see the
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
     5
-- COPYING file in the source package for more information.
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
     6
--
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
     7
-- Some parts come from mod_remote_roster (module by Waqas Hussain and Kim Alvefur, see https://code.google.com/p/prosody-modules/)
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
     8
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
     9
-- TODO: manage external <presence/> (for "roster" presence permission) when the account with the roster is offline
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    10
1994
c4da3d9f212d mod_privilege: fixed imports, using "/" instead of "." was causing caching issues
Goffi <goffi@goffi.org>
parents: 1993
diff changeset
    11
local jid = require("util.jid")
c4da3d9f212d mod_privilege: fixed imports, using "/" instead of "." was causing caching issues
Goffi <goffi@goffi.org>
parents: 1993
diff changeset
    12
local set = require("util.set")
c4da3d9f212d mod_privilege: fixed imports, using "/" instead of "." was causing caching issues
Goffi <goffi@goffi.org>
parents: 1993
diff changeset
    13
local st = require("util.stanza")
c4da3d9f212d mod_privilege: fixed imports, using "/" instead of "." was causing caching issues
Goffi <goffi@goffi.org>
parents: 1993
diff changeset
    14
local roster_manager = require("core.rostermanager")
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    15
local usermanager_user_exists = require "core.usermanager".user_exists
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
    16
local hosts = prosody.hosts
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    17
local full_sessions = prosody.full_sessions
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
    18
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
    19
local priv_session = module:shared("/*/privilege/session")
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
    20
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    21
if priv_session.connected_cb == nil then
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    22
    -- set used to have connected event listeners
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    23
    -- which allows a host to react on events from
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    24
    -- other hosts
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    25
    priv_session.connected_cb = set.new()
1667
ca07a6ada631 mod_privilege: presence permission configuration check + use global set to know privileged entities to advertise
Goffi <goffi@goffi.org>
parents: 1666
diff changeset
    26
end
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    27
local connected_cb = priv_session.connected_cb
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    28
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    29
-- the folowing sets are used to forward presence stanza
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    30
-- the folowing sets are used to forward presence stanza
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    31
local presence_man_ent = set.new()
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
    32
local presence_roster = set.new()
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    33
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    34
local _ALLOWED_ROSTER = set.new({'none', 'get', 'set', 'both'})
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    35
local _ROSTER_GET_PERM = set.new({'get', 'both'})
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    36
local _ROSTER_SET_PERM = set.new({'set', 'both'})
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    37
local _ALLOWED_MESSAGE = set.new({'none', 'outgoing'})
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    38
local _ALLOWED_PRESENCE = set.new({'none', 'managed_entity', 'roster'})
1669
746d94f37a4c mod_privilege: presence already known are advertised to privileged entity (for "maneger_entity" permission only so far)
Goffi <goffi@goffi.org>
parents: 1668
diff changeset
    39
local _PRESENCE_MANAGED = set.new({'managed_entity', 'roster'})
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    40
local _TO_CHECK = {roster=_ALLOWED_ROSTER, message=_ALLOWED_MESSAGE, presence=_ALLOWED_PRESENCE}
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    41
local _PRIV_ENT_NS = 'urn:xmpp:privilege:2'
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
    42
local _FORWARDED_NS = 'urn:xmpp:forward:0'
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    43
local _MODULE_HOST = module:get_host()
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    44
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    45
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    46
module:log("debug", "Loading privileged entity module ")
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    47
1667
ca07a6ada631 mod_privilege: presence permission configuration check + use global set to know privileged entities to advertise
Goffi <goffi@goffi.org>
parents: 1666
diff changeset
    48
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
    49
--> Permissions management <--
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    50
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    51
local config_priv = module:get_option("privileged_entities", {})
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    52
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    53
local function get_session_privileges(session, host)
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    54
    if not session.privileges then return nil end
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    55
    return session.privileges[host]
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    56
end
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    57
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
    58
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
    59
local function advertise_perm(session, to_jid, perms)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    60
    -- send <message/> stanza to advertise permissions
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    61
    -- as expained in § 4.2
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    62
    local message = st.message({from=module.host, to=to_jid})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    63
                      :tag("privilege", {xmlns=_PRIV_ENT_NS})
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
    64
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    65
    for _, perm in pairs({'roster', 'message', 'presence'}) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    66
        if perms[perm] then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    67
            message:tag("perm", {access=perm, type=perms[perm]}):up()
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    68
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    69
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    70
    local iq_perm = perms["iq"]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    71
    if iq_perm ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    72
        message:tag("perm", {access="iq"})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    73
        for namespace, ns_perm in pairs(iq_perm) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    74
                local perm_type
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    75
                if ns_perm.set and ns_perm.get then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    76
                    perm_type = "both"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    77
                elseif ns_perm.set then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    78
                    perm_type = "set"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    79
                elseif ns_perm.get then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    80
                    perm_type = "get"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    81
                else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    82
                    perm_type = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    83
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    84
                message:tag("namespace", {ns=namespace, type=perm_type})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    85
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    86
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    87
    session.send(message)
1666
d440a22fa0af mod_privilege: advertise_perm method now use session.send instead of module:send to avoid to go back in hook
Goffi <goffi@goffi.org>
parents: 1665
diff changeset
    88
end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
    89
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
    90
local function set_presence_perm_set(to_jid, perms)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    91
    -- fill the presence sets according to perms
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    92
    if _PRESENCE_MANAGED:contains(perms.presence) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    93
        presence_man_ent:add(to_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    94
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    95
    if perms.presence == 'roster' then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    96
        presence_roster:add(to_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
    97
    end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    98
end
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
    99
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   100
local function advertise_presences(session, to_jid, perms)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   101
    -- send presence status for already connected entities
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   102
    -- as explained in § 7.1
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   103
    -- people in roster are probed only for active sessions
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   104
    -- TODO: manage roster load for inactive sessions
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   105
    if not perms.presence then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   106
    local to_probe = {}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   107
    for _, user_session in pairs(full_sessions) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   108
        if user_session.presence and _PRESENCE_MANAGED:contains(perms.presence) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   109
            local presence = st.clone(user_session.presence)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   110
            presence.attr.to = to_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   111
            module:log("debug", "sending current presence for "..tostring(user_session.full_jid))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   112
            session.send(presence)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   113
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   114
        if perms.presence == "roster" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   115
            -- we reset the cache to avoid to miss a presence that just changed
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   116
            priv_session.last_presence = nil
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
   117
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   118
            if user_session.roster then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   119
                local bare_jid = jid.bare(user_session.full_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   120
                for entity, item in pairs(user_session.roster) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   121
                    if entity~=false and entity~="pending" and (item.subscription=="both" or item.subscription=="to") then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   122
                        local _, host = jid.split(entity)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   123
                        if not hosts[host] then -- we don't probe jid from hosts we manage
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   124
                            -- using a table with entity as key avoid probing several time the same one
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   125
                            to_probe[entity] = bare_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   126
                        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   127
                    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   128
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   129
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   130
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   131
    end
1671
c81a981479d4 mod_privilege: implemented probing of rosters items (for existing sessions only) on connection + use a globally shared table for priv_session (and fixed last_presence)
Goffi <goffi@goffi.org>
parents: 1670
diff changeset
   132
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   133
    -- now we probe peoples for "roster" presence permission
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   134
    for probe_to, probe_from in pairs(to_probe) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   135
        module:log("debug", "probing presence for %s (on behalf of %s)", tostring(probe_to), tostring(probe_from))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   136
        local probe = st.presence({from=probe_from, to=probe_to, type="probe"})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   137
        prosody.core_route_stanza(nil, probe)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   138
    end
1669
746d94f37a4c mod_privilege: presence already known are advertised to privileged entity (for "maneger_entity" permission only so far)
Goffi <goffi@goffi.org>
parents: 1668
diff changeset
   139
end
746d94f37a4c mod_privilege: presence already known are advertised to privileged entity (for "maneger_entity" permission only so far)
Goffi <goffi@goffi.org>
parents: 1668
diff changeset
   140
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   141
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   142
local function on_auth(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   143
    -- Check if entity is privileged according to configuration,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   144
    -- and set session.privileges accordingly
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   145
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   146
    local session = event.session
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   147
    local bare_jid = jid.join(session.username, session.host)
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   148
    if not session.privileges then
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   149
        session.privileges = {}
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   150
    end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   151
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   152
    local conf_ent_priv = config_priv[bare_jid]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   153
    local ent_priv = {}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   154
    if conf_ent_priv ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   155
        module:log("debug", "Entity is privileged")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   156
        for perm_type, allowed_values in pairs(_TO_CHECK) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   157
            local value = conf_ent_priv[perm_type]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   158
            if value ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   159
                if not allowed_values:contains(value) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   160
                    module:log('warn', 'Invalid value for '..perm_type..' privilege: ['..value..']')
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   161
                    module:log('warn', 'Setting '..perm_type..' privilege to none')
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   162
                    ent_priv[perm_type] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   163
                elseif value == 'none' then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   164
                    ent_priv[perm_type] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   165
                else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   166
                    ent_priv[perm_type] = value
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   167
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   168
            else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   169
                ent_priv[perm_type] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   170
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   171
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   172
        -- extra checks for presence permission
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   173
        if ent_priv.presence == 'roster' and not _ROSTER_GET_PERM:contains(ent_priv.roster) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   174
            module:log("warn", "Can't allow roster presence privilege without roster \"get\" privilege")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   175
            module:log("warn", "Setting presence permission to none")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   176
            ent_priv.presence = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   177
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   178
        -- iq permission
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   179
        local iq_perm_config = conf_ent_priv["iq"]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   180
        if iq_perm_config ~= nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   181
            local iq_perm = {}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   182
            ent_priv["iq"] = iq_perm
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   183
            for ns, ns_perm_config in pairs(iq_perm_config) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   184
                iq_perm[ns] = {
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   185
                    ["get"] = ns_perm_config == "get" or ns_perm_config == "both",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   186
                    ["set"] = ns_perm_config == "set" or ns_perm_config == "both"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   187
                }
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   188
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   189
        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   190
            ent_priv["iq"] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   191
        end
1667
ca07a6ada631 mod_privilege: presence permission configuration check + use global set to know privileged entities to advertise
Goffi <goffi@goffi.org>
parents: 1666
diff changeset
   192
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   193
        if session.type == "component" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   194
            -- we send the message stanza only for component
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   195
            -- it will be sent at first <presence/> for other entities
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   196
            advertise_perm(session, bare_jid, ent_priv)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   197
            set_presence_perm_set(bare_jid, ent_priv)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   198
            advertise_presences(session, bare_jid, ent_priv)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   199
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   200
    end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   201
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   202
    session.privileges[_MODULE_HOST] = ent_priv
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   203
end
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   204
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   205
local function on_presence(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   206
    -- Permission are already checked at this point,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   207
    -- we only advertise them to the entity
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   208
    local session = event.origin
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   209
    local session_privileges = get_session_privileges(session, _MODULE_HOST)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   210
    if session_privileges then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   211
        advertise_perm(session, session.full_jid, session_privileges)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   212
        set_presence_perm_set(session.full_jid, session_privileges)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   213
        advertise_presences(session, session.full_jid, session_privileges)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   214
    end
1663
495a093798eb mod_privilege: added permissions notification on initial presence for entities which are not components
Goffi <goffi@goffi.org>
parents: 1662
diff changeset
   215
end
495a093798eb mod_privilege: added permissions notification on initial presence for entities which are not components
Goffi <goffi@goffi.org>
parents: 1662
diff changeset
   216
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   217
local function on_component_auth(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   218
    -- react to component-authenticated event from this host
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   219
    -- and call the on_auth methods from all other hosts
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   220
    -- needed for the component to get delegations advertising
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   221
    for callback in connected_cb:items() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   222
        callback(event)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   223
    end
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   224
end
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   225
1779
0d78bb31348e mod_privilege: fixed bad calling of on_auth for components
Goffi <goffi@goffi.org>
parents: 1712
diff changeset
   226
if module:get_host_type() ~= "component" then
0d78bb31348e mod_privilege: fixed bad calling of on_auth for components
Goffi <goffi@goffi.org>
parents: 1712
diff changeset
   227
    connected_cb:add(on_auth)
0d78bb31348e mod_privilege: fixed bad calling of on_auth for components
Goffi <goffi@goffi.org>
parents: 1712
diff changeset
   228
end
1661
7116bc76663b mod_privilege: mod_privilege first draft
Goffi <goffi@goffi.org>
parents:
diff changeset
   229
module:hook('authentication-success', on_auth)
1712
ad7afcf86131 mod_privilege: fixed bad handling of presence permissions / component authentication between different hosts
Goffi <goffi@goffi.org>
parents: 1711
diff changeset
   230
module:hook('component-authenticated', on_component_auth)
1663
495a093798eb mod_privilege: added permissions notification on initial presence for entities which are not components
Goffi <goffi@goffi.org>
parents: 1662
diff changeset
   231
module:hook('presence/initial', on_presence)
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   232
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   233
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   234
--> roster permission <--
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   235
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   236
-- get
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   237
module:hook("iq-get/bare/jabber:iq:roster:query", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   238
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   239
    if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   240
        -- we don't want stanzas addressed to /self
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   241
        return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   242
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   243
    local node, host = jid.split(stanza.attr.to)
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   244
    local session_privileges = get_session_privileges(session, host)
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   245
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   246
    if session_privileges and _ROSTER_GET_PERM:contains(session_privileges.roster) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   247
        module:log("debug", "Roster get from allowed privileged entity received")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   248
        -- following code is adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   249
        local roster = roster_manager.load_roster(node, host)
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   250
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   251
        local reply = st.reply(stanza):query("jabber:iq:roster")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   252
        for entity_jid, item in pairs(roster) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   253
            if entity_jid and entity_jid ~= "pending" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   254
                reply:tag("item", {
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   255
                    jid = entity_jid,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   256
                    subscription = item.subscription,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   257
                    ask = item.ask,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   258
                    name = item.name,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   259
                })
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   260
                for group in pairs(item.groups) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   261
                    reply:tag("group"):text(group):up()
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   262
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   263
                reply:up(); -- move out from item
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   264
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   265
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   266
        -- end of code adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   267
        session.send(reply)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   268
    else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   269
        module:log("warn", "Entity "..tostring(session.full_jid).." try to get roster without permission")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   270
        session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   271
    end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   272
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   273
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   274
end)
1662
1146cb4493a9 mod_privilege: roster get permission implemented
Goffi <goffi@goffi.org>
parents: 1661
diff changeset
   275
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   276
-- set
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   277
module:hook("iq-set/bare/jabber:iq:roster:query", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   278
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   279
    if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   280
        -- we don't want stanzas addressed to /self
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   281
        return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   282
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   283
    local from_node, from_host = jid.split(stanza.attr.to)
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   284
    local session_privileges = get_session_privileges(session, from_host)
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   285
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   286
    if session_privileges and _ROSTER_SET_PERM:contains(session_privileges.roster) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   287
        module:log("debug", "Roster set from allowed privileged entity received")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   288
        -- following code is adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   289
        if not(usermanager_user_exists(from_node, from_host)) then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   290
        local roster = roster_manager.load_roster(from_node, from_host)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   291
        if not(roster) then return; end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   292
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   293
        local query = stanza.tags[1]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   294
        for _, item in ipairs(query.tags) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   295
            if item.name == "item"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   296
                and item.attr.xmlns == "jabber:iq:roster" and item.attr.jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   297
                    -- Protection against overwriting roster.pending, until we move it
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   298
                and item.attr.jid ~= "pending" then
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   299
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   300
                local item_jid = jid.prep(item.attr.jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   301
                local _, host, resource = jid.split(item_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   302
                if not resource then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   303
                    if item_jid ~= stanza.attr.to then -- not self-item_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   304
                        if item.attr.subscription == "remove" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   305
                            local r_item = roster[item_jid]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   306
                            if r_item then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   307
                                roster[item_jid] = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   308
                                if roster_manager.save_roster(from_node, from_host, roster) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   309
                                    session.send(st.reply(stanza))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   310
                                    roster_manager.roster_push(from_node, from_host, item_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   311
                                else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   312
                                    roster[item_jid] = item
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   313
                                    session.send(st.error_reply(stanza, "wait", "internal-server-error", "Unable to save roster"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   314
                                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   315
                            else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   316
                                session.send(st.error_reply(stanza, "modify", "item-not-found"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   317
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   318
                        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   319
                            local subscription = item.attr.subscription
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   320
                            if subscription ~= "both" and subscription ~= "to" and subscription ~= "from" and subscription ~= "none" then -- TODO error on invalid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   321
                                subscription = roster[item_jid] and roster[item_jid].subscription or "none"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   322
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   323
                            local r_item = {name = item.attr.name, groups = {}}
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   324
                            if r_item.name == "" then r_item.name = nil; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   325
                            r_item.subscription = subscription
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   326
                            if subscription ~= "both" and subscription ~= "to" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   327
                                r_item.ask = roster[item_jid] and roster[item_jid].ask
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   328
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   329
                            for _, child in ipairs(item) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   330
                                if child.name == "group" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   331
                                    local text = table.concat(child)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   332
                                    if text and text ~= "" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   333
                                        r_item.groups[text] = true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   334
                                    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   335
                                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   336
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   337
                            local olditem = roster[item_jid]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   338
                            roster[item_jid] = r_item
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   339
                            if roster_manager.save_roster(from_node, from_host, roster) then -- Ok, send success
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   340
                                session.send(st.reply(stanza))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   341
                                -- and push change to all resources
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   342
                                roster_manager.roster_push(from_node, from_host, item_jid)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   343
                            else -- Adding to roster failed
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   344
                                roster[item_jid] = olditem
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   345
                                session.send(st.error_reply(stanza, "wait", "internal-server-error", "Unable to save roster"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   346
                            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   347
                        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   348
                    else -- Trying to add self to roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   349
                        session.send(st.error_reply(stanza, "cancel", "not-allowed"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   350
                    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   351
                else -- Invalid JID added to roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   352
                    module:log("warn", "resource: %s , host: %s", tostring(resource), tostring(host))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   353
                    session.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME what's the correct error?
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   354
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   355
            else -- Roster set didn't include a single item, or its name wasn't  'item'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   356
                session.send(st.error_reply(stanza, "modify", "bad-request"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   357
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   358
        end -- for loop end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   359
        -- end of code adapted from mod_remote_roster
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   360
    else -- The permission is not granted
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   361
        module:log("warn", "Entity "..tostring(session.full_jid).." try to set roster without permission")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   362
        session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   363
    end
1664
d1072db4db44 mod_privilege: implemented roster set privilege
Goffi <goffi@goffi.org>
parents: 1663
diff changeset
   364
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   365
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   366
end)
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   367
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   368
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   369
--> message permission <--
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   370
3397
7454274ead2f mod_privilege: fixed routing issue with message permission:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
   371
local function clean_xmlns(node)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   372
    -- Recursively remove "jabber:client" attribute from node.
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   373
    -- In Prosody internal routing, xmlns should not be set.
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   374
    -- Keeping xmlns would lead to issues like mod_smacks ignoring the outgoing stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   375
    -- so we remove all xmlns attributes with a value of "jabber:client"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   376
    if node.attr.xmlns == 'jabber:client' then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   377
        for childnode in node:childtags() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   378
            clean_xmlns(childnode)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   379
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   380
        node.attr.xmlns = nil
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   381
    end
3397
7454274ead2f mod_privilege: fixed routing issue with message permission:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
   382
end
7454274ead2f mod_privilege: fixed routing issue with message permission:
Goffi <goffi@goffi.org>
parents: 2072
diff changeset
   383
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   384
module:hook("message/host", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   385
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   386
    local privilege_elt = stanza:get_child('privilege', _PRIV_ENT_NS)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   387
    if privilege_elt==nil then return; end
1959
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   388
    local _, to_host = jid.split(stanza.attr.to)
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   389
    local session_privileges = get_session_privileges(session, to_host)
f719d5e6c627 mod_privilege: fixed session.privilege overwritting when multiple hosts are activated + fixed roster permission check on presence permission.
Goffi <goffi@goffi.org>
parents: 1779
diff changeset
   390
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   391
    if session_privileges and session_privileges.message=="outgoing" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   392
        if #privilege_elt.tags==1 and privilege_elt.tags[1].name == "forwarded"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   393
            and privilege_elt.tags[1].attr.xmlns==_FORWARDED_NS then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   394
            local message_elt = privilege_elt.tags[1]:get_child('message', 'jabber:client')
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   395
            if message_elt ~= nil then
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   396
                local username, from_host, from_resource = jid.split(message_elt.attr.from)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   397
                if from_resource == nil and hosts[from_host] then -- we only accept bare jids from one of the server hosts
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   398
                    clean_xmlns(message_elt);  -- needed do to proper routing
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   399
                    local session = {
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   400
                        username = username;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   401
                        host = from_host;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   402
                        type = "c2s";
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   403
                        log = module._log;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   404
                    }
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   405
                    -- at this point everything should be alright, we can send the message
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   406
                    prosody.core_post_stanza(session, message_elt, true)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   407
                else -- trying to send a message from a forbidden entity
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   408
                    module:log("warn", "Entity "..tostring(session.full_jid).." try to send a message from "..tostring(message_elt.attr.from))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   409
                    session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   410
                end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   411
            else -- incorrect message child
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   412
                session.send(st.error_reply(stanza, "modify", "bad-request", "invalid forwarded <message/> element"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   413
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   414
        else -- incorrect forwarded child
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   415
            session.send(st.error_reply(stanza, "modify", "bad-request", "invalid <forwarded/> element"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   416
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   417
    else -- The permission is not granted
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   418
        module:log("warn", "Entity "..tostring(session.full_jid).." try to send message without permission")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   419
        session.send(st.error_reply(stanza, 'auth', 'forbidden'))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   420
    end
1665
69aa2b54ba8a mod_privilege: implemented message privilege
Goffi <goffi@goffi.org>
parents: 1664
diff changeset
   421
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   422
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   423
end)
1668
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   424
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   425
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   426
--> presence permission <--
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   427
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   428
local function same_tags(tag1, tag2)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   429
    -- check if two tags are equivalent
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   430
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   431
    if tag1.name ~= tag2.name then return false; end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   432
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   433
    if #tag1 ~= #tag2 then return false; end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   434
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   435
    for name, value in pairs(tag1.attr) do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   436
        if tag2.attr[name] ~= value then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   437
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   438
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   439
    for i=1,#tag1 do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   440
        if type(tag1[i]) == "string" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   441
            if tag1[i] ~= tag2[i] then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   442
        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   443
            if not same_tags(tag1[i], tag2[i]) then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   444
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   445
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   446
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   447
    return true
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   448
end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   449
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   450
local function same_presences(presence1, presence2)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   451
    -- check that 2 <presence/> stanzas are equivalent (except for "to" attribute)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   452
    -- /!\ if the id change but everything else is equivalent, this method return false
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   453
    -- this behaviour may change in the future
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   454
    if presence1.attr.from ~= presence2.attr.from or presence1.attr.id ~= presence2.attr.id
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   455
        or presence1.attr.type ~= presence2.attr.type then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   456
        return false
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   457
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   458
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   459
    if presence1.attr.id and presence1.attr.id == presence2.attr.id then return true; end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   460
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   461
    if #presence1 ~= #presence2 then return false; end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   462
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   463
    for i=1,#presence1 do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   464
        if type(presence1[i]) == "string" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   465
            if presence1[i] ~= presence2[i] then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   466
        else
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   467
            if not same_tags(presence1[i], presence2[i]) then return false; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   468
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   469
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   470
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   471
    return true
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   472
end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   473
1711
64b3d1eb0cfe mod_privilege: fixed various issues reported by luacheck
Goffi <goffi@goffi.org>
parents: 1671
diff changeset
   474
local function forward_presence(presence, to_jid)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   475
    local presence_fwd = st.clone(presence)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   476
    presence_fwd.attr.to = to_jid
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   477
    module:log("debug", "presence forwarded to "..to_jid..": "..tostring(presence_fwd))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   478
    module:send(presence_fwd)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   479
    -- cache used to avoid to send several times the same stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   480
    priv_session.last_presence = presence
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   481
end
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   482
1668
6bdcb1418029 mod_privilege: implemented "managed_entity" presence
Goffi <goffi@goffi.org>
parents: 1667
diff changeset
   483
module:hook("presence/bare", function(event)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   484
    if presence_man_ent:empty() and presence_roster:empty() then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   485
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   486
    local stanza = event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   487
    if stanza.attr.type == nil or stanza.attr.type == "unavailable" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   488
        if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   489
            for entity in presence_man_ent:items() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   490
                if stanza.attr.from ~= entity then forward_presence(stanza, entity); end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   491
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   492
        else -- directed presence
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   493
            -- we ignore directed presences from our own host, as we already have them
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   494
            local _, from_host = jid.split(stanza.attr.from)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   495
            if hosts[from_host] then return; end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   496
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   497
            -- we don't send several time the same presence, as recommended in §7 #2
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   498
            if priv_session.last_presence and same_presences(priv_session.last_presence, stanza) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   499
               return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   500
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   501
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   502
            for entity in presence_roster:items() do
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   503
                if stanza.attr.from ~= entity then forward_presence(stanza, entity); end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   504
            end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   505
        end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   506
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   507
end, 150)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   508
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   509
--> IQ permission <--
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   510
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   511
module:hook("iq/bare/".._PRIV_ENT_NS..":privileged_iq", function(event)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   512
    local session, stanza = event.origin, event.stanza
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   513
    if not stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   514
        -- we don't want stanzas addressed to /self
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   515
        return
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   516
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   517
    local from_node, from_host, from_resource = jid.split(stanza.attr.to)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   518
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   519
    if from_resource ~= nil or not usermanager_user_exists(from_node, from_host) then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   520
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   521
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   522
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   523
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   524
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   525
                "wrapping <IQ> stanza recipient must be a bare JID of a local user"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   526
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   527
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   528
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   529
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   530
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   531
    local session_privileges = get_session_privileges(session, from_host)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   532
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   533
    if session_privileges == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   534
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   535
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   536
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   537
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   538
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   539
                "no privilege granted"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   540
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   541
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   542
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   543
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   544
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   545
    local iq_privileges = session_privileges["iq"]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   546
    if iq_privileges == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   547
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   548
            session.send(st.error_reply(stanza, "auth", "forbidden", "you are not allowed to send privileged <IQ> stanzas"))
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   549
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   550
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   551
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   552
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   553
    local privileged_iq = stanza:get_child("privileged_iq", _PRIV_ENT_NS)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   554
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   555
    local wrapped_iq = privileged_iq.tags[1]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   556
    if wrapped_iq == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   557
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   558
            st.error_reply(stanza, "auth", "forbidden", "missing <IQ> stanza to send")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   559
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   560
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   561
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   562
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   563
    if wrapped_iq.attr.xmlns ~= "jabber:client" then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   564
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   565
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   566
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   567
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   568
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   569
                'wrapped <IQ> must have a xmlns of "jabber:client"'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   570
                )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   571
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   572
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   573
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   574
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   575
    clean_xmlns(wrapped_iq)
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   576
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   577
    if #wrapped_iq.tags ~= 1 then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   578
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   579
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   580
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   581
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   582
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   583
                'invalid payload in wrapped <IQ>'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   584
                )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   585
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   586
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   587
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   588
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   589
    local payload = wrapped_iq.tags[1]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   590
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   591
    local priv_ns = payload.attr.xmlns
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   592
    if priv_ns == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   593
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   594
            st.error_reply(stanza, "auth", "forbidden", "xmlns not set in privileged <IQ>")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   595
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   596
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   597
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   598
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   599
    local ns_perms = iq_privileges[priv_ns]
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   600
    local iq_type = stanza.attr.type
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   601
    if ns_perms == nil or iq_type == nil or not ns_perms[iq_type] then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   602
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   603
            session.send(st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   604
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   605
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   606
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   607
                "you are not allowed to send privileged <IQ> stanzas of this type and namespace")
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   608
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   609
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   610
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   611
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   612
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   613
    if wrapped_iq.attr.from ~= nil and wrapped_iq.attr.from ~= stanza.attr.to then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   614
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   615
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   616
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   617
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   618
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   619
                'wrapped <IQ> "from" attribute is inconsistent with main <IQ> "to" attribute'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   620
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   621
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   622
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   623
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   624
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   625
    wrapped_iq.attr.from = stanza.attr.to
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   626
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   627
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   628
    if wrapped_iq.attr.type ~= iq_type then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   629
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   630
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   631
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   632
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   633
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   634
                'invalid wrapped <IQ>: type mismatch'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   635
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   636
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   637
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   638
    end
1670
0b1b4b7d5fe0 mod_privilege: implemented "roster" presence permission
Goffi <goffi@goffi.org>
parents: 1669
diff changeset
   639
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   640
    if wrapped_iq.attr.id == nil then
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   641
        session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   642
            st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   643
                stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   644
                "auth",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   645
                "forbidden",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   646
                'invalid wrapped <IQ>: missing "id" attribute'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   647
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   648
        )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   649
        return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   650
    end
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   651
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   652
    -- at this point, wrapped_iq is considered valid, and privileged entity is allowed to send it
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   653
    local username, from_host, _ = jid.split(wrapped_iq.attr.from)
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   654
    local newsession = {
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   655
        username = username;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   656
        host = from_host;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   657
	    full_jid = stanza.attr.to;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   658
        type = "c2s";
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   659
        log = module._log;
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   660
    }
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   661
4998
cce12a660b98 mod_privilege: process entity IQs (credit to adx) and messages with a constructed entity session
Nicoco <nicoco@nicoco.fr>
parents: 4941
diff changeset
   662
    module:send_iq(wrapped_iq,newsession)
4941
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   663
        :next(function (response)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   664
            local reply = st.reply(stanza);
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   665
            response.stanza.attr.xmlns = 'jabber:client'
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   666
            reply:tag("privilege", {xmlns = _PRIV_ENT_NS})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   667
            :tag("forwarded", {xmlns = _FORWARDED_NS})
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   668
            :add_child(response.stanza)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   669
            session.send(reply)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   670
        end,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   671
        function(response)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   672
            module:log("error", "Error while sending privileged <IQ>: %s", response);
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   673
            session.send(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   674
                st.error_reply(
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   675
                    stanza,
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   676
                    "cancel",
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   677
                    "internal-server-error"
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   678
                )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   679
            )
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   680
        end)
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   681
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   682
    return true
3ddab718f717 mod_privilege: update to v0.4:
Goffi <goffi@goffi.org>
parents: 3397
diff changeset
   683
end)