Mercurial > libervia-backend
annotate sat/plugins/plugin_sec_aesgcm.py @ 4001:32d714a8ea51
plugin XEP-0045: dot not wait for MAM retrieval to be completed:
in `_join_MAM`, `room.fully_joined` is called before retrieving the MAM archive, as the
process can be very long, and is not necessary to have the room working (message can be
received after being in the room, and added out of order). This avoid blocking the `join`
workflow for an extended time.
Some renaming and coroutine integrations.
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 10 Mar 2023 17:22:41 +0100 |
parents | 0ff265725489 |
children | 78b5f356900c |
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). |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
159 attachments = data["extra"][C.MESS_KEY_ATTACHMENTS] |
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() |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
168 del data["extra"][C.MESS_KEY_ATTACHMENTS] |
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'], |
2ba602aef90e
plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents:
3205
diff
changeset
|
184 extra={C.MESS_KEY_ATTACHMENTS: [attachment]}, |
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) |
c90f27ce52b0
plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents:
3136
diff
changeset
|
302 attachments = data['extra'].setdefault(C.MESS_KEY_ATTACHMENTS, []) |
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: |
3196
adf1aeaa0d37
core (constants): renamed `MESS_KEY_MEDIA_TYPE` to `MESS_KEY_ATTACHMENTS_MEDIA_TYPE`
Goffi <goffi@goffi.org>
parents:
3186
diff
changeset
|
310 attachment[C.MESS_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 |