|
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); |