Parcourir la source

Adds domain name verification and multidomain support.

Adds option to enable/disable domain checking, disabled by default. Domain verification for multiple domains depends on new option muc_mapper_domain_base.
j8
damencho il y a 8 ans
Parent
révision
4bb51516bb
1 fichiers modifiés avec 78 ajouts et 5 suppressions
  1. 78
    5
      resources/prosody-plugins/token/util.lib.lua

+ 78
- 5
resources/prosody-plugins/token/util.lib.lua Voir le fichier

@@ -6,6 +6,7 @@ local have_async, async = pcall(require, "util.async");
6 6
 local hex = require "util.hex";
7 7
 local jwt = require "luajwtjitsi";
8 8
 local http = require "net.http";
9
+local jid = require "util.jid";
9 10
 local json = require "cjson";
10 11
 local path = require "util.paths";
11 12
 local sha256 = require "util.hashes".sha256;
@@ -37,6 +38,40 @@ function Util.new(module)
37 38
     self.asapKeyServer = module:get_option_string("asap_key_server");
38 39
     self.allowEmptyToken = module:get_option_boolean("allow_empty_token");
39 40
 
41
+    --[[
42
+        Multidomain can be supported in some deployments. In these deployments
43
+        there is a virtual conference muc, which address contains the subdomain
44
+        to use. Those deployments are accessible
45
+        by URL https://domain/subdomain.
46
+        Then the address of the room will be:
47
+        roomName@conference.subdomain.domain. This is like a virtual address
48
+        where there is only one muc configured by default with address:
49
+        conference.domain and the actual presentation of the room in that muc
50
+        component is [subdomain]roomName@conference.domain.
51
+        These setups relay on configuration 'muc_domain_base' which holds
52
+        the main domain and we use it to substract subdomains from the
53
+        virtual addresses.
54
+        The following confgurations are for multidomain setups and domain name
55
+        verification:
56
+     --]]
57
+
58
+    -- optional parameter for custom muc component prefix,
59
+    -- defaults to "conference"
60
+    self.muc_domain_prefix = module:get_option_string(
61
+        "muc_mapper_domain_prefix", "conference");
62
+    -- domain base, which is the main domain used in the deployment,
63
+    -- the main VirtualHost for the deployment
64
+    self.muc_domain_base = module:get_option_string("muc_mapper_domain_base");
65
+    -- The "real" MUC domain that we are proxying to
66
+    if self.muc_domain_base then
67
+        self.muc_domain = module:get_option_string(
68
+            "muc_mapper_domain",
69
+            self.muc_domain_prefix.."."..self.muc_domain_base);
70
+    end
71
+    -- whether domain name verification is enabled, by default it is disabled
72
+    self.enableDomainVerification = module:get_option_boolean(
73
+        "enable_domain_verification", false);
74
+
40 75
     if self.allowEmptyToken == true then
41 76
         module:log("warn", "WARNING - empty tokens allowed");
42 77
     end
@@ -139,12 +174,18 @@ function Util:verify_token(token)
139 174
         return nil, "'room' claim is missing";
140 175
     end
141 176
 
177
+    local audClaim = claims["aud"];
178
+    if audClaim == nil then
179
+        return nil, "'aud' claim is missing";
180
+    end
181
+
142 182
     return claims;
143 183
 end
144 184
 
145 185
 --- Verifies token and process needed values to be stored in the session.
146 186
 -- Stores in session the following values:
147 187
 -- session.jitsi_meet_room - the room name value from the token
188
+-- session.jitsi_meet_domain - the domain name value from the token
148 189
 -- @param session the current session
149 190
 -- @param token the token to verify
150 191
 -- @return false and error
@@ -183,15 +224,19 @@ function Util:process_and_verify_token(session, token)
183 224
     if claims ~= nil then
184 225
         -- Binds room name to the session which is later checked on MUC join
185 226
         session.jitsi_meet_room = claims["room"];
227
+        -- Binds domain name to the session
228
+        session.jitsi_meet_domain = claims["aud"];
186 229
         return true;
187 230
     else
188 231
         return false, "not-allowed", msg;
189 232
     end
190 233
 end
191 234
 
192
---- Verifies room name if necesarry.
235
+--- Verifies room name and domain if necesarry.
193 236
 -- Checks configs and if necessary checks the room name extracted from
237
+-- room_address against the one saved in the session when token was verified.
238
+-- Also verifies domain name from token against the domain in the room_address,
239
+-- if enableDomainVerification is enabled.
194 240
 -- @param session the current session
195 241
 -- @param room_address the whole room address as received
196 242
 -- @return returns true in case room was verified or there is no need to verify
@@ -205,7 +250,8 @@ function Util:verify_room(session, room_address)
205 250
         return true;
206 251
     end
207 252
 
208
-    local room = string.match(room_address, "^(%w+)@");
253
+    -- extract room name using all chars, except the not allowed ones
254
+    local room,_,_ = jid.split(room_address);
209 255
     if room == nil then
210 256
         log("error",
211 257
             "Unable to get name of the MUC room ? to: %s", room_address);
@@ -213,11 +259,37 @@ function Util:verify_room(session, room_address)
213 259
     end
214 260
 
215 261
     local auth_room = session.jitsi_meet_room;
216
-    if room ~= string.lower(auth_room) then
217
-        return false;
262
+    if not self.enableDomainVerification then
263
+        if room ~= string.lower(auth_room) then
264
+            return false;
265
+        end
266
+
267
+        return true;
218 268
     end
219 269
 
220
-    return true;
270
+    local room_address_to_verify = jid.bare(room_address);
271
+    -- parses bare room address, for multidomain expected format is:
272
+    -- [subdomain]roomName@conference.domain
273
+    local target_subdomain, target_room
274
+            = room_address_to_verify:match("^%[([^%]]+)%](.+)$");
275
+
276
+    local auth_domain = session.jitsi_meet_domain;
277
+    if target_subdomain then
278
+        -- from this point we depend on muc_domain_base,
279
+        -- deny access if option is missing
280
+        if not self.muc_domain_base then
281
+            module:log("warn", "No 'muc_domain_base' option set, denying access!");
282
+            return false;
283
+        end
284
+
285
+        return room_address_to_verify == jid.join(
286
+            "["..auth_domain.."]"..string.lower(auth_room), self.muc_domain);
287
+    else
288
+        -- we do not have a domain part (multidomain is not enabled)
289
+        -- verify with info from the token
290
+        return room_address_to_verify == jid.join(
291
+            string.lower(auth_room), self.muc_domain_prefix.."."..auth_domain);
292
+    end
221 293
 end
222 294
 
223 295
 return Util;

Chargement…
Annuler
Enregistrer