|
|
|
@ -116,43 +116,42 @@ class Keyring(object): |
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks |
|
|
|
|
def handle_key_deferred(verify_request): |
|
|
|
|
with Measure(self.clock, "handle_key_deferred"): |
|
|
|
|
server_name = verify_request.server_name |
|
|
|
|
try: |
|
|
|
|
_, key_id, verify_key = yield verify_request.deferred |
|
|
|
|
except IOError as e: |
|
|
|
|
logger.warn( |
|
|
|
|
"Got IOError when downloading keys for %s: %s %s", |
|
|
|
|
server_name, type(e).__name__, str(e.message), |
|
|
|
|
) |
|
|
|
|
raise SynapseError( |
|
|
|
|
502, |
|
|
|
|
"Error downloading keys for %s" % (server_name,), |
|
|
|
|
Codes.UNAUTHORIZED, |
|
|
|
|
) |
|
|
|
|
except Exception as e: |
|
|
|
|
logger.exception( |
|
|
|
|
"Got Exception when downloading keys for %s: %s %s", |
|
|
|
|
server_name, type(e).__name__, str(e.message), |
|
|
|
|
) |
|
|
|
|
raise SynapseError( |
|
|
|
|
401, |
|
|
|
|
"No key for %s with id %s" % (server_name, key_ids), |
|
|
|
|
Codes.UNAUTHORIZED, |
|
|
|
|
) |
|
|
|
|
server_name = verify_request.server_name |
|
|
|
|
try: |
|
|
|
|
_, key_id, verify_key = yield verify_request.deferred |
|
|
|
|
except IOError as e: |
|
|
|
|
logger.warn( |
|
|
|
|
"Got IOError when downloading keys for %s: %s %s", |
|
|
|
|
server_name, type(e).__name__, str(e.message), |
|
|
|
|
) |
|
|
|
|
raise SynapseError( |
|
|
|
|
502, |
|
|
|
|
"Error downloading keys for %s" % (server_name,), |
|
|
|
|
Codes.UNAUTHORIZED, |
|
|
|
|
) |
|
|
|
|
except Exception as e: |
|
|
|
|
logger.exception( |
|
|
|
|
"Got Exception when downloading keys for %s: %s %s", |
|
|
|
|
server_name, type(e).__name__, str(e.message), |
|
|
|
|
) |
|
|
|
|
raise SynapseError( |
|
|
|
|
401, |
|
|
|
|
"No key for %s with id %s" % (server_name, key_ids), |
|
|
|
|
Codes.UNAUTHORIZED, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
json_object = verify_request.json_object |
|
|
|
|
json_object = verify_request.json_object |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
verify_signed_json(json_object, server_name, verify_key) |
|
|
|
|
except: |
|
|
|
|
raise SynapseError( |
|
|
|
|
401, |
|
|
|
|
"Invalid signature for server %s with key %s:%s" % ( |
|
|
|
|
server_name, verify_key.alg, verify_key.version |
|
|
|
|
), |
|
|
|
|
Codes.UNAUTHORIZED, |
|
|
|
|
) |
|
|
|
|
try: |
|
|
|
|
verify_signed_json(json_object, server_name, verify_key) |
|
|
|
|
except: |
|
|
|
|
raise SynapseError( |
|
|
|
|
401, |
|
|
|
|
"Invalid signature for server %s with key %s:%s" % ( |
|
|
|
|
server_name, verify_key.alg, verify_key.version |
|
|
|
|
), |
|
|
|
|
Codes.UNAUTHORIZED, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
server_to_deferred = { |
|
|
|
|
server_name: defer.Deferred() |
|
|
|
@ -245,59 +244,60 @@ class Keyring(object): |
|
|
|
|
|
|
|
|
|
@defer.inlineCallbacks |
|
|
|
|
def do_iterations(): |
|
|
|
|
merged_results = {} |
|
|
|
|
|
|
|
|
|
missing_keys = {} |
|
|
|
|
for verify_request in verify_requests: |
|
|
|
|
missing_keys.setdefault(verify_request.server_name, set()).update( |
|
|
|
|
verify_request.key_ids |
|
|
|
|
) |
|
|
|
|
with Measure(self.clock, "get_server_verify_keys"): |
|
|
|
|
merged_results = {} |
|
|
|
|
|
|
|
|
|
for fn in key_fetch_fns: |
|
|
|
|
results = yield fn(missing_keys.items()) |
|
|
|
|
merged_results.update(results) |
|
|
|
|
|
|
|
|
|
# We now need to figure out which verify requests we have keys |
|
|
|
|
# for and which we don't |
|
|
|
|
missing_keys = {} |
|
|
|
|
requests_missing_keys = [] |
|
|
|
|
for verify_request in verify_requests: |
|
|
|
|
server_name = verify_request.server_name |
|
|
|
|
result_keys = merged_results[server_name] |
|
|
|
|
|
|
|
|
|
if verify_request.deferred.called: |
|
|
|
|
# We've already called this deferred, which probably |
|
|
|
|
# means that we've already found a key for it. |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
for key_id in verify_request.key_ids: |
|
|
|
|
if key_id in result_keys: |
|
|
|
|
with PreserveLoggingContext(): |
|
|
|
|
verify_request.deferred.callback(( |
|
|
|
|
server_name, |
|
|
|
|
key_id, |
|
|
|
|
result_keys[key_id], |
|
|
|
|
)) |
|
|
|
|
break |
|
|
|
|
else: |
|
|
|
|
# The else block is only reached if the loop above |
|
|
|
|
# doesn't break. |
|
|
|
|
missing_keys.setdefault(server_name, set()).update( |
|
|
|
|
verify_request.key_ids |
|
|
|
|
) |
|
|
|
|
requests_missing_keys.append(verify_request) |
|
|
|
|
|
|
|
|
|
if not missing_keys: |
|
|
|
|
break |
|
|
|
|
|
|
|
|
|
for verify_request in requests_missing_keys.values(): |
|
|
|
|
verify_request.deferred.errback(SynapseError( |
|
|
|
|
401, |
|
|
|
|
"No key for %s with id %s" % ( |
|
|
|
|
verify_request.server_name, verify_request.key_ids, |
|
|
|
|
), |
|
|
|
|
Codes.UNAUTHORIZED, |
|
|
|
|
)) |
|
|
|
|
missing_keys.setdefault(verify_request.server_name, set()).update( |
|
|
|
|
verify_request.key_ids |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
for fn in key_fetch_fns: |
|
|
|
|
results = yield fn(missing_keys.items()) |
|
|
|
|
merged_results.update(results) |
|
|
|
|
|
|
|
|
|
# We now need to figure out which verify requests we have keys |
|
|
|
|
# for and which we don't |
|
|
|
|
missing_keys = {} |
|
|
|
|
requests_missing_keys = [] |
|
|
|
|
for verify_request in verify_requests: |
|
|
|
|
server_name = verify_request.server_name |
|
|
|
|
result_keys = merged_results[server_name] |
|
|
|
|
|
|
|
|
|
if verify_request.deferred.called: |
|
|
|
|
# We've already called this deferred, which probably |
|
|
|
|
# means that we've already found a key for it. |
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
for key_id in verify_request.key_ids: |
|
|
|
|
if key_id in result_keys: |
|
|
|
|
with PreserveLoggingContext(): |
|
|
|
|
verify_request.deferred.callback(( |
|
|
|
|
server_name, |
|
|
|
|
key_id, |
|
|
|
|
result_keys[key_id], |
|
|
|
|
)) |
|
|
|
|
break |
|
|
|
|
else: |
|
|
|
|
# The else block is only reached if the loop above |
|
|
|
|
# doesn't break. |
|
|
|
|
missing_keys.setdefault(server_name, set()).update( |
|
|
|
|
verify_request.key_ids |
|
|
|
|
) |
|
|
|
|
requests_missing_keys.append(verify_request) |
|
|
|
|
|
|
|
|
|
if not missing_keys: |
|
|
|
|
break |
|
|
|
|
|
|
|
|
|
for verify_request in requests_missing_keys.values(): |
|
|
|
|
verify_request.deferred.errback(SynapseError( |
|
|
|
|
401, |
|
|
|
|
"No key for %s with id %s" % ( |
|
|
|
|
verify_request.server_name, verify_request.key_ids, |
|
|
|
|
), |
|
|
|
|
Codes.UNAUTHORIZED, |
|
|
|
|
)) |
|
|
|
|
|
|
|
|
|
def on_err(err): |
|
|
|
|
for verify_request in verify_requests: |
|
|
|
|