Ver código fonte

Uses JWT for token generation in prosody plugin.

j8
paweldomas 9 anos atrás
pai
commit
d666fbb6a4

+ 1
- 2
prosody-plugins/mod_auth_token.lua Ver arquivo

@@ -27,10 +27,9 @@ local provider = {};
27 27
 
28 28
 local appId = module:get_option_string("app_id");
29 29
 local appSecret = module:get_option_string("app_secret");
30
-local tokenLifetime = module:get_option_number("token_lifetime");
31 30
 
32 31
 function provider.test_password(username, password)
33
-	local result, msg = token_util.verify_password(password, appId, appSecret, tokenLifetime);
32
+	local result, msg = token_util.verify_password(password, appId, appSecret, nil);
34 33
 	if result == true then
35 34
 		return true;
36 35
 	else

+ 14
- 5
prosody-plugins/mod_token_verification.lua Ver arquivo

@@ -22,25 +22,34 @@ end
22 22
 
23 23
 local appId = parentCtx:get_option_string("app_id");
24 24
 local appSecret = parentCtx:get_option_string("app_secret");
25
-local tokenLifetime = parentCtx:get_option_string("token_lifetime");
26 25
 
27
-log("debug", "%s - starting MUC token verifier app_id: %s app_secret: %s token-lifetime: %s",
28
-	tostring(host), tostring(appId), tostring(appSecret), tostring(tokenLifetime));
26
+log("debug", "%s - starting MUC token verifier app_id: %s app_secret: %s",
27
+	tostring(host), tostring(appId), tostring(appSecret));
29 28
 
30 29
 local function handle_pre_create(event)
30
+
31 31
 	local origin, stanza = event.origin, event.stanza;	
32 32
 	local token = stanza:get_child("token", "http://jitsi.org/jitmeet/auth-token");
33
+
33 34
 	-- token not required for admin users
34 35
 	local user_jid = stanza.attr.from;	
35 36
 	if is_admin(user_jid) then
36 37
 		log("debug", "Token not required from admin user: %s", user_jid);
37 38
 		return nil;
38 39
 	end
39
-	log("debug", "Will verify token for user: %s ", user_jid);
40
+
41
+	local room = string.match(stanza.attr.to, "^(%w+)@");
42
+	log("debug", "Will verify token for user: %s, room: %s ", user_jid, room);
43
+	if room == nil then
44
+		log("error", "Unable to get name of the MUC room ? to: %s", stanza.attr.to);
45
+		return nil;
46
+	end
47
+
40 48
 	if token ~= nil then
41 49
 		token = token[1];
42 50
 	end
43
-	local result, msg = token_util.verify_password(token, appId, appSecret, tokenLifetime);
51
+
52
+	local result, msg = token_util.verify_password(token, appId, appSecret, room);
44 53
 	if result ~= true then
45 54
 		log("debug", "Token verification failed: %s", msg);
46 55
 		origin.send(st.error_reply(stanza, "cancel", "not-allowed", msg));

+ 20
- 58
prosody-plugins/token/util.lib.lua Ver arquivo

@@ -1,76 +1,38 @@
1 1
 -- Token authentication
2 2
 -- Copyright (C) 2015 Atlassian
3 3
 
4
-local hashes = require "util.hashes";
4
+local jwt = require "luajwt";
5 5
 
6 6
 local _M = {};
7 7
 
8
-local function calc_hash(password, appId, appSecret)
9
-	local hash, room, ts = string.match(password, "(%w+)_(%w+)_(%d+)");
10
-	if hash ~= nil and room ~= nil and ts ~= nil then
11
-		log("debug", "Hash: '%s' room: '%s', ts: '%s'", hash, room, ts);
12
-                local toHash = room .. ts .. appId .. appSecret;
13
-		log("debug", "to be hashed: '%s'", toHash);
14
-		local hash = hashes.sha256(toHash, true);
15
-		log("debug", "hash: '%s'", hash);
16
-		return hash;
17
-	else
18
-		log("error", "Invalid password format: '%s'", password);
19
-		return nil;
20
-	end
21
-end
22
-
23
-local function extract_hash(password)
24
-	local hash, room, ts = string.match(password, "(%w+)_(%w+)_(%d+)");
25
-	return hash;
26
-end
8
+local function verify_password_impl(password, appId, appSecret, roomName)
27 9
 
28
-local function extract_ts(password)
29
-	local hash, room, ts = string.match(password, "(%w+)_(%w+)_(%d+)");
30
-	return ts;
31
-end
32
-
33
-local function get_utc_timestamp()
34
-        return os.time(os.date("!*t")) * 1000;
35
-end
36
-
37
-local function verify_timestamp(ts, tokenLifetime)
38
-	return get_utc_timestamp() - ts <= tokenLifetime;
39
-end
40
-
41
-local function verify_password_impl(password, appId, appSecret, tokenLifetime)
42
-
43
-	if password == nil then
44
-   		return nil, "password is missing";
45
-        end
46
-
47
-	if tokenLifetime == nil then
48
-		tokenLifetime = 24 * 60 * 60 * 1000;
10
+	local claims, err = jwt.decode(password, appSecret, true);
11
+	if claims == nil then
12
+		return nil, err;
49 13
 	end
50 14
 
51
-	local ts = extract_ts(password);	
52
-	if ts == nil then
53
-		return nil, "timestamp not found in the password";
15
+	local issClaim = claims["iss"];
16
+	if issClaim == nil then
17
+		return nil, "Issuer field is missing";
54 18
 	end
55
-       	local os_ts = get_utc_timestamp();
56
-	log("debug", "System TS: '%s' user TS: %s", tostring(os_ts), tostring(ts));
57
-	local isValid = verify_timestamp(ts, tokenLifetime);
58
-	if not isValid then
59
-		return nil, "token expired";
19
+	if issClaim ~= appId then
20
+		return nil, "Invalid application ID('iss' claim)";
60 21
 	end
61 22
 
62
-	local realHash = calc_hash(password, appId, appSecret);
63
-	local givenhash = extract_hash(password);
64
-        log("debug", "Compare '%s' to '%s'", tostring(realHash), tostring(givenhash));
65
-	if realHash == givenhash then
66
-		return true;
67
-	else
68
-		return nil, "invalid hash";
23
+	local roomClaim = claims["room"];
24
+	if roomClaim == nil then
25
+		return nil, "Room field is missing";
26
+	end
27
+	if roomName ~= nil and roomName ~= roomClaim then
28
+		return nil, "Invalid room name('room' claim)";
69 29
 	end
30
+	
31
+	return true;
70 32
 end
71 33
 
72
-function _M.verify_password(password, appId, appSecret, tokenLifetime)
73
-	return verify_password_impl(password, appId, appSecret, tokenLifetime);
34
+function _M.verify_password(password, appId, appSecret, roomName)
35
+	return verify_password_impl(password, appId, appSecret, roomName);
74 36
 end
75 37
 
76 38
 return _M;

Carregando…
Cancelar
Salvar