2020import logging
2121
2222from 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
2724from twisted .internet import defer
2825
2926from 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