mod_sasl2_fast/mod_sasl2_fast.lua
changeset 5080 eb46abc65dfd
parent 5079 ba2f1292d5fe
child 5081 e900bbd2e70d
equal deleted inserted replaced
5079:ba2f1292d5fe 5080:eb46abc65dfd
    10 
    10 
    11 local xmlns_fast = "urn:xmpp:fast:0";
    11 local xmlns_fast = "urn:xmpp:fast:0";
    12 local xmlns_sasl2 = "urn:xmpp:sasl:2";
    12 local xmlns_sasl2 = "urn:xmpp:sasl:2";
    13 
    13 
    14 local token_store = module:open_store("fast_tokens", "map");
    14 local token_store = module:open_store("fast_tokens", "map");
       
    15 
       
    16 local log = module._log;
    15 
    17 
    16 local function make_token(username, client_id, mechanism)
    18 local function make_token(username, client_id, mechanism)
    17 	local new_token = "secret-token:fast-"..id.long();
    19 	local new_token = "secret-token:fast-"..id.long();
    18 	local key = hash.sha256(client_id, true).."-new";
    20 	local key = hash.sha256(client_id, true).."-new";
    19 	local issued_at = now();
    21 	local issued_at = now();
    33 	return function (mechanism, username, client_id, token_hash, cb_data)
    35 	return function (mechanism, username, client_id, token_hash, cb_data)
    34 		local tried_current_token = false;
    36 		local tried_current_token = false;
    35 		local key = hash.sha256(client_id, true).."-new";
    37 		local key = hash.sha256(client_id, true).."-new";
    36 		local token;
    38 		local token;
    37 		repeat
    39 		repeat
       
    40 			log("debug", "Looking for %s token %s/%s", mechanism, username, key);
    38 			token = token_store:get(username, key);
    41 			token = token_store:get(username, key);
    39 			if token and token.mechanism == mechanism then
    42 			if token and token.mechanism == mechanism then
    40 				local expected_hash = hmac_f(token.secret, "Initiator"..cb_data);
    43 				local expected_hash = hmac_f(token.secret, "Initiator"..cb_data);
    41 				if hash.equals(expected_hash, token_hash) then
    44 				if hash.equals(expected_hash, token_hash) then
    42 					if token.expires_at < now() then
    45 					if token.expires_at < now() then
    52 					end
    55 					end
    53 					return true, username, hmac_f(token.secret, "Responder"..cb_data);
    56 					return true, username, hmac_f(token.secret, "Responder"..cb_data);
    54 				end
    57 				end
    55 			end
    58 			end
    56 			if not tried_current_token then
    59 			if not tried_current_token then
       
    60 				log("debug", "Trying next token...");
    57 				-- Try again with the current token instead
    61 				-- Try again with the current token instead
    58 				tried_current_token = true;
    62 				tried_current_token = true;
    59 				key = key:sub(1, -4).."-cur";
    63 				key = key:sub(1, -4).."-cur";
    60 			else
    64 			else
       
    65 				log("debug", "No matching %s token found for %s/%s", mechanism, username, key);
    61 				return nil;
    66 				return nil;
    62 			end
    67 			end
    63 		until false;
    68 		until false;
    64 	end
    69 	end
    65 end
    70 end
   105 			fast_sasl_handler.profile._client_id = client_id;
   110 			fast_sasl_handler.profile._client_id = client_id;
   106 			fast_sasl_handler.profile.cb = session.sasl_handler.profile.cb;
   111 			fast_sasl_handler.profile.cb = session.sasl_handler.profile.cb;
   107 			fast_sasl_handler.userdata = session.sasl_handler.userdata;
   112 			fast_sasl_handler.userdata = session.sasl_handler.userdata;
   108 			session.sasl_handler = fast_sasl_handler;
   113 			session.sasl_handler = fast_sasl_handler;
   109 		else
   114 		else
   110 			session.log("warn", "Client asked to auth via FAST, but no SASL handler available");
   115 			session.log("warn", "Client asked to auth via FAST, but SASL handler or client id missing");
   111 			local failure = st.stanza("failure", { xmlns = xmlns_sasl2 })
   116 			local failure = st.stanza("failure", { xmlns = xmlns_sasl2 })
   112 				:tag("malformed-request"):up()
   117 				:tag("malformed-request"):up()
   113 				:text_tag("text", "FAST is not available on this stream");
   118 				:text_tag("text", "FAST is not available on this stream");
   114 			session.send(failure);
   119 			session.send(failure);
   115 			return true;
   120 			return true;