Mercurial > libervia-backend
annotate sat/plugins/plugin_sec_aesgcm.py @ 4026:fe4725bf42fb
core (memory/sqla): be sure to have a dict when serialising History.extra:
`extra` can be None, this patch avoid this value when serialising it by using an empty
dict.
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 24 Mar 2023 10:29:48 +0100 |
parents | 78b5f356900c |
children | 524856bd7b19 |
rev | line source |
---|---|
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
1 #!/usr/bin/env python3 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
2 |
3174
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
3 # SàT plugin for handling AES-GCM file encryption |
3479 | 4 # Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org) |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
5 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
6 # This program is free software: you can redistribute it and/or modify |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
7 # it under the terms of the GNU Affero General Public License as published by |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
8 # the Free Software Foundation, either version 3 of the License, or |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
9 # (at your option) any later version. |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
10 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
11 # This program is distributed in the hope that it will be useful, |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
14 # GNU Affero General Public License for more details. |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
15 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
16 # You should have received a copy of the GNU Affero General Public License |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
18 |
3174
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
19 import re |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
20 from textwrap import dedent |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
21 from functools import partial |
3186
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
22 from urllib import parse |
3174
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
23 import mimetypes |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
24 import secrets |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
25 from cryptography.hazmat.primitives import ciphers |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
26 from cryptography.hazmat.primitives.ciphers import modes |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
27 from cryptography.hazmat import backends |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
28 from cryptography.exceptions import AlreadyFinalized |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
29 import treq |
3186
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
30 from twisted.internet import defer |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
31 from sat.core.i18n import _ |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
32 from sat.core.constants import Const as C |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
33 from sat.core import exceptions |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
34 from sat.tools import stream |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
35 from sat.core.log import getLogger |
3205
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
36 from sat.tools.web import treq_client_no_ssl |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
37 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
38 log = getLogger(__name__) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
39 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
40 PLUGIN_INFO = { |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
41 C.PI_NAME: "AES-GCM", |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
42 C.PI_IMPORT_NAME: "AES-GCM", |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
43 C.PI_TYPE: "SEC", |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
44 C.PI_PROTOCOLS: ["OMEMO Media sharing"], |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
45 C.PI_DEPENDENCIES: ["XEP-0363", "XEP-0384", "DOWNLOAD", "ATTACH"], |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
46 C.PI_MAIN: "AESGCM", |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
47 C.PI_HANDLER: "no", |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
48 C.PI_DESCRIPTION: dedent(_("""\ |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
49 Implementation of AES-GCM scheme, a way to encrypt files (not official XMPP standard). |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
50 See https://xmpp.org/extensions/inbox/omemo-media-sharing.html for details |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
51 """)), |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
52 } |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
53 |
3174
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
54 AESGCM_RE = re.compile( |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
55 r'aesgcm:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9' |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
56 r'()@:%_\+.~#?&\/\/=]*)') |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
57 |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
58 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
59 class AESGCM(object): |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
60 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
61 def __init__(self, host): |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
62 self.host = host |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
63 log.info(_("AESGCM plugin initialization")) |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
64 self._http_upload = host.plugins['XEP-0363'] |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
65 self._attach = host.plugins["ATTACH"] |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
66 host.plugins["DOWNLOAD"].register_scheme( |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
67 "aesgcm", self.download |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
68 ) |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
69 self._attach.register( |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
70 self.canHandleAttachment, self.attach, encrypted=True) |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
71 host.trigger.add("XEP-0363_upload_pre_slot", self._upload_pre_slot) |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
72 host.trigger.add("XEP-0363_upload", self._upload_trigger) |
3174
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
73 host.trigger.add("messageReceived", self._messageReceivedTrigger) |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
74 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
75 async def download(self, client, uri_parsed, dest_path, options): |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
76 fragment = bytes.fromhex(uri_parsed.fragment) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
77 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
78 # legacy method use 16 bits IV, but OMEMO media sharing published spec indicates |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
79 # which is 12 bits IV (AES-GCM spec recommandation), so we have to determine |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
80 # which size has been used. |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
81 if len(fragment) == 48: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
82 iv_size = 16 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
83 elif len(fragment) == 44: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
84 iv_size = 12 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
85 else: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
86 raise ValueError( |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
87 f"Invalid URL fragment, can't decrypt file at {uri_parsed.get_url()}") |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
88 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
89 iv, key = fragment[:iv_size], fragment[iv_size:] |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
90 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
91 decryptor = ciphers.Cipher( |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
92 ciphers.algorithms.AES(key), |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
93 modes.GCM(iv), |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
94 backend=backends.default_backend(), |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
95 ).decryptor() |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
96 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
97 download_url = parse.urlunparse( |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
98 ('https', uri_parsed.netloc, uri_parsed.path, '', '', '')) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
99 |
3205
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
100 if options.get('ignore_tls_errors', False): |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
101 log.warning( |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
102 "TLS certificate check disabled, this is highly insecure" |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
103 ) |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
104 treq_client = treq_client_no_ssl |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
105 else: |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
106 treq_client = treq |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
107 |
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
108 head_data = await treq_client.head(download_url) |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
109 content_length = int(head_data.headers.getRawHeaders('content-length')[0]) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
110 # the 128 bits tag is put at the end |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
111 file_size = content_length - 16 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
112 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
113 file_obj = stream.SatFile( |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
114 self.host, |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
115 client, |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
116 dest_path, |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
117 mode="wb", |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
118 size = file_size, |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
119 ) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
120 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
121 progress_id = file_obj.uid |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
122 |
3205
2c0628f3927e
plugin download, aesgcm: disable TLS check if `check_certificate` setting is disabled
Goffi <goffi@goffi.org>
parents:
3196
diff
changeset
|
123 resp = await treq_client.get(download_url, unbuffered=True) |
3186
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
124 if resp.code == 200: |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
125 d = treq.collect(resp, partial( |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
126 self.onDataDownload, |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
127 client=client, |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
128 file_obj=file_obj, |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
129 decryptor=decryptor)) |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
130 else: |
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
131 d = defer.Deferred() |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
132 self.host.plugins["DOWNLOAD"].errback_download(file_obj, d, resp) |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
133 return progress_id, d |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
134 |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
135 async def canHandleAttachment(self, client, data): |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
136 try: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
137 await self._http_upload.getHTTPUploadEntity(client) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
138 except exceptions.NotFound: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
139 return False |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
140 else: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
141 return True |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
142 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
143 async def _upload_cb(self, client, filepath, filename, extra): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
144 extra['encryption'] = C.ENC_AES_GCM |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
145 return await self._http_upload.file_http_upload( |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
146 client=client, |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
147 filepath=filepath, |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
148 filename=filename, |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
149 extra=extra |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
150 ) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
151 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
152 async def attach(self, client, data): |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
153 # XXX: the attachment removal/resend code below is due to the one file per |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
154 # message limitation of OMEMO media sharing unofficial XEP. We have to remove |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
155 # attachments from original message, and send them one by one. |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
156 # TODO: this is to be removed when a better mechanism is available with OMEMO (now |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
157 # possible with the 0.4 version of OMEMO, it's possible to encrypt other stanza |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
158 # elements than body). |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
159 attachments = data["extra"][C.KEY_ATTACHMENTS] |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
160 if not data['message'] or data['message'] == {'': ''}: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
161 extra_attachments = attachments[1:] |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
162 del attachments[1:] |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
163 await self._attach.upload_files(client, data, upload_cb=self._upload_cb) |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
164 else: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
165 # we have a message, we must send first attachment separately |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
166 extra_attachments = attachments[:] |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
167 attachments.clear() |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
168 del data["extra"][C.KEY_ATTACHMENTS] |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
169 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
170 body_elt = data["xml"].body |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
171 if body_elt is None: |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
172 body_elt = data["xml"].addElement("body") |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
173 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
174 for attachment in attachments: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
175 body_elt.addContent(attachment["url"]) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
176 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
177 for attachment in extra_attachments: |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
178 # we send all remaining attachment in a separate message |
3222
653fa213d2f8
plugin aesgcm: wait for each splitted message to be sent before sending next one
Goffi <goffi@goffi.org>
parents:
3219
diff
changeset
|
179 await client.sendMessage( |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
180 to_jid=data['to'], |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
181 message={'': ''}, |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
182 subject=data['subject'], |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
183 mess_type=data['type'], |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
184 extra={C.KEY_ATTACHMENTS: [attachment]}, |
3219
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
185 ) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
186 |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
187 if ((not data['extra'] |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
188 and (not data['message'] or data['message'] == {'': ''}) |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
189 and not data['subject'])): |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
190 # nothing left to send, we can cancel the message |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
191 raise exceptions.CancelError("Cancelled by AESGCM attachment handling") |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
192 |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
193 def onDataDownload(self, data, client, file_obj, decryptor): |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
194 if file_obj.tell() + len(data) > file_obj.size: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
195 # we're reaching end of file with this bunch of data |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
196 # we may still have a last bunch if the tag is incomplete |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
197 bytes_left = file_obj.size - file_obj.tell() |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
198 if bytes_left > 0: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
199 decrypted = decryptor.update(data[:bytes_left]) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
200 file_obj.write(decrypted) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
201 tag = data[bytes_left:] |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
202 else: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
203 tag = data |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
204 if len(tag) < 16: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
205 # the tag is incomplete, either we'll get the rest in next data bunch |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
206 # or we have already the other part from last bunch of data |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
207 try: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
208 # we store partial tag in decryptor._sat_tag |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
209 tag = decryptor._sat_tag + tag |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
210 except AttributeError: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
211 # no other part, we'll get the rest at next bunch |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
212 decryptor.sat_tag = tag |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
213 else: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
214 # we have the complete tag, it must be 128 bits |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
215 if len(tag) != 16: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
216 raise ValueError(f"Invalid tag: {tag}") |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
217 remain = decryptor.finalize_with_tag(tag) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
218 file_obj.write(remain) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
219 file_obj.close() |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
220 else: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
221 decrypted = decryptor.update(data) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
222 file_obj.write(decrypted) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
223 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
224 def _upload_pre_slot(self, client, extra, file_metadata): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
225 if extra.get('encryption') != C.ENC_AES_GCM: |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
226 return True |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
227 # the tag is appended to the file |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
228 file_metadata["size"] += 16 |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
229 return True |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
230 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
231 def _encrypt(self, data, encryptor): |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
232 if data: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
233 return encryptor.update(data) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
234 else: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
235 try: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
236 # end of file is reached, me must finalize |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
237 ret = encryptor.finalize() |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
238 tag = encryptor.tag |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
239 return ret + tag |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
240 except AlreadyFinalized: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
241 # as we have already finalized, we can now send EOF |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
242 return b'' |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
243 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
244 def _upload_trigger(self, client, extra, sat_file, file_producer, slot): |
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
245 if extra.get('encryption') != C.ENC_AES_GCM: |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
246 return True |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
247 log.debug("encrypting file with AES-GCM") |
3178
98b321234068
plugin aesgcm: use 12 bytes Initialisation Vector:
Goffi <goffi@goffi.org>
parents:
3174
diff
changeset
|
248 iv = secrets.token_bytes(12) |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
249 key = secrets.token_bytes(32) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
250 fragment = f'{iv.hex()}{key.hex()}' |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
251 ori_url = parse.urlparse(slot.get) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
252 # we change the get URL with the one with aesgcm scheme and containing the |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
253 # encoded key + iv |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
254 slot.get = parse.urlunparse(['aesgcm', *ori_url[1:5], fragment]) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
255 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
256 # encrypted data size will be bigger than original file size |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
257 # so we need to check with final data length to avoid a warning on close() |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
258 sat_file.check_size_with_read = True |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
259 |
3922
0ff265725489
plugin XEP-0447: handle attachment and download:
Goffi <goffi@goffi.org>
parents:
3859
diff
changeset
|
260 # file_producer get length directly from file, and this cause trouble as |
3090
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
261 # we have to change the size because of encryption. So we adapt it here, |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
262 # else the producer would stop reading prematurely |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
263 file_producer.length = sat_file.size |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
264 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
265 encryptor = ciphers.Cipher( |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
266 ciphers.algorithms.AES(key), |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
267 modes.GCM(iv), |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
268 backend=backends.default_backend(), |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
269 ).encryptor() |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
270 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
271 if sat_file.data_cb is not None: |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
272 raise exceptions.InternalError( |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
273 f"data_cb was expected to be None, it is set to {sat_file.data_cb}") |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
274 |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
275 # with data_cb we encrypt the file on the fly |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
276 sat_file.data_cb = partial(self._encrypt, encryptor=encryptor) |
4f8bdf50593f
plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff
changeset
|
277 return True |
3174
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
278 |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
279 |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
280 def _popAESGCMLinks(self, match, links): |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
281 link = match.group() |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
282 if link not in links: |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
283 links.append(link) |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
284 return "" |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
285 |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
286 def _checkAESGCMAttachments(self, client, data): |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
287 if not data.get('message'): |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
288 return data |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
289 links = [] |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
290 |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
291 for lang, message in list(data['message'].items()): |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
292 message = AESGCM_RE.sub( |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
293 partial(self._popAESGCMLinks, links=links), |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
294 message) |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
295 if links: |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
296 message = message.strip() |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
297 if not message: |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
298 del data['message'][lang] |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
299 else: |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
300 data['message'][lang] = message |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
301 mess_encrypted = client.encryption.isEncrypted(data) |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
302 attachments = data['extra'].setdefault(C.KEY_ATTACHMENTS, []) |
3174
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
303 for link in links: |
3186
84b0c8b4dee0
plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents:
3178
diff
changeset
|
304 path = parse.urlparse(link).path |
3174
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
305 attachment = { |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
306 "url": link, |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
307 } |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
308 media_type = mimetypes.guess_type(path, strict=False)[0] |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
309 if media_type is not None: |
4023
78b5f356900c
component AP gateway: handle attachments
Goffi <goffi@goffi.org>
parents:
3922
diff
changeset
|
310 attachment[C.KEY_ATTACHMENTS_MEDIA_TYPE] = media_type |
3174
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
311 |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
312 if mess_encrypted: |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
313 # we don't add the encrypted flag if the message itself is not |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
314 # encrypted, because the decryption key is part of the link, |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
315 # so sending it over unencrypted channel is like having no |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
316 # encryption at all. |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
317 attachment['encrypted'] = True |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
318 attachments.append(attachment) |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
319 |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
320 return data |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
321 |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
322 def _messageReceivedTrigger(self, client, message_elt, post_treat): |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
323 # we use a post_treat callback instead of "message_parse" trigger because we need |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
324 # to check if the "encrypted" flag is set to decide if we add the same flag to the |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
325 # attachment |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
326 post_treat.addCallback(partial(self._checkAESGCMAttachments, client)) |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
327 return True |