mod_cloud_notify_encrypted/mod_cloud_notify_encrypted.lua
changeset 4460 8ed1989e99f9
parent 4377 41ac0941b217
child 4461 091d06c7d724
equal deleted inserted replaced
4459:89e54247ade6 4460:8ed1989e99f9
       
     1 local array = require "util.array";
     1 local base64 = require "util.encodings".base64;
     2 local base64 = require "util.encodings".base64;
     2 local ciphers = require "openssl.cipher";
     3 local ciphers = require "openssl.cipher";
     3 local jid = require "util.jid";
     4 local jid = require "util.jid";
     4 local json = require "util.json";
     5 local json = require "util.json";
     5 local random = require "util.random";
     6 local random = require "util.random";
       
     7 local set = require "util.set";
     6 local st = require "util.stanza";
     8 local st = require "util.stanza";
     7 
     9 
     8 local xmlns_jmi = "urn:xmpp:jingle-message:0";
    10 local xmlns_jmi = "urn:xmpp:jingle-message:0";
     9 local xmlns_push = "urn:xmpp:push:0";
    11 local xmlns_push = "urn:xmpp:push:0";
    10 local xmlns_push_encrypt = "tigase:push:encrypt:0";
    12 local xmlns_push_encrypt = "tigase:push:encrypt:0";
    74 		elseif original_stanza.attr.type ~= "error" then
    76 		elseif original_stanza.attr.type ~= "error" then
    75 			local jmi_propose = original_stanza:get_child("propose", xmlns_jmi);
    77 			local jmi_propose = original_stanza:get_child("propose", xmlns_jmi);
    76 			if jmi_propose then
    78 			if jmi_propose then
    77 				push_payload.type = "call";
    79 				push_payload.type = "call";
    78 				push_payload.sid = jmi_propose.attr.id;
    80 				push_payload.sid = jmi_propose.attr.id;
       
    81 				local media_types = set.new();
       
    82 				for description in jmi_propose:childtags("description") do
       
    83 					local media_type = description.attr.media;
       
    84 					if media_type then
       
    85 						media_types:add(media_type);
       
    86 					end
       
    87 				end
       
    88 				push_payload.media = array.collect(media_types:items());
    79 			else
    89 			else
    80 				push_payload.type = "chat";
    90 				push_payload.type = "chat";
    81 			end
    91 			end
    82 		end
    92 		end
    83 	elseif original_stanza.name == "presence"
    93 	elseif original_stanza.name == "presence"
    92 	-- FIXME: luaossl does not expose the EVP_CTRL_GCM_GET_TAG API, so we append 16 NUL bytes
   102 	-- FIXME: luaossl does not expose the EVP_CTRL_GCM_GET_TAG API, so we append 16 NUL bytes
    93 	-- Siskin does not validate the tag anyway.
   103 	-- Siskin does not validate the tag anyway.
    94 	local encrypted_payload = base64.encode(ciphers.new("AES-128-GCM"):encrypt(key_binary, iv):final(push_json)..string.rep("\0", 16));
   104 	local encrypted_payload = base64.encode(ciphers.new("AES-128-GCM"):encrypt(key_binary, iv):final(push_json)..string.rep("\0", 16));
    95 	local encrypted_element = st.stanza("encrypted", { xmlns = xmlns_push_encrypt, iv = base64.encode(iv) })
   105 	local encrypted_element = st.stanza("encrypted", { xmlns = xmlns_push_encrypt, iv = base64.encode(iv) })
    96 		:text(encrypted_payload);
   106 		:text(encrypted_payload);
       
   107 	if push_payload.type == "call" then
       
   108 		encrypted_payload.attr.type = "voip";
       
   109 		event.important = true;
       
   110 	end
    97 	-- Replace the unencrypted notification data with the encrypted one
   111 	-- Replace the unencrypted notification data with the encrypted one
    98 	event.notification_payload
   112 	event.notification_payload
    99 		:remove_children("x", "jabber:x:data")
   113 		:remove_children("x", "jabber:x:data")
   100 		:add_child(encrypted_element);
   114 		:add_child(encrypted_element);
   101 end
   115 end
   102 
   116 
   103 module:hook("cloud_notify/registration", handle_register);
   117 module:hook("cloud_notify/registration", handle_register);
   104 module:hook("cloud_notify/push", handle_push);
   118 module:hook("cloud_notify/push", handle_push, 1);