annotate sat/plugins/plugin_sec_aesgcm.py @ 3219:2ba602aef90e

plugin attach, aesgcm: attachments refactoring: attachment handling has been simplified, and now use a "register" method similar as the ones used for download or upload. A default method (for unencrypted messages) will try a simple upload and will copy the links to body. AESGCM plugin has been adapted to be used for encrypted files. If more than one file is sent with AESGCM plugin, they will be split in several messages as current de-facto standard (OMEMO media sharing) doesn't support several files per message.
author Goffi <goffi@goffi.org>
date Wed, 18 Mar 2020 20:25:02 +0100
parents 2c0628f3927e
children 653fa213d2f8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
3136
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3090
diff changeset
4 # Copyright (C) 2009-2020 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"]
3090
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 host.plugins["DOWNLOAD"].registerScheme(
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)
3090
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 host.trigger.add("XEP-0363_upload_size", self._uploadSizeTrigger)
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 host.trigger.add("XEP-0363_upload", self._uploadTrigger)
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()
84b0c8b4dee0 plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents: 3178
diff changeset
132 self.host.plugins["DOWNLOAD"].errbackDownload(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
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
143 async def _uploadCb(self, client, filepath, filename, options):
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
144 options['encryption'] = C.ENC_AES_GCM
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
145 return await self._http_upload.fileHTTPUpload(
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,
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
149 options=options
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:]
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
163 await self._attach.uploadFiles(client, data, upload_cb=self._uploadCb)
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
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
170 body_elt = next(data["xml"].elements((C.NS_CLIENT, "body")))
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
171
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
172 for attachment in attachments:
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
173 body_elt.addContent(attachment["url"])
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
174
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
175 for attachment in extra_attachments:
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
176 # we send all remaining attachment in a separate message
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
177 client.sendMessage(
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
178 to_jid=data['to'],
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
179 message={'': ''},
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
180 subject=data['subject'],
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
181 mess_type=data['type'],
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
182 extra={C.MESS_KEY_ATTACHMENTS: [attachment]},
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
183 )
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
184
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
185 if ((not data['extra']
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
186 and (not data['message'] or data['message'] == {'': ''})
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
187 and not data['subject'])):
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
188 # nothing left to send, we can cancel the message
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
189 raise exceptions.CancelError("Cancelled by AESGCM attachment handling")
2ba602aef90e plugin attach, aesgcm: attachments refactoring:
Goffi <goffi@goffi.org>
parents: 3205
diff changeset
190
3090
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 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
192 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
193 # 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
194 # 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
195 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
196 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
197 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
198 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
199 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
200 else:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 tag = data
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 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
203 # 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
204 # 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
205 try:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 # 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
207 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
208 except AttributeError:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 # 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
210 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
211 else:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
212 # 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
213 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
214 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
215 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
216 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
217 file_obj.close()
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 else:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 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
220 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
221
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 def _uploadSizeTrigger(self, client, options, file_path, size, size_adjust):
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 if options.get('encryption') != C.ENC_AES_GCM:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 return True
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
225 # the tag is appended to the file
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 size_adjust.append(16)
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 return True
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
228
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 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
230 if data:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 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
232 else:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 try:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
234 # 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
235 ret = encryptor.finalize()
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 tag = encryptor.tag
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 return ret + tag
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 except AlreadyFinalized:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 # 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
240 return b''
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
241
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 def _uploadTrigger(self, client, options, sat_file, file_producer, slot):
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 if options.get('encryption') != C.ENC_AES_GCM:
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
244 return True
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 log.debug("encrypting file with AES-GCM")
3178
98b321234068 plugin aesgcm: use 12 bytes Initialisation Vector:
Goffi <goffi@goffi.org>
parents: 3174
diff changeset
246 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
247 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
248 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
249 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
250 # 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
251 # encoded key + iv
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 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
253
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 # 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
255 # 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
256 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
257
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 # file_producer get length directly from file, and this cause trouble has
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 # 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
260 # 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
261 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
262
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 encryptor = ciphers.Cipher(
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 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
265 modes.GCM(iv),
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
266 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
267 ).encryptor()
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
268
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
269 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
270 raise exceptions.InternalError(
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
271 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
272
4f8bdf50593f plugin sec aesgcm: new plugin handling `aesgcm:` scheme for e2e encrypted media sharing:
Goffi <goffi@goffi.org>
parents:
diff changeset
273 # 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
274 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
275 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
276
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
277
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
278 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
279 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
280 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
281 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
282 return ""
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
283
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
284 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
285 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
286 return data
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
287 links = []
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
288
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
289 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
290 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
291 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
292 message)
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
293 if 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 = message.strip()
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
295 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
296 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
297 else:
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
298 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
299 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
300 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
301 for link in links:
3186
84b0c8b4dee0 plugin download, aesgcm: fixed handling of HTTP errors
Goffi <goffi@goffi.org>
parents: 3178
diff changeset
302 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
303 attachment = {
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
304 "url": link,
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
305 }
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
306 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
307 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
308 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
309
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
310 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
311 # 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
312 # 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
313 # 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
314 # 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
315 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
316 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
317
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
318 return data
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 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
321 # 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
322 # 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
323 # attachment
c90f27ce52b0 plugin aesgcm: look for "aesgcm" links in body to use them as attachments
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
324 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
325 return True