Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 978f263

Browse files
committed
Use the v2 lookup API for 3PID invites (#5897)
2 parents 4f6ee99 + 71fc040 commit 978f263

File tree

10 files changed

+320
-183
lines changed

10 files changed

+320
-183
lines changed

changelog.d/5897.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Switch to the v2 lookup API for 3PID invites.

synapse/events/spamcheck.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
1716
class SpamChecker(object):
1817
def __init__(self, hs):
1918
self.spam_checker = None

synapse/handlers/identity.py

Lines changed: 34 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,13 @@
2020
import logging
2121

2222
from canonicaljson import json
23-
from signedjson.key import decode_verify_key_bytes
24-
from signedjson.sign import verify_signed_json
25-
from unpaddedbase64 import decode_base64
2623

2724
from twisted.internet import defer
2825

2926
from synapse.api.errors import (
30-
AuthError,
3127
CodeMessageException,
3228
Codes,
3329
HttpResponseException,
34-
ProxiedRequestError,
3530
SynapseError,
3631
)
3732

@@ -48,26 +43,9 @@ def __init__(self, hs):
4843
self.federation_http_client = hs.get_http_client()
4944

5045
self.trusted_id_servers = set(hs.config.trusted_third_party_id_servers)
51-
self.trust_any_id_server_just_for_testing_do_not_use = (
52-
hs.config.use_insecure_ssl_client_just_for_testing_do_not_use
53-
)
5446
self.rewrite_identity_server_urls = hs.config.rewrite_identity_server_urls
5547
self._enable_lookup = hs.config.enable_3pid_lookup
5648

57-
def _should_trust_id_server(self, id_server):
58-
if id_server not in self.trusted_id_servers:
59-
if self.trust_any_id_server_just_for_testing_do_not_use:
60-
logger.warn(
61-
"Trusting untrustworthy ID server %r even though it isn't"
62-
" in the trusted id list for testing because"
63-
" 'use_insecure_ssl_client_just_for_testing_do_not_use'"
64-
" is set in the config",
65-
id_server,
66-
)
67-
else:
68-
return False
69-
return True
70-
7149
@defer.inlineCallbacks
7250
def threepid_from_creds(self, creds):
7351
if "id_server" in creds:
@@ -84,16 +62,17 @@ def threepid_from_creds(self, creds):
8462
else:
8563
raise SynapseError(400, "No client_secret in creds")
8664

87-
if not self._should_trust_id_server(id_server):
65+
if not should_trust_id_server(self.hs, id_server):
8866
logger.warn(
8967
"%s is not a trusted ID server: rejecting 3pid " + "credentials",
9068
id_server,
9169
)
9270
return None
71+
9372
# if we have a rewrite rule set for the identity server,
9473
# apply it now.
95-
if id_server in self.rewrite_identity_server_urls:
96-
id_server = self.rewrite_identity_server_urls[id_server]
74+
id_server = self.rewrite_identity_server_urls.get(id_server, id_server)
75+
9776
try:
9877
data = yield self.http_client.get_json(
9978
"https://%s%s"
@@ -130,10 +109,7 @@ def bind_threepid(self, creds, mxid):
130109
# if we have a rewrite rule set for the identity server,
131110
# apply it now, but only for sending the request (not
132111
# storing in the database).
133-
if id_server in self.rewrite_identity_server_urls:
134-
id_server_host = self.rewrite_identity_server_urls[id_server]
135-
else:
136-
id_server_host = id_server
112+
id_server_host = self.rewrite_identity_server_urls.get(id_server, id_server)
137113

138114
try:
139115
data = yield self.http_client.post_json_get_json(
@@ -205,7 +181,6 @@ def try_unbind_threepid_with_id_server(self, mxid, threepid, id_server):
205181
Deferred[bool]: True on success, otherwise False if the identity
206182
server doesn't support unbinding
207183
"""
208-
url = "https://%s/_matrix/identity/api/v1/3pid/unbind" % (id_server,)
209184
content = {
210185
"mxid": mxid,
211186
"threepid": {"medium": threepid["medium"], "address": threepid["address"]},
@@ -228,8 +203,7 @@ def try_unbind_threepid_with_id_server(self, mxid, threepid, id_server):
228203
#
229204
# Note that destination_is has to be the real id_server, not
230205
# the server we connect to.
231-
if id_server in self.rewrite_identity_server_urls:
232-
id_server = self.rewrite_identity_server_urls[id_server]
206+
id_server = self.rewrite_identity_server_urls.get(id_server, id_server)
233207

234208
url = "https://%s/_matrix/identity/api/v1/3pid/unbind" % (id_server,)
235209

@@ -258,7 +232,7 @@ def try_unbind_threepid_with_id_server(self, mxid, threepid, id_server):
258232
def requestEmailToken(
259233
self, id_server, email, client_secret, send_attempt, next_link=None
260234
):
261-
if not self._should_trust_id_server(id_server):
235+
if not should_trust_id_server(self.hs, id_server):
262236
raise SynapseError(
263237
400, "Untrusted ID server '%s'" % id_server, Codes.SERVER_NOT_TRUSTED
264238
)
@@ -269,10 +243,8 @@ def requestEmailToken(
269243
"send_attempt": send_attempt,
270244
}
271245

272-
# if we have a rewrite rule set for the identity server,
273-
# apply it now.
274-
if id_server in self.rewrite_identity_server_urls:
275-
id_server = self.rewrite_identity_server_urls[id_server]
246+
# Rewrite id_server URL if necessary
247+
id_server = self.rewrite_identity_server_urls.get(id_server, id_server)
276248

277249
if next_link:
278250
params.update({"next_link": next_link})
@@ -292,11 +264,14 @@ def requestEmailToken(
292264
def requestMsisdnToken(
293265
self, id_server, country, phone_number, client_secret, send_attempt, **kwargs
294266
):
295-
if not self._should_trust_id_server(id_server):
267+
if not should_trust_id_server(self.hs, id_server):
296268
raise SynapseError(
297269
400, "Untrusted ID server '%s'" % id_server, Codes.SERVER_NOT_TRUSTED
298270
)
299271

272+
# Rewrite id_server URL if necessary
273+
id_server = self.rewrite_identity_server_urls.get(id_server, id_server)
274+
300275
params = {
301276
"country": country,
302277
"phone_number": phone_number,
@@ -319,119 +294,30 @@ def requestMsisdnToken(
319294
logger.info("Proxied requestToken failed: %r", e)
320295
raise e.to_synapse_error()
321296

322-
@defer.inlineCallbacks
323-
def lookup_3pid(self, id_server, medium, address):
324-
"""Looks up a 3pid in the passed identity server.
325-
326-
Args:
327-
id_server (str): The server name (including port, if required)
328-
of the identity server to use.
329-
medium (str): The type of the third party identifier (e.g. "email").
330-
address (str): The third party identifier (e.g. "[email protected]").
331-
332-
Returns:
333-
Deferred[dict]: The result of the lookup. See
334-
https://matrix.org/docs/spec/identity_service/r0.1.0.html#association-lookup
335-
for details
336-
"""
337-
if not self._should_trust_id_server(id_server):
338-
raise SynapseError(
339-
400, "Untrusted ID server '%s'" % id_server, Codes.SERVER_NOT_TRUSTED
340-
)
341-
342-
if not self._enable_lookup:
343-
raise AuthError(
344-
403, "Looking up third-party identifiers is denied from this server"
345-
)
346-
347-
target = self.rewrite_identity_server_urls.get(id_server, id_server)
348-
349-
try:
350-
data = yield self.http_client.get_json(
351-
"https://%s/_matrix/identity/api/v1/lookup" % (target,),
352-
{"medium": medium, "address": address},
353-
)
354297

355-
if "mxid" in data:
356-
if "signatures" not in data:
357-
raise AuthError(401, "No signatures on 3pid binding")
358-
yield self._verify_any_signature(data, id_server)
359-
360-
except HttpResponseException as e:
361-
logger.info("Proxied lookup failed: %r", e)
362-
raise e.to_synapse_error()
363-
except IOError as e:
364-
logger.info("Failed to contact %r: %s", id_server, e)
365-
raise ProxiedRequestError(503, "Failed to contact identity server")
366-
367-
defer.returnValue(data)
368-
369-
@defer.inlineCallbacks
370-
def bulk_lookup_3pid(self, id_server, threepids):
371-
"""Looks up given 3pids in the passed identity server.
372-
373-
Args:
374-
id_server (str): The server name (including port, if required)
375-
of the identity server to use.
376-
threepids ([[str, str]]): The third party identifiers to lookup, as
377-
a list of 2-string sized lists ([medium, address]).
378-
379-
Returns:
380-
Deferred[dict]: The result of the lookup. See
381-
https://matrix.org/docs/spec/identity_service/r0.1.0.html#association-lookup
382-
for details
383-
"""
384-
if not self._should_trust_id_server(id_server):
385-
raise SynapseError(
386-
400, "Untrusted ID server '%s'" % id_server, Codes.SERVER_NOT_TRUSTED
387-
)
388-
389-
if not self._enable_lookup:
390-
raise AuthError(
391-
403, "Looking up third-party identifiers is denied from this server"
392-
)
393-
394-
target = self.rewrite_identity_server_urls.get(id_server, id_server)
395-
396-
try:
397-
data = yield self.http_client.post_json_get_json(
398-
"https://%s/_matrix/identity/api/v1/bulk_lookup" % (target,),
399-
{"threepids": threepids},
298+
def should_trust_id_server(hs, id_server):
299+
if id_server not in hs.config.trusted_third_party_id_servers:
300+
if hs.trust_any_id_server_just_for_testing_do_not_use:
301+
logger.warn(
302+
"Trusting untrustworthy ID server %r even though it isn't"
303+
" in the trusted id list for testing because"
304+
" 'use_insecure_ssl_client_just_for_testing_do_not_use'"
305+
" is set in the config",
306+
id_server,
400307
)
308+
else:
309+
return False
310+
return True
401311

402-
except HttpResponseException as e:
403-
logger.info("Proxied lookup failed: %r", e)
404-
raise e.to_synapse_error()
405-
except IOError as e:
406-
logger.info("Failed to contact %r: %s", id_server, e)
407-
raise ProxiedRequestError(503, "Failed to contact identity server")
408-
409-
defer.returnValue(data)
410-
411-
@defer.inlineCallbacks
412-
def _verify_any_signature(self, data, server_hostname):
413-
if server_hostname not in data["signatures"]:
414-
raise AuthError(401, "No signature from server %s" % (server_hostname,))
415312

416-
for key_name, signature in data["signatures"][server_hostname].items():
417-
target = self.rewrite_identity_server_urls.get(
418-
server_hostname, server_hostname
419-
)
313+
class LookupAlgorithm:
314+
"""
315+
Supported hashing algorithms when performing a 3PID lookup.
420316
421-
key_data = yield self.http_client.get_json(
422-
"https://%s/_matrix/identity/api/v1/pubkey/%s" % (target, key_name)
423-
)
424-
if "public_key" not in key_data:
425-
raise AuthError(
426-
401, "No public key named %s from %s" % (key_name, server_hostname)
427-
)
428-
verify_signed_json(
429-
data,
430-
server_hostname,
431-
decode_verify_key_bytes(
432-
key_name, decode_base64(key_data["public_key"])
433-
),
434-
)
435-
return
317+
SHA256 - Hashing an (address, medium, pepper) combo with sha256, then url-safe base64
318+
encoding
319+
NONE - Not performing any hashing. Simply sending an (address, medium) combo in plaintext
320+
"""
436321

437-
raise AuthError(401, "No signature from server %s" % (server_hostname,))
322+
SHA256 = "sha256"
323+
NONE = "none"

0 commit comments

Comments
 (0)