Software /
code /
prosody-modules
Annotate
mod_cloud_notify_encrypted/mod_cloud_notify_encrypted.lua @ 4449:c25eef56e9c9
mod_muc_http_defaults: Fix order of http callback arguments
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 19 Feb 2021 20:36:11 +0100 |
parent | 4373:41ac0941b217 |
child | 4456:8ed1989e99f9 |
rev | line source |
---|---|
4327
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 local base64 = require "util.encodings".base64; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 local ciphers = require "openssl.cipher"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 local jid = require "util.jid"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 local json = require "util.json"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 local random = require "util.random"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 local st = require "util.stanza"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 local xmlns_jmi = "urn:xmpp:jingle-message:0"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 local xmlns_push = "urn:xmpp:push:0"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 local xmlns_push_encrypt = "tigase:push:encrypt:0"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 local xmlns_push_encrypt_aes_128_gcm = "tigase:push:encrypt:aes-128-gcm"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 -- https://xeps.tigase.net//docs/push-notifications/encrypt/#41-discovering-support |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 local function account_disco_info(event) |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 event.reply:tag("feature", {var=xmlns_push_encrypt}):up(); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 event.reply:tag("feature", {var=xmlns_push_encrypt_aes_128_gcm}):up(); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 module:hook("account-disco-info", account_disco_info); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 function handle_register(event) |
4329
2a5164162708
mod_cloud_notify_encrypted: Fix the location of the <encrypt> element in push registrations
Matthew Wild <mwild1@gmail.com>
parents:
4327
diff
changeset
|
21 local encrypt = event.stanza:get_child("enable", xmlns_push):get_child("encrypt", xmlns_push_encrypt); |
4327
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 if not encrypt then return; end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 local algorithm = encrypt.attr.alg; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 if algorithm ~= "aes-128-gcm" then |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 event.origin.send(st.error_reply( |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 event.stanza, "modify", "feature-not-implemented", "Unknown encryption algorithm" |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 )); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 return false; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 local key_base64 = encrypt:get_text(); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 local key_binary = base64.decode(key_base64); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 if not key_binary or #key_binary ~= 16 then |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 event.origin.send(st.error_reply( |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 event.stanza, "modify", "bad-request", "Invalid encryption key" |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 )); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 return false; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 event.push_info.encryption = { |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 algorithm = algorithm; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 key_base64 = key_base64; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 }; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 function handle_push(event) |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 local encryption = event.push_info.encryption; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 if not encryption then return; end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 if encryption.algorithm ~= "aes-128-gcm" then |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 event.reason = "Unsupported encryption algorithm: "..tostring(encryption.algorithm); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 return true; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 local push_summary = event.push_summary; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 local original_stanza = event.original_stanza; |
4331
2e355540f8c8
mod_cloud_notify_encrypted: Truncate message body to 255 characters
Matthew Wild <mwild1@gmail.com>
parents:
4330
diff
changeset
|
59 local body = original_stanza:get_child_text("body"); |
4373
41ac0941b217
mod_cloud_notify_encrypted: Fix traceback on push of message with no body
Matthew Wild <mwild1@gmail.com>
parents:
4333
diff
changeset
|
60 if body and #body > 255 then |
4331
2e355540f8c8
mod_cloud_notify_encrypted: Truncate message body to 255 characters
Matthew Wild <mwild1@gmail.com>
parents:
4330
diff
changeset
|
61 body = body:sub(1, 255); |
2e355540f8c8
mod_cloud_notify_encrypted: Truncate message body to 255 characters
Matthew Wild <mwild1@gmail.com>
parents:
4330
diff
changeset
|
62 end |
4327
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 local push_payload = { |
4330
e655581173be
mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents:
4329
diff
changeset
|
65 unread = tonumber(push_summary["message-count"]) or 1; |
e655581173be
mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents:
4329
diff
changeset
|
66 sender = jid.bare(original_stanza.attr.from); |
e655581173be
mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents:
4329
diff
changeset
|
67 message = body; |
4327
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 }; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 if original_stanza.name == "message" then |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 if original_stanza.attr.type == "groupchat" then |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 push_payload.type = "groupchat"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 push_payload.nickname = jid.resource(original_stanza.attr.from); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 elseif original_stanza.attr.type ~= "error" then |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 local jmi_propose = original_stanza:get_child("propose", xmlns_jmi); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 if jmi_propose then |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 push_payload.type = "call"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 push_payload.sid = jmi_propose.attr.id; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 else |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 push_payload.type = "chat"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 elseif original_stanza.name == "presence" |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 and original_stanza.attr.type == "subscribe" then |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 push_payload.type = "subscribe"; |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 local iv = random.bytes(12); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 local key_binary = base64.decode(encryption.key_base64); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
90 local push_json = json.encode(push_payload); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 |
4330
e655581173be
mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents:
4329
diff
changeset
|
92 -- FIXME: luaossl does not expose the EVP_CTRL_GCM_GET_TAG API, so we append 16 NUL bytes |
e655581173be
mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents:
4329
diff
changeset
|
93 -- Siskin does not validate the tag anyway. |
e655581173be
mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
Matthew Wild <mwild1@gmail.com>
parents:
4329
diff
changeset
|
94 local encrypted_payload = base64.encode(ciphers.new("AES-128-GCM"):encrypt(key_binary, iv):final(push_json)..string.rep("\0", 16)); |
4327
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
95 local encrypted_element = st.stanza("encrypted", { xmlns = xmlns_push_encrypt, iv = base64.encode(iv) }) |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
96 :text(encrypted_payload); |
4333
97f369745ec7
mod_cloud_notify_encrypted: Use new direct access to notification element
Matthew Wild <mwild1@gmail.com>
parents:
4331
diff
changeset
|
97 -- Replace the unencrypted notification data with the encrypted one |
97f369745ec7
mod_cloud_notify_encrypted: Use new direct access to notification element
Matthew Wild <mwild1@gmail.com>
parents:
4331
diff
changeset
|
98 event.notification_payload |
97f369745ec7
mod_cloud_notify_encrypted: Use new direct access to notification element
Matthew Wild <mwild1@gmail.com>
parents:
4331
diff
changeset
|
99 :remove_children("x", "jabber:x:data") |
97f369745ec7
mod_cloud_notify_encrypted: Use new direct access to notification element
Matthew Wild <mwild1@gmail.com>
parents:
4331
diff
changeset
|
100 :add_child(encrypted_element); |
4327
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
101 end |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
102 |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
103 module:hook("cloud_notify/registration", handle_register); |
beb3342f1137
mod_cloud_notify_encrypted: New module for Encrypted Push Notifications
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
104 module:hook("cloud_notify/push", handle_push); |