From 6d3d15a64b7d82cb7abf04dc0d567dbea94b21aa Mon Sep 17 00:00:00 2001 From: damencho Date: Mon, 15 Jun 2020 11:55:21 -0500 Subject: [PATCH] feat: Adds an option to validate a recording token. --- .../prosody-plugins/mod_filter_iq_jibri.lua | 39 +++++++++++++++---- resources/prosody-plugins/token/util.lib.lua | 23 +++++++---- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/resources/prosody-plugins/mod_filter_iq_jibri.lua b/resources/prosody-plugins/mod_filter_iq_jibri.lua index c211de6d30..f61b539ad1 100644 --- a/resources/prosody-plugins/mod_filter_iq_jibri.lua +++ b/resources/prosody-plugins/mod_filter_iq_jibri.lua @@ -1,5 +1,8 @@ local st = require "util.stanza"; local is_feature_allowed = module:require "util".is_feature_allowed; +local token_util = module:require "token/util".new(module); + +local accepted_rayo_iq_token_issuers = module:get_option_array("accepted_rayo_iq_token_issuers"); -- filters jibri iq in case of requested from jwt authenticated session that -- has features in the user context, but without feature for recording @@ -11,15 +14,37 @@ module:hook("pre-iq/full", function(event) local session = event.origin; local token = session.auth_token; - if jibri.attr.action == 'start' - and (token == nil + if jibri.attr.action == 'start' then + local errorReason; + if accepted_rayo_iq_token_issuers then + local iq_token = jibri.attr.token; + if iq_token then + local session = {}; + session.auth_token = iq_token; + local verified, reason = token_util:process_and_verify_token( + session, accepted_rayo_iq_token_issuers); + if verified then + return nil; -- this will proceed with dispatching the stanza + end + errorReason = reason; + else + errorReason = 'No recording token provided'; + end + + module:log("warn", "not a valid token %s", tostring(errorReason)); + session.send(st.error_reply(stanza, "auth", "forbidden")); + return true; + end + + if token == nil or not is_feature_allowed(session, - (jibri.attr.recording_mode == 'file' and 'recording' or 'livestreaming')) + (jibri.attr.recording_mode == 'file' and 'recording' or 'livestreaming') ) then - module:log("info", - "Filtering jibri start recording, stanza:%s", tostring(stanza)); - session.send(st.error_reply(stanza, "auth", "forbidden")); - return true; + module:log("info", + "Filtering jibri start recording, stanza:%s", tostring(stanza)); + session.send(st.error_reply(stanza, "auth", "forbidden")); + return true; + end end end end diff --git a/resources/prosody-plugins/token/util.lib.lua b/resources/prosody-plugins/token/util.lib.lua index 72af078dbe..4c53df85b8 100644 --- a/resources/prosody-plugins/token/util.lib.lua +++ b/resources/prosody-plugins/token/util.lib.lua @@ -159,9 +159,10 @@ end --- Verifies issuer part of token -- @param 'iss' claim from the token to verify +-- @param 'acceptedIssuers' list of issuers to check -- @return nil and error string or true for accepted claim -function Util:verify_issuer(issClaim) - for i, iss in ipairs(self.acceptedIssuers) do +function Util:verify_issuer(issClaim, acceptedIssuers) + for i, iss in ipairs(acceptedIssuers) do if issClaim == iss then --claim matches an accepted issuer so return success return true; @@ -192,8 +193,9 @@ end --- Verifies token -- @param token the token to verify -- @param secret the secret to use to verify token +-- @param acceptedIssuers the list of accepted issuers to check -- @return nil and error or the extracted claims from the token -function Util:verify_token(token, secret) +function Util:verify_token(token, secret, acceptedIssuers) local claims, err = jwt.decode(token, secret, true); if claims == nil then return nil, err; @@ -209,7 +211,7 @@ function Util:verify_token(token, secret) return nil, "'iss' claim is missing"; end --check the issuer against the accepted list - local issCheck, issCheckErr = self:verify_issuer(issClaim); + local issCheck, issCheckErr = self:verify_issuer(issClaim, acceptedIssuers); if issCheck == nil then return nil, issCheckErr; end @@ -241,8 +243,13 @@ end -- session.jitsi_meet_context_group - the group value from the token -- session.jitsi_meet_context_features - the features value from the token -- @param session the current session +-- @param acceptedIssuers optional list of accepted issuers to check -- @return false and error -function Util:process_and_verify_token(session) +function Util:process_and_verify_token(session, acceptedIssuers) + if not acceptedIssuers then + acceptedIssuers = self.acceptedIssuers; + end + if session.auth_token == nil then if self.allowEmptyToken then return true; @@ -272,9 +279,9 @@ function Util:process_and_verify_token(session) -- now verify the whole token local claims, msg; if self.asapKeyServer then - claims, msg = self:verify_token(session.auth_token, pubKey); + claims, msg = self:verify_token(session.auth_token, pubKey, acceptedIssuers); else - claims, msg = self:verify_token(session.auth_token, self.appSecret); + claims, msg = self:verify_token(session.auth_token, self.appSecret, acceptedIssuers); end if claims ~= nil then -- Binds room name to the session which is later checked on MUC join @@ -401,4 +408,4 @@ function Util:verify_room(session, room_address) end end -return Util; \ No newline at end of file +return Util;