annotate libervia/backend/plugins/plugin_sec_autocrypt.py @ 4351:6a0a081485b8

plugin autocrypt: Autocrypt protocol implementation: Implementation of autocrypt: `autocrypt` header is checked, and if present and no public key is known for the peer, the key is imported. `autocrypt` header is also added to outgoing message (only if an email gateway is detected). For the moment, the JID is use as identifier, but the real email used by gateway should be used in the future. rel 456
author Goffi <goffi@goffi.org>
date Fri, 28 Feb 2025 09:23:35 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4351
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia plugin
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2025 Jérôme Poisson (goffi@goffi.org)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 import base64
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
20 from functools import partial
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from typing import TYPE_CHECKING, cast
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from typing import Literal
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
23
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from pydantic import BaseModel, field_validator
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from twisted.internet import defer
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 from twisted.words.protocols.jabber import jid
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 from twisted.words.xish import domish
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
28
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from libervia.backend.core.constants import Const as C
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from libervia.backend.core.core_types import MessageData, SatXMPPEntity
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 from libervia.backend.core.i18n import _
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 from libervia.backend.core.log import getLogger
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 from libervia.backend.memory import persistent
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 from libervia.backend.plugins.plugin_xep_0106 import XEP_0106
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 from libervia.backend.plugins.plugin_xep_0131 import XEP_0131
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 from libervia.backend.plugins.plugin_xep_0373 import get_gpg_provider
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
37 from libervia.backend.tools.common import regex
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 if TYPE_CHECKING:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 from libervia.backend.core.main import LiberviaBackend
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
41
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 log = getLogger(__name__)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
43
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
44
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 PLUGIN_INFO = {
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 C.PI_NAME: "Autocrypt",
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 C.PI_IMPORT_NAME: "AUTOCRYPT",
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 C.PI_TYPE: C.PLUG_TYPE_SEC,
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 C.PI_MODES: C.PLUG_MODE_BOTH,
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 C.PI_PROTOCOLS: [],
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 C.PI_DEPENDENCIES: ["XEP-0106", "XEP-0131", "XEP-0373"],
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 C.PI_RECOMMENDATIONS: [],
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 C.PI_MAIN: "Autocrypt",
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 C.PI_HANDLER: "no",
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 C.PI_DESCRIPTION: _(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 "Autocrypt support, to automatically encrypt message to email gateways when "
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 "suitable."
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 ),
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
59 }
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
60
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
61
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 class AutocryptHeaderParseError(ValueError):
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 """Raised when Autocrypt header parsing fails"""
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
64
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
65
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 class AutocryptData(BaseModel):
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 """Parsed Autocrypt header data.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
68
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 @param addr: Email address for the key.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 @param keydata: Base64-encoded public key.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 @param prefer_encrypt: Encryption preference hint.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 """
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
73
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
74 addr: str
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 keydata: str
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 prefer_encrypt: Literal["mutual"] | None = None
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
77
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 @field_validator("addr")
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 @classmethod
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 def check_email(cls, value):
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 value = value.strip()
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 if not regex.RE_EMAIL.match(value):
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 raise ValueError("Invalid email address")
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 return value
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
85
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 @field_validator("keydata")
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 @classmethod
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 def validate_keydata(cls, value: str) -> str:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 """Validate keydata is proper base64"""
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 try:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 base64.b64decode(value, validate=True)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 except ValueError as e:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 raise ValueError("Invalid base64 in keydata") from e
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 return value.strip()
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
95
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
96 def to_header(self) -> str:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
97 """Generate the Autocrypt header.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
98
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
99 @return: Formatted header value per Autocrypt specification.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
100 """
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
101 parts = [f"addr={self.addr}", f"keydata={self.keydata}"]
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
102
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
103 if self.prefer_encrypt is not None:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
104 parts.append(f"prefer-encrypt={self.prefer_encrypt}")
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
105
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
106 return "; ".join(parts)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
107
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
108
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
109 def parse_autocrypt_header(header: str) -> AutocryptData:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
110 """Parse an Autocrypt header.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
111
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
112 @param header: Raw Autocrypt header value
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
113 @return: Parsed AutocryptData.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
114 @raise AutocryptHeaderParseError: Some required field is invalid or missing.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
115 """
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
116 attributes = {}
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
117 for part in header.split(";"):
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
118 part = part.strip()
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
119 if not part:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
120 continue
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
121 if "=" not in part:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
122 # Ignore invalid parts
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
123 continue
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
124 key, value = part.split("=", 1)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
125 key = key.strip().lower()
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
126 value = value.strip()
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
127
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
128 if key in {"addr", "keydata", "prefer-encrypt"}:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
129 attributes[key] = value
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
130
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
131 if not attributes.get("addr"):
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
132 raise AutocryptHeaderParseError('Missing required "addr" attribute')
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
133 if not attributes.get("keydata"):
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
134 raise AutocryptHeaderParseError('Missing required "keydata" attribute')
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
135
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
136 try:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
137 return AutocryptData(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
138 addr=attributes["addr"],
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
139 keydata=attributes["keydata"],
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
140 prefer_encrypt=attributes.get("prefer-encrypt"),
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
141 )
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
142 except ValueError as e:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
143 raise AutocryptHeaderParseError(f"Invalid Autocrypt header: {e}") from e
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
144
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
145
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
146 class Autocrypt:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
147
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
148 def __init__(self, host: "LiberviaBackend") -> None:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
149 self.host = host
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
150 log.info(f"plugin {PLUGIN_INFO[C.PI_NAME]!r} initialization")
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
151 self._shim = cast(XEP_0131, host.plugins["XEP-0131"])
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
152 self._e = cast(XEP_0106, host.plugins["XEP-0106"])
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
153 host.trigger.add("message_received", self.message_received_trigger)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
154 host.trigger.add("sendMessage", self.send_message_trigger)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
155
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
156 def profile_connecting(self, client: SatXMPPEntity) -> None:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
157 # Sender already handled.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
158 client._autocrypt_seen: set[str] = set()
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
159 client._autocrypt_gpg_provider = get_gpg_provider(self.host, client)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
160
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
161 async def handle_autocrypt_data(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
162 self, client: SatXMPPEntity, mess_data: MessageData, autocrypt_data_raw: str
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
163 ) -> None:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
164 """Process Autocrypt header from XMPP email gateway
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
165
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
166 @param client: Client session.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
167 @param mess_data: Message data.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
168 @param autocrypt_data: Raw Autocrypt header value
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
169 @raise AutocryptHeaderParseError: For invalid header format
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
170 """
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
171 from_jid = mess_data["from"]
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
172 to_jid = mess_data["to"]
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
173 is_email_gateway = await self.host.memory.disco.has_identity(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
174 client, "gateway", "smtp", jid.JID(to_jid.host)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
175 )
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
176 if to_jid.resource or not is_email_gateway:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
177 log.warning("Ignoring Autocrypt header from non email gateway.")
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
178 return
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
179
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
180 try:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
181 autocrypt_data = parse_autocrypt_header(autocrypt_data_raw)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
182 except AutocryptHeaderParseError as e:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
183 log.error(f"Invalid Autocrypt header: {e}")
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
184 return
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
185
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
186 sender_email = self._e.unescape(from_jid.user)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
187 if sender_email != autocrypt_data.addr:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
188 log.warning(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
189 f"Sender email ({sender_email!r}) doesn't match autocrypt header address"
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
190 f" ({autocrypt_data.addr!r}), ignoring autocrypt data."
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
191 )
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
192 return
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
193
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
194 if sender_email in client._autocrypt_seen:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
195 log.debug(f"We have already handled {sender_email!r} , nothing to do.")
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
196 return None
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
197 gpg_provider = client._autocrypt_gpg_provider
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
198 public_keys = gpg_provider.list_public_keys(sender_email)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
199 if not public_keys:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
200 log.debug(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
201 f"No public key found for {sender_email!r}, importing autocrypt data."
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
202 )
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
203 # FIXME: Maybe we should import the Autocrypt key in a separated location?
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
204 # Autocrypt is less secure than normal key management.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
205 gpg_provider.import_public_key(base64.b64decode(autocrypt_data.keydata))
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
206 else:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
207 log.debug(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
208 f"There are already known public key for {sender_email}, we skipt "
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
209 "autocrypt"
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
210 )
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
211 client._autocrypt_seen.add(sender_email)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
212
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
213 def _check_headers(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
214 self, client: SatXMPPEntity, mess_data: MessageData
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
215 ) -> MessageData:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
216 try:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
217 autocrypt_data = mess_data["extra"]["headers"]["autocrypt"]
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
218 except KeyError:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
219 pass
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
220 else:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
221 defer.ensureDeferred(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
222 self.handle_autocrypt_data(client, mess_data, autocrypt_data)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
223 )
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
224 return mess_data
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
225
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
226 def message_received_trigger(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
227 self,
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
228 client: SatXMPPEntity,
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
229 message_elt: domish.Element,
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
230 post_treat: defer.Deferred,
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
231 ) -> Literal[True]:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
232 post_treat.addCallback(partial(self._check_headers, client))
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
233 return True
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
234
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
235 async def add_autocrypt_header(self, client, mess_data: MessageData) -> MessageData:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
236 to_jid = mess_data["to"]
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
237 if await self.host.memory.disco.has_identity(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
238 client, "gateway", "smtp", jid.JID(to_jid.host)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
239 ):
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
240 gpg_provider = client._autocrypt_gpg_provider
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
241 # FIXME! We currently use from jid as email, but we would need to get sender
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
242 # email from gateway instead, as we don't know what is actually used, and it
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
243 # may differ from the JID.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
244 sender_email = mess_data["from"].userhost()
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
245 try:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
246 public_key = next(iter(gpg_provider.list_public_keys(sender_email)))
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
247 except StopIteration:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
248 log.debug("No public key found, can't set autocrypt header.")
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
249 return mess_data
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
250
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
251 exported_key = gpg_provider.export_public_key(public_key)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
252 autocrypt_data = AutocryptData(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
253 addr=sender_email,
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
254 keydata=base64.b64encode(exported_key).decode("ascii"),
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
255 prefer_encrypt="mutual",
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
256 )
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
257
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
258 mess_data["extra"].setdefault("headers", {})[
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
259 "autocrypt"
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
260 ] = autocrypt_data.to_header()
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
261 return mess_data
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
262
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
263 def send_message_trigger(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
264 self, client, mess_data, pre_xml_treatments, post_xml_treatments
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
265 ) -> Literal[True]:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
266 """Process the XEP-0131 related data to be sent"""
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
267
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
268 def add_headers(mess_data: MessageData) -> MessageData:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
269 extra = mess_data["extra"]
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
270 self.move_keywords_to_headers(extra)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
271 # Now we parse headers, if any.
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
272 if "headers" in extra:
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
273 headers_data = HeadersData(**extra["headers"])
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
274 message_elt = mess_data["xml"]
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
275 message_elt.addChild(headers_data.to_element())
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
276 return mess_data
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
277
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
278 post_xml_treatments.addCallback(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
279 lambda mess_data: defer.ensureDeferred(
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
280 self.add_autocrypt_header(client, mess_data)
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
281 )
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
282 )
6a0a081485b8 plugin autocrypt: Autocrypt protocol implementation:
Goffi <goffi@goffi.org>
parents:
diff changeset
283 return True