瀏覽代碼

Merge pull request #7508 from abora8x8/abora/vpass

Add pre and post validation for users that want to use their own publ…
j8
Aaron van Meerten 4 年之前
父節點
當前提交
5d012c24a7
No account linked to committer's email address

+ 19
- 2
resources/prosody-plugins/mod_auth_token.lua 查看文件

@@ -77,9 +77,18 @@ end
77 77
 function provider.get_sasl_handler(session)
78 78
 
79 79
 	local function get_username_from_token(self, message)
80
-        local res, error, reason = token_util:process_and_verify_token(session);
81 80
 
82
-        if (res == false) then
81
+        -- retrieve custom public key from server and save it on the session
82
+        local pre_event_result = prosody.events.fire_event("pre-jitsi-authentication-fetch-key", session);
83
+        if pre_event_result ~= nil and pre_event_result.res == false then
84
+            log("warn",
85
+                "Error verifying token on pre authentication stage:%s, reason:%s", pre_event_result.error, pre_event_result.reason);
86
+            session.auth_token = nil;
87
+            return pre_event_result.res, pre_event_result.error, pre_event_result.reason;
88
+        end
89
+
90
+        local res, error, reason = token_util:process_and_verify_token(session);
91
+        if res == false then
83 92
             log("warn",
84 93
                 "Error verifying token err:%s, reason:%s", error, reason);
85 94
             session.auth_token = nil;
@@ -102,6 +111,14 @@ function provider.get_sasl_handler(session)
102 111
             self.username = message;
103 112
         end
104 113
 
114
+        local post_event_result = prosody.events.fire_event("post-jitsi-authentication", session);
115
+        if post_event_result ~= nil and post_event_result.res == false then
116
+            log("warn",
117
+                "Error verifying token on post authentication stage :%s, reason:%s", post_event_result.error, post_event_result.reason);
118
+            session.auth_token = nil;
119
+            return post_event_result.res, post_event_result.error, post_event_result.reason;
120
+        end
121
+
105 122
         return res;
106 123
 	end
107 124
 

+ 10
- 58
resources/prosody-plugins/token/util.lib.lua 查看文件

@@ -5,17 +5,13 @@ local basexx = require "basexx";
5 5
 local have_async, async = pcall(require, "util.async");
6 6
 local hex = require "util.hex";
7 7
 local jwt = require "luajwtjitsi";
8
-local http = require "net.http";
9 8
 local jid = require "util.jid";
10 9
 local json_safe = require "cjson.safe";
11 10
 local path = require "util.paths";
12 11
 local sha256 = require "util.hashes".sha256;
13
-local timer = require "util.timer";
12
+local http_get_with_retry = module:require "util".http_get_with_retry;
14 13
 
15
-local http_timeout = 30;
16
-local http_headers = {
17
-    ["User-Agent"] = "Prosody ("..prosody.version.."; "..prosody.platform..")"
18
-};
14
+local nr_retries = 3;
19 15
 
20 16
 -- TODO: Figure out a less arbitrary default cache size.
21 17
 local cacheSize = module:get_option_number("jwt_pubkey_cache_size", 128);
@@ -131,65 +127,18 @@ function Util:get_public_key(keyId)
131 127
     if content == nil then
132 128
         -- If the key is not found in the cache.
133 129
         module:log("debug", "Cache miss for key: "..keyId);
134
-        local code;
135
-        local timeout_occurred;
136
-        local wait, done = async.waiter();
137
-
138 130
         local keyurl = path.join(self.asapKeyServer, hex.to(sha256(keyId))..'.pem');
139
-
140
-        local function cb(content_, code_, response_, request_)
141
-            if timeout_occurred == nil then
142
-                content, code = content_, code_;
143
-                if code == 200 or code == 204 then
144
-                    self.cache:set(keyId, content);
145
-                else
146
-                    module:log("warn", "Error on public key request: Code %s, Content %s",
147
-                    code_, content_);
148
-                end
149
-                done();
150
-            else
151
-                module:log("warn", "public key reply delivered after timeout from: %s",keyurl);
152
-            end
153
-        end
154
-
155
-        -- TODO: Is the done() call racey? Can we cancel this if the request
156
-        --       succeedes?
157
-        local function cancel()
158
-            -- TODO: This check is racey. Not likely to be a problem, but we should
159
-            --       still stick a mutex on content / code at some point.
160
-            if code == nil then
161
-                timeout_occurred = true;
162
-                module:log("warn", "Timeout %s seconds fetching public key from: %s",http_timeout,keyurl);
163
-                if http.destroy_request ~= nil then
164
-                    http.destroy_request(request);
165
-                end
166
-                done();
167
-            end
168
-        end
169
-
170 131
         module:log("debug", "Fetching public key from: "..keyurl);
171
-
172
-        -- We hash the key ID to work around some legacy behavior and make
173
-        -- deployment easier. It also helps prevent directory
174
-        -- traversal attacks (although path cleaning could have done this too).
175
-        local request = http.request(keyurl, {
176
-            headers = http_headers or {},
177
-            method = "GET"
178
-        }, cb);
179
-
180
-        timer.add_task(http_timeout, cancel);
181
-        wait();
182
-
183
-        if code == 200 or code == 204 then
184
-            return content;
132
+        content = http_get_with_retry(keyurl, nr_retries);
133
+        if content ~= nil then
134
+            self.cache:set(keyId, content);
185 135
         end
136
+        return content;
186 137
     else
187 138
         -- If the key is in the cache, use it.
188 139
         module:log("debug", "Cache hit for key: "..keyId);
189 140
         return content;
190 141
     end
191
-
192
-    return nil;
193 142
 end
194 143
 
195 144
 --- Verifies issuer part of token
@@ -301,7 +250,10 @@ function Util:process_and_verify_token(session, acceptedIssuers)
301 250
     end
302 251
 
303 252
     local pubKey;
304
-    if self.asapKeyServer and session.auth_token ~= nil then
253
+    if session.public_key then
254
+        module:log("debug","Public key was found on the session");
255
+        pubKey = session.public_key;
256
+    elseif self.asapKeyServer and session.auth_token ~= nil then
305 257
         local dotFirst = session.auth_token:find("%.");
306 258
         if not dotFirst then return nil, "Invalid token" end
307 259
         local header, err = json_safe.decode(basexx.from_url64(session.auth_token:sub(1,dotFirst-1)));

+ 75
- 0
resources/prosody-plugins/util.lib.lua 查看文件

@@ -1,5 +1,13 @@
1 1
 local jid = require "util.jid";
2
+local timer = require "util.timer";
3
+local http = require "net.http";
4
+
5
+local http_timeout = 30;
2 6
 local have_async, async = pcall(require, "util.async");
7
+local http_headers = {
8
+    ["User-Agent"] = "Prosody ("..prosody.version.."; "..prosody.platform..")"
9
+};
10
+
3 11
 local muc_domain_prefix
4 12
     = module:get_option_string("muc_mapper_domain_prefix", "conference");
5 13
 
@@ -208,6 +216,72 @@ function is_healthcheck_room(room_jid)
208 216
     return false;
209 217
 end
210 218
 
219
+-- Utility function to make an http get request and
220
+-- retry @param retry number of times
221
+-- @param url endpoint to be called
222
+-- @param retry nr of retries, if retry is
223
+-- nil there will be no retries
224
+-- @returns result of the http call or nil if
225
+-- the external call failed after the last retry
226
+function http_get_with_retry(url, retry)
227
+    local content, code;
228
+    local timeout_occurred;
229
+    local wait, done = async.waiter();
230
+    local function cb(content_, code_, response_, request_)
231
+        if timeout_occurred == nil then
232
+            code = code_;
233
+            if code == 200 or code == 204 then
234
+                module:log("debug", "External call was successful, content %s", content_);
235
+                content = content_
236
+            else
237
+                module:log("warn", "Error on public key request: Code %s, Content %s",
238
+                    code_, content_);
239
+            end
240
+            done();
241
+        else
242
+            module:log("warn", "External call reply delivered after timeout from: %s", url);
243
+        end
244
+    end
245
+
246
+    local function call_http()
247
+        return http.request(url, {
248
+            headers = http_headers or {},
249
+            method = "GET"
250
+        }, cb);
251
+    end
252
+
253
+    local request = call_http();
254
+
255
+    local function cancel()
256
+        -- TODO: This check is racey. Not likely to be a problem, but we should
257
+        --       still stick a mutex on content / code at some point.
258
+        if code == nil then
259
+            timeout_occurred = true;
260
+            module:log("warn", "Timeout %s seconds making the external call to: %s", http_timeout, url);
261
+            -- no longer present in prosody 0.11, so check before calling
262
+            if http.destroy_request ~= nil then
263
+                http.destroy_request(request);
264
+            end
265
+            if retry == nil then
266
+                module:log("debug", "External call failed and retry policy is not set");
267
+                done();
268
+            elseif retry ~= nil and retry < 1 then
269
+                module:log("debug", "External call failed after retry")
270
+                done();
271
+            else
272
+                module:log("debug", "External call failed, retry nr %s", retry)
273
+                retry = retry - 1;
274
+                request = call_http()
275
+                return http_timeout;
276
+            end
277
+        end
278
+    end
279
+    timer.add_task(http_timeout, cancel);
280
+    wait();
281
+
282
+    return content;
283
+end
284
+
211 285
 return {
212 286
     is_feature_allowed = is_feature_allowed;
213 287
     is_healthcheck_room = is_healthcheck_room;
@@ -217,4 +291,5 @@ return {
217 291
     room_jid_split_subdomain = room_jid_split_subdomain;
218 292
     internal_room_jid_match_rewrite = internal_room_jid_match_rewrite;
219 293
     update_presence_identity = update_presence_identity;
294
+    http_get_with_retry = http_get_with_retry;
220 295
 };

Loading…
取消
儲存