From 65e879733a1a0fa9c81cf7875ae02cfa4c42feb4 Mon Sep 17 00:00:00 2001 From: Jude Nelson Date: Tue, 30 May 2017 20:29:32 -0400 Subject: [PATCH] fix some bugs found from testing, and close #440 --- blockstack_client/data.py | 13 +++++++++++-- blockstack_client/rpc.py | 12 ++++++------ blockstack_client/storage.py | 19 +++++++++++++++++-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/blockstack_client/data.py b/blockstack_client/data.py index a67e67d44..a4060a90e 100644 --- a/blockstack_client/data.py +++ b/blockstack_client/data.py @@ -1401,7 +1401,11 @@ def sign_datastore_info( datastore_info, datastore_privkey_hex, config_path=CONF root_tombstones = make_inode_tombstones( datastore_id, root_uuid, device_ids ) signed_tombstones = sign_mutable_data_tombstones( root_tombstones, datastore_privkey_hex ) - return {'datastore_sig': datastore_sig, 'root_sig': root_sig, 'root_tombstones': signed_tombstones} + ret = {'datastore_sig': datastore_sig, 'root_sig': root_sig, 'root_tombstones': signed_tombstones} + if BLOCKSTACK_TEST: + assert verify_datastore_info(datastore_info, ret, get_pubkey_hex(datastore_privkey_hex), config_path=config_path) + + return ret def verify_datastore_info( datastore_info, sigs, datastore_pubkey_hex, config_path=CONFIG_PATH ): @@ -1419,6 +1423,9 @@ def verify_datastore_info( datastore_info, sigs, datastore_pubkey_hex, config_pa res = storage.verify_data_payload( datastore_info['datastore_blob'], datastore_pubkey_hex, sigs['datastore_sig'] ) if not res: log.debug("Failed to verify datastore blob payload with {} and {}".format(datastore_pubkey_hex, sigs['datastore_sig'])) + if BLOCKSTACK_TEST: + log.debug("datastore_info: {}".format(json.dumps(datastore_info))) + return False res = storage.verify_data_payload( datastore_info['root_blob_header'], datastore_pubkey_hex, sigs['root_sig'] ) @@ -3254,7 +3261,9 @@ def datastore_deletefile_make_inodes(api_client, datastore, data_path, data_pubk min_version = max(parent_dir_inode['version'], dead_child['version']) # update the parent - parent_dir_info = make_dir_inode_data( datastore_id, datastore_id, parent_dir_uuid, parent_dir_inode['idata']['children'], device_ids, reader_pubkeys=parent_dir_inode['reader_pubkeys'], min_version=min_version, config_path=config_path ) + parent_dir_info = make_dir_inode_data( datastore_id, datastore_id, parent_dir_uuid, parent_dir_inode['idata']['children'], device_ids, + reader_pubkeys=parent_dir_inode['reader_pubkeys'], min_version=min_version, config_path=config_path ) + if 'error' in parent_dir_info: log.error("Failed to update directory {}: {}".format(dir_path, parent_dir_info['error'])) return {'error': 'Failed to create parent directory', 'errno': errno.EIO} diff --git a/blockstack_client/rpc.py b/blockstack_client/rpc.py index b5f9957db..5b68c3c18 100644 --- a/blockstack_client/rpc.py +++ b/blockstack_client/rpc.py @@ -3240,9 +3240,9 @@ class BlockstackAPIEndpointHandler(SimpleHTTPRequestHandler): 'GET': { 'name': '', 'desc': 'Get an app user\'s datastore metadata', - 'auth_session': True, - 'auth_pass': True, - 'need_data_key': True, + 'auth_session': False, + 'auth_pass': False, + 'need_data_key': False, }, }, }, @@ -3257,9 +3257,9 @@ class BlockstackAPIEndpointHandler(SimpleHTTPRequestHandler): 'GET': { 'name': '', 'desc': 'read files and list directories in the app user\'s data store', - 'auth_session': True, - 'auth_pass': True, - 'need_data_key': True, + 'auth_session': False, + 'auth_pass': False, + 'need_data_key': False, }, 'POST': { 'name': 'store_write', diff --git a/blockstack_client/storage.py b/blockstack_client/storage.py index 30ba63e5f..fe481136a 100644 --- a/blockstack_client/storage.py +++ b/blockstack_client/storage.py @@ -252,7 +252,12 @@ def parse_data_tombstone( signed_tombstone ): if not tombstone_data.startswith('delete-'): return {'error': 'Missing `delete` crib'} - tombstone_payload = tombstone_data[len('delete:'):] + # strip `delete-${timestamp}:` + tombstone_payload_parts = tombstone_data.split(':', 1) + if len(tombstone_payload_parts) != 2: + return {'error': 'Invalid `delete` crib'} + + tombstone_payload = tombstone_payload_parts[1] return {'tombstone_payload': tombstone_payload, 'sigb64': sigb64} @@ -736,6 +741,16 @@ def get_mutable_data(fq_data_id, data_pubkey, urls=None, data_address=None, data h for h in storage_handlers if h.__name__ == d ) + # ripemd160(sha256(pubkey)) + data_pubkey_hashes = [] + for a in filter(lambda x: x is not None, [data_address, owner_address]): + try: + h = keylib.b58check.b58check_decode(str(a)).encode('hex') + data_pubkey_hashes.append(h) + except: + log.debug("Invalid address '{}'".format(a)) + continue + log.debug('get_mutable_data {} fqu={} bsk_version={}'.format(fq_data_id, fqu, bsk_version)) for storage_handler in handlers_to_use: if not getattr(storage_handler, 'get_mutable_handler', None): @@ -782,7 +797,7 @@ def get_mutable_data(fq_data_id, data_pubkey, urls=None, data_address=None, data log.debug('Try {} ({})'.format(storage_handler.__name__, url)) try: - data_txt = storage_handler.get_mutable_handler(url, fqu=fqu) + data_txt = storage_handler.get_mutable_handler(url, fqu=fqu, data_pubkey=data_pubkey, data_pubkey_hashes=data_pubkey_hashes) except UnhandledURLException as uue: # handler doesn't handle this URL msg = 'Storage handler {} does not handle URLs like {}'