annotate sat/plugins/plugin_xep_0420.py @ 3888:aa7197b67c26

component AP gateway: AP <=> XMPP reactions conversions: - Pubsub Attachments plugin has been renamed to XEP-0470 following publication - XEP-0470 has been updated to follow 0.2 changes - AP reactions (as implemented in Pleroma) are converted to XEP-0470 - XEP-0470 events are converted to AP reactions (again, using "EmojiReact" from Pleroma) - AP activities related to attachments (like/reactions) are cached in Libervia because it's not possible to retrieve them from Pleroma instances once they have been emitted (doing an HTTP get on their ID returns a 404). For now those cache are not flushed, this should be improved in the future. - `sharedInbox` is used when available. Pleroma returns a 500 HTTP error when ``to`` or ``cc`` are used in a direct inbox. - reactions and like are not currently used for direct messages, because they can't be emitted from Pleroma in this case, thus there is no point in implementing them for the moment. rel 371
author Goffi <goffi@goffi.org>
date Wed, 31 Aug 2022 17:07:03 +0200
parents 00212260f659
children 8289ac1b34f4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3877
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
1 #!/usr/bin/env python3
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
2
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
3 # Libervia plugin for Stanza Content Encryption
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
4 # Copyright (C) 2022-2022 Tim Henkes (me@syndace.dev)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
5
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
9 # (at your option) any later version.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
10
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
15
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
18
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
19 # Type-check with `mypy --strict --disable-error-code no-untyped-call`
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
20 # Lint with `pylint`
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
21
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
22 from abc import ABC, abstractmethod
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
23 from datetime import datetime
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
24 import enum
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
25 import secrets
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
26 import string
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
27 from typing import Dict, Iterator, List, NamedTuple, Optional, Set, Tuple, Union, cast
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
28
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
29 from lxml import etree
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
30
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
31 from sat.core.constants import Const as C
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
32 from sat.core.i18n import D_
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
33 from sat.core.log import Logger, getLogger
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
34 from sat.core.sat_main import SAT
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
35 from sat.tools.xml_tools import ElementParser
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
36 from sat.plugins.plugin_xep_0033 import NS_ADDRESS
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
37 from sat.plugins.plugin_xep_0082 import XEP_0082
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
38 from sat.plugins.plugin_xep_0334 import NS_HINTS
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
39 from sat.plugins.plugin_xep_0359 import NS_SID
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
40 from sat.plugins.plugin_xep_0380 import NS_EME
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
41 from twisted.words.protocols.jabber import jid
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
42 from twisted.words.xish import domish
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
43
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
44
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
45 __all__ = [ # pylint: disable=unused-variable
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
46 "PLUGIN_INFO",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
47 "NS_SCE",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
48 "XEP_0420",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
49 "ProfileRequirementsNotMet",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
50 "AffixVerificationFailed",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
51 "SCECustomAffix",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
52 "SCEAffixPolicy",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
53 "SCEProfile",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
54 "SCEAffixValues"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
55 ]
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
56
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
57
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
58 log = cast(Logger, getLogger(__name__))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
59
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
60
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
61 PLUGIN_INFO = {
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
62 C.PI_NAME: "SCE",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
63 C.PI_IMPORT_NAME: "XEP-0420",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
64 C.PI_TYPE: "SEC",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
65 C.PI_PROTOCOLS: [ "XEP-0420" ],
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
66 C.PI_DEPENDENCIES: [ "XEP-0334", "XEP-0082" ],
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
67 C.PI_RECOMMENDATIONS: [ "XEP-0045", "XEP-0033", "XEP-0359" ],
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
68 C.PI_MAIN: "XEP_0420",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
69 C.PI_HANDLER: "no",
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
70 C.PI_DESCRIPTION: D_("Implementation of Stanza Content Encryption"),
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
71 }
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
72
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
73
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
74 NS_SCE = "urn:xmpp:sce:1"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
75
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
76
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
77 class ProfileRequirementsNotMet(Exception):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
78 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
79 Raised by :meth:`XEP_0420.unpack_stanza` in case the requirements formulated by the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
80 profile are not met.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
81 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
82
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
83
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
84 class AffixVerificationFailed(Exception):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
85 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
86 Raised by :meth:`XEP_0420.unpack_stanza` in case of affix verification failure.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
87 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
88
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
89
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
90 class SCECustomAffix(ABC):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
91 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
92 Interface for custom affixes of SCE profiles.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
93 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
94
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
95 @property
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
96 @abstractmethod
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
97 def element_name(self) -> str:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
98 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
99 @return: The name of the affix's XML element.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
100 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
101
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
102 @property
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
103 @abstractmethod
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
104 def element_schema(self) -> str:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
105 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
106 @return: The XML schema definition of the affix element's XML structure, i.e. the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
107 ``<xs:element/>`` schema element. This element will be referenced using
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
108 ``<xs:element ref="{element_name}"/>``.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
109 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
110
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
111 @abstractmethod
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
112 def create(self, stanza: domish.Element) -> domish.Element:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
113 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
114 @param stanza: The stanza element which has been processed by
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
115 :meth:`XEP_0420.pack_stanza`, i.e. all encryptable children have been removed
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
116 and only the root ``<message/>`` or ``<iq/>`` and unencryptable children
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
117 remain. Do not modify.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
118 @return: An affix element to include in the envelope. The element must have the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
119 name :attr:`element_name` and must validate using :attr:`element_schema`.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
120 @raise ValueError: if the affix couldn't be built.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
121 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
122
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
123 @abstractmethod
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
124 def verify(self, stanza: domish.Element, element: domish.Element) -> None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
125 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
126 @param stanza: The stanza element before being processed by
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
127 :meth:`XEP_0420.unpack_stanza`, i.e. all encryptable children have been
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
128 removed and only the root ``<message/>`` or ``<iq/>`` and unencryptable
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
129 children remain. Do not modify.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
130 @param element: The affix element to verify.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
131 @raise AffixVerificationFailed: on verification failure.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
132 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
133
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
134
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
135 @enum.unique
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
136 class SCEAffixPolicy(enum.Enum):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
137 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
138 Policy for the presence of an affix in an SCE envelope.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
139 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
140
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
141 REQUIRED: str = "REQUIRED"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
142 OPTIONAL: str = "OPTIONAL"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
143 NOT_NEEDED: str = "NOT_NEEDED"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
144
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
145
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
146 class SCEProfile(NamedTuple):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
147 # pylint: disable=invalid-name
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
148 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
149 An SCE profile, i.e. the definition which affixes are required, optional or not needed
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
150 at all by an SCE-enabled encryption protocol.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
151 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
152
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
153 rpad_policy: SCEAffixPolicy
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
154 time_policy: SCEAffixPolicy
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
155 to_policy: SCEAffixPolicy
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
156 from_policy: SCEAffixPolicy
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
157 custom_policies: Dict[SCECustomAffix, SCEAffixPolicy]
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
158
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
159
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
160 class SCEAffixValues(NamedTuple):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
161 # pylint: disable=invalid-name
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
162 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
163 Structure returned by :meth:`XEP_0420.unpack_stanza` with the parsed/processes values
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
164 of all affixes included in the envelope. For custom affixes, the whole affix element
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
165 is returned.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
166 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
167
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
168 rpad: Optional[str]
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
169 timestamp: Optional[datetime]
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
170 recipient: Optional[jid.JID]
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
171 sender: Optional[jid.JID]
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
172 custom: Dict[SCECustomAffix, domish.Element]
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
173
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
174
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
175 ENVELOPE_SCHEMA = """<?xml version="1.0" encoding="utf8"?>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
176 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
177 targetNamespace="urn:xmpp:sce:1"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
178 xmlns="urn:xmpp:sce:1">
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
179
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
180 <xs:element name="envelope">
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
181 <xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
182 <xs:all>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
183 <xs:element ref="content"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
184 <xs:element ref="rpad" minOccurs="0"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
185 <xs:element ref="time" minOccurs="0"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
186 <xs:element ref="to" minOccurs="0"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
187 <xs:element ref="from" minOccurs="0"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
188 {custom_affix_references}
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
189 </xs:all>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
190 </xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
191 </xs:element>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
192
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
193 <xs:element name="content">
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
194 <xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
195 <xs:sequence>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
196 <xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
197 </xs:sequence>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
198 </xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
199 </xs:element>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
200
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
201 <xs:element name="rpad" type="xs:string"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
202
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
203 <xs:element name="time">
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
204 <xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
205 <xs:attribute name="stamp" type="xs:dateTime"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
206 </xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
207 </xs:element>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
208
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
209 <xs:element name="to">
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
210 <xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
211 <xs:attribute name="jid" type="xs:string"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
212 </xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
213 </xs:element>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
214
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
215 <xs:element name="from">
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
216 <xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
217 <xs:attribute name="jid" type="xs:string"/>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
218 </xs:complexType>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
219 </xs:element>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
220
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
221 {custom_affix_definitions}
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
222 </xs:schema>
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
223 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
224
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
225
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
226 class XEP_0420: # pylint: disable=invalid-name
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
227 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
228 Implementation of XEP-0420: Stanza Content Encryption under namespace
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
229 ``urn:xmpp:sce:1``.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
230
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
231 This is a passive plugin, i.e. it doesn't hook into any triggers to process stanzas
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
232 actively, but offers API for other plugins to use.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
233 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
234
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
235 # Set of namespaces whose elements are never allowed to be transferred in an encrypted
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
236 # envelope.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
237 MUST_BE_PLAINTEXT_NAMESPACES: Set[str] = {
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
238 NS_HINTS,
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
239 NS_SID, # TODO: Not sure whether this ban applies to both stanza-id and origin-id
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
240 NS_ADDRESS,
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
241 # Not part of the specification (yet), but just doesn't make sense in an encrypted
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
242 # envelope:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
243 NS_EME
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
244 }
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
245
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
246 # Set of (namespace, element name) tuples that define elements which are never allowed
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
247 # to be transferred in an encrypted envelope. If all elements under a certain
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
248 # namespace are forbidden, the namespace can be added to
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
249 # :attr:`MUST_BE_PLAINTEXT_NAMESPACES` instead.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
250 # Note: only full namespaces are forbidden by the spec for now, the following is for
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
251 # potential future use.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
252 MUST_BE_PLAINTEXT_ELEMENTS: Set[Tuple[str, str]] = set()
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
253
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
254 def __init__(self, sat: SAT) -> None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
255 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
256 @param sat: The SAT instance.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
257 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
258
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
259 @staticmethod
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
260 def pack_stanza(profile: SCEProfile, stanza: domish.Element) -> bytes:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
261 """Pack a stanza according to Stanza Content Encryption.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
262
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
263 Removes all elements from the stanza except for a few exceptions that explicitly
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
264 need to be transferred in plaintext, e.g. because they contain hints/instructions
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
265 for the server on how to process the stanza. Together with the affix elements as
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
266 requested by the profile, the removed elements are added to an envelope XML
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
267 structure that builds the plaintext to be encrypted by the SCE-enabled encryption
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
268 scheme. Optional affixes are always added to the structure, i.e. they are treated
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
269 by the packing code as if they were required.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
270
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
271 Once built, the envelope structure is serialized to a byte string and returned for
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
272 the encryption scheme to encrypt and add to the stanza.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
273
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
274 @param profile: The SCE profile, i.e. the definition of affixes to include in the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
275 envelope.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
276 @param stanza: The stanza to process. Will be modified by the call.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
277 @return: The serialized envelope structure that builds the plaintext for the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
278 encryption scheme to process.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
279 @raise ValueError: if the <to/> or <from/> affixes are requested but the stanza
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
280 doesn't have the "to"/"from" attribute set to extract the value from. Can also
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
281 be raised by custom affixes.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
282
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
283 @warning: It is up to the calling code to add a <store/> message processing hint
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
284 if applicable.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
285 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
286
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
287 # Prepare the envelope and content elements
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
288 envelope = domish.Element((NS_SCE, "envelope"))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
289 content = envelope.addElement((NS_SCE, "content"))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
290
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
291 # Note the serialized byte size of the content element before adding any children
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
292 empty_content_byte_size = len(content.toXml().encode("utf-8"))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
293
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
294 # Just for type safety
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
295 stanza_children = cast(List[Union[domish.Element, str]], stanza.children)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
296 content_children = cast(List[Union[domish.Element, str]], content.children)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
297
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
298 # Move elements that are not explicitly forbidden from being encrypted from the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
299 # stanza to the content element.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
300 for child in list(cast(Iterator[domish.Element], stanza.elements())):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
301 if (
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
302 child.uri not in XEP_0420.MUST_BE_PLAINTEXT_NAMESPACES
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
303 and (child.uri, child.name) not in XEP_0420.MUST_BE_PLAINTEXT_ELEMENTS
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
304 ):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
305 # Remove the child from the stanza
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
306 stanza_children.remove(child)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
307
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
308 # A namespace of ``None`` can be used on domish elements to inherit the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
309 # namespace from the parent. When moving elements from the stanza root to
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
310 # the content element, however, we don't want elements to inherit the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
311 # namespace of the content element. Thus, check for elements with ``None``
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
312 # for their namespace and set the namespace to jabber:client, which is the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
313 # namespace of the parent element.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
314 if child.uri is None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
315 child.uri = C.NS_CLIENT
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
316 child.defaultUri = C.NS_CLIENT
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
317
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
318 # Add the child with corrected namespaces to the content element
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
319 content_children.append(child)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
320
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
321 # Add the affixes requested by the profile
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
322 if profile.rpad_policy is not SCEAffixPolicy.NOT_NEEDED:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
323 # The specification defines the rpad affix to contain "[...] a randomly
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
324 # generated sequence of random length between 0 and 200 characters." This
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
325 # implementation differs a bit from the specification in that a minimum size
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
326 # other than 0 is chosen depending on the serialized size of the content
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
327 # element. This is to prevent the scenario where the encrypted content is
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
328 # short and the rpad is also randomly chosen to be short, which could allow
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
329 # guessing the content of a short message. To do so, the rpad length is first
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
330 # chosen to pad the content to at least 53 bytes, then afterwards another 0 to
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
331 # 200 bytes are added. Note that single-byte characters are used by this
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
332 # implementation, thus the number of characters equals the number of bytes.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
333 content_byte_size = len(content.toXml().encode("utf-8"))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
334 content_byte_size_diff = content_byte_size - empty_content_byte_size
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
335 rpad_length = max(0, 53 - content_byte_size_diff) + secrets.randbelow(201)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
336 rpad_content = "".join(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
337 secrets.choice(string.digits + string.ascii_letters + string.punctuation)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
338 for __
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
339 in range(rpad_length)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
340 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
341 envelope.addElement((NS_SCE, "rpad"), content=rpad_content)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
342
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
343 if profile.time_policy is not SCEAffixPolicy.NOT_NEEDED:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
344 time_element = envelope.addElement((NS_SCE, "time"))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
345 time_element["stamp"] = XEP_0082.format_datetime()
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
346
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
347 if profile.to_policy is not SCEAffixPolicy.NOT_NEEDED:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
348 recipient = cast(Optional[str], stanza.getAttribute("to", None))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
349 if recipient is None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
350 raise ValueError(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
351 "<to/> affix requested, but stanza doesn't have the 'to' attribute"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
352 " set."
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
353 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
354
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
355 to_element = envelope.addElement((NS_SCE, "to"))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
356 to_element["jid"] = jid.JID(recipient).userhost()
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
357
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
358 if profile.from_policy is not SCEAffixPolicy.NOT_NEEDED:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
359 sender = cast(Optional[str], stanza.getAttribute("from", None))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
360 if sender is None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
361 raise ValueError(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
362 "<from/> affix requested, but stanza doesn't have the 'from'"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
363 " attribute set."
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
364 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
365
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
366 from_element = envelope.addElement((NS_SCE, "from"))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
367 from_element["jid"] = jid.JID(sender).userhost()
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
368
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
369 for affix, policy in profile.custom_policies.items():
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
370 if policy is not SCEAffixPolicy.NOT_NEEDED:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
371 envelope.addChild(affix.create(stanza))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
372
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
373 return cast(str, envelope.toXml()).encode("utf-8")
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
374
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
375 @staticmethod
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
376 def unpack_stanza(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
377 profile: SCEProfile,
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
378 stanza: domish.Element,
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
379 envelope_serialized: bytes
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
380 ) -> SCEAffixValues:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
381 """Unpack a stanza packed according to Stanza Content Encryption.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
382
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
383 Parses the serialized envelope as XML, verifies included affixes and makes sure
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
384 the requirements of the profile are met, and restores the stanza by moving
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
385 decrypted elements from the envelope back to the stanza top level.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
386
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
387 @param profile: The SCE profile, i.e. the definition of affixes that have to/may
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
388 be included in the envelope.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
389 @param stanza: The stanza to process. Will be modified by the call.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
390 @param envelope_serialized: The serialized envelope, i.e. the plaintext produced
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
391 by the decryption scheme utilizing SCE.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
392 @return: The parsed and processed values of all affixes that were present on the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
393 envelope, notably including the timestamp.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
394 @raise ValueError: if the serialized envelope element is malformed.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
395 @raise ProfileRequirementsNotMet: if one or more affixes required by the profile
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
396 are missing from the envelope.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
397 @raise AffixVerificationFailed: if an affix included in the envelope fails to
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
398 validate. It doesn't matter whether the affix is required by the profile or
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
399 not, all affixes included in the envelope are validated and cause this
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
400 exception to be raised on failure.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
401
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
402 @warning: It is up to the calling code to verify the timestamp, if returned, since
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
403 the requirements on the timestamp may vary between SCE-enabled protocols.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
404 """
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
405
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
406 try:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
407 envelope_serialized_string = envelope_serialized.decode("utf-8")
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
408 except UnicodeError as e:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
409 raise ValueError("Serialized envelope can't bare parsed as utf-8.") from e
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
410
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
411 custom_affixes = set(profile.custom_policies.keys())
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
412
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
413 # Make sure the envelope adheres to the schema
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
414 parser = etree.XMLParser(schema=etree.XMLSchema(etree.XML(ENVELOPE_SCHEMA.format(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
415 custom_affix_references="".join(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
416 f'<xs:element ref="{custom_affix.element_name}" minOccurs="0"/>'
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
417 for custom_affix
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
418 in custom_affixes
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
419 ),
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
420 custom_affix_definitions="".join(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
421 custom_affix.element_schema
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
422 for custom_affix
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
423 in custom_affixes
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
424 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
425 ).encode("utf-8"))))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
426
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
427 try:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
428 etree.fromstring(envelope_serialized_string, parser)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
429 except etree.XMLSyntaxError as e:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
430 raise ValueError("Serialized envelope doesn't pass schema validation.") from e
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
431
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
432 # Prepare the envelope and content elements
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
433 envelope = cast(domish.Element, ElementParser()(envelope_serialized_string))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
434 content = cast(domish.Element, next(envelope.elements(NS_SCE, "content")))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
435
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
436 # Verify the affixes
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
437 rpad_element = cast(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
438 Optional[domish.Element],
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
439 next(envelope.elements(NS_SCE, "rpad"), None)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
440 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
441 time_element = cast(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
442 Optional[domish.Element],
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
443 next(envelope.elements(NS_SCE, "time"), None)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
444 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
445 to_element = cast(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
446 Optional[domish.Element],
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
447 next(envelope.elements(NS_SCE, "to"), None)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
448 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
449 from_element = cast(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
450 Optional[domish.Element],
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
451 next(envelope.elements(NS_SCE, "from"), None)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
452 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
453
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
454 # The rpad doesn't need verification.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
455 rpad_value = None if rpad_element is None else str(rpad_element)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
456
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
457 # The time affix isn't verified other than that the timestamp is parseable.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
458 try:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
459 timestamp_value = None if time_element is None else \
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
460 XEP_0082.parse_datetime(time_element["stamp"])
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
461 except ValueError as e:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
462 raise AffixVerificationFailed("Malformed time affix") from e
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
463
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
464 # The to affix is verified by comparing the to attribute of the stanza with the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
465 # JID referenced by the affix. Note that only bare JIDs are compared as per the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
466 # specification.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
467 recipient_value: Optional[jid.JID] = None
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
468 if to_element is not None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
469 recipient_value = jid.JID(to_element["jid"])
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
470
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
471 recipient_actual = cast(Optional[str], stanza.getAttribute("to", None))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
472 if recipient_actual is None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
473 raise AffixVerificationFailed(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
474 "'To' affix is included in the envelope, but the stanza is lacking a"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
475 " 'to' attribute to compare the value to."
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
476 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
477
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
478 recipient_actual_bare_jid = jid.JID(recipient_actual).userhost()
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
479 recipient_target_bare_jid = recipient_value.userhost()
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
480
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
481 if recipient_actual_bare_jid != recipient_target_bare_jid:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
482 raise AffixVerificationFailed(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
483 f"Mismatch between actual and target recipient bare JIDs:"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
484 f" {recipient_actual_bare_jid} vs {recipient_target_bare_jid}."
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
485 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
486
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
487 # The from affix is verified by comparing the from attribute of the stanza with
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
488 # the JID referenced by the affix. Note that only bare JIDs are compared as per
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
489 # the specification.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
490 sender_value: Optional[jid.JID] = None
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
491 if from_element is not None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
492 sender_value = jid.JID(from_element["jid"])
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
493
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
494 sender_actual = cast(Optional[str], stanza.getAttribute("from", None))
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
495 if sender_actual is None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
496 raise AffixVerificationFailed(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
497 "'From' affix is included in the envelope, but the stanza is lacking"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
498 " a 'from' attribute to compare the value to."
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
499 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
500
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
501 sender_actual_bare_jid = jid.JID(sender_actual).userhost()
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
502 sender_target_bare_jid = sender_value.userhost()
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
503
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
504 if sender_actual_bare_jid != sender_target_bare_jid:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
505 raise AffixVerificationFailed(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
506 f"Mismatch between actual and target sender bare JIDs:"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
507 f" {sender_actual_bare_jid} vs {sender_target_bare_jid}."
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
508 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
509
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
510 # Find and verify custom affixes
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
511 custom_values: Dict[SCECustomAffix, domish.Element] = {}
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
512 for affix in custom_affixes:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
513 element_name = affix.element_name
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
514 element = cast(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
515 Optional[domish.Element],
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
516 next(envelope.elements(NS_SCE, element_name), None)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
517 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
518 if element is not None:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
519 affix.verify(stanza, element)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
520 custom_values[affix] = element
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
521
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
522 # Check whether all affixes required by the profile are present
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
523 rpad_missing = \
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
524 profile.rpad_policy is SCEAffixPolicy.REQUIRED and rpad_element is None
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
525 time_missing = \
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
526 profile.time_policy is SCEAffixPolicy.REQUIRED and time_element is None
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
527 to_missing = \
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
528 profile.to_policy is SCEAffixPolicy.REQUIRED and to_element is None
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
529 from_missing = \
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
530 profile.from_policy is SCEAffixPolicy.REQUIRED and from_element is None
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
531 custom_missing = any(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
532 affix not in custom_values
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
533 for affix, policy
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
534 in profile.custom_policies.items()
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
535 if policy is SCEAffixPolicy.REQUIRED
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
536 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
537
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
538 if rpad_missing or time_missing or to_missing or from_missing or custom_missing:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
539 custom_missing_string = ""
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
540 for custom_affix in custom_affixes:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
541 value = "present" if custom_affix in custom_values else "missing"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
542 custom_missing_string += f", [custom]{custom_affix.element_name}={value}"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
543
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
544 raise ProfileRequirementsNotMet(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
545 f"SCE envelope is missing affixes required by the profile {profile}."
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
546 f" Affix presence:"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
547 f" rpad={'missing' if rpad_missing else 'present'}"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
548 f", time={'missing' if time_missing else 'present'}"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
549 f", to={'missing' if to_missing else 'present'}"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
550 f", from={'missing' if from_missing else 'present'}"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
551 + custom_missing_string
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
552 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
553
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
554 # Just for type safety
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
555 content_children = cast(List[Union[domish.Element, str]], content.children)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
556 stanza_children = cast(List[Union[domish.Element, str]], stanza.children)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
557
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
558 # Move elements that are not explicitly forbidden from being encrypted from the
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
559 # content element to the stanza.
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
560 for child in list(cast(Iterator[domish.Element], content.elements())):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
561 if (
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
562 child.uri in XEP_0420.MUST_BE_PLAINTEXT_NAMESPACES
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
563 or (child.uri, child.name) in XEP_0420.MUST_BE_PLAINTEXT_ELEMENTS
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
564 ):
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
565 log.warning(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
566 f"An element that MUST be transferred in plaintext was found in an"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
567 f" SCE envelope: {child.toXml()}"
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
568 )
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
569 else:
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
570 # Remove the child from the content element
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
571 content_children.remove(child)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
572
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
573 # Add the child to the stanza
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
574 stanza_children.append(child)
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
575
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
576 return SCEAffixValues(
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
577 rpad_value,
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
578 timestamp_value,
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
579 recipient_value,
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
580 sender_value,
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
581 custom_values
00212260f659 plugin XEP-0420: Implementation of Stanza Content Encryption:
Syndace <me@syndace.dev>
parents:
diff changeset
582 )