diff --git a/onionr/communicator2.py b/onionr/communicator2.py index 1aabc9fc..98d1aecd 100755 --- a/onionr/communicator2.py +++ b/onionr/communicator2.py @@ -134,15 +134,18 @@ class OnionrCommunicatorDaemon: content = base64.b64decode(content) if self._core._crypto.sha3Hash(content) == blockHash: content = content.decode() # decode here because sha3Hash needs bytes above - metas = self._core._utils.getBlockMetadataFromData(content) + metas = self._core._utils.getBlockMetadataFromData(content) # returns tuple(metadata, meta), meta is also in metadata metadata = metas[0] meta = metas[1] - if self._core._crypto.verifyPow(metas[2], metadata) and self._core._utils.validateMetadata(metadata): - logger.info('Block passed proof, saving.') - self._core.setData(content) - self._core.addToBlockDB(blockHash, dataSaved=True) + if self._core._utils.validateMetadata(metadata): + if self._core._crypto.verifyPow(metas[2], metadata): + logger.info('Block passed proof, saving.') + self._core.setData(content) + self._core.addToBlockDB(blockHash, dataSaved=True) + else: + logger.warn('POW failed for block ' + blockHash) else: - logger.warn('POW failed for block ' + blockHash) + logger.warn('Metadata for ' + blockHash + ' is invalid.') self.blockQueue.remove(blockHash) else: logger.warn('Block hash validation failed for ' + blockHash + ' got ' + self._core._crypto.sha3Hash(content)) diff --git a/onionr/onionrutils.py b/onionr/onionrutils.py index 77323633..84225b04 100644 --- a/onionr/onionrutils.py +++ b/onionr/onionrutils.py @@ -18,7 +18,7 @@ along with this program. If not, see . ''' # Misc functions that do not fit in the main api, but are useful -import getpass, sys, requests, os, socket, hashlib, logger, sqlite3, config, binascii, time, base64, json, glob, shutil, math +import getpass, sys, requests, os, socket, hashlib, logger, sqlite3, config, binascii, time, base64, json, glob, shutil, math, json import nacl.signing, nacl.encoding from onionrblockapi import Block import onionrexceptions @@ -313,7 +313,34 @@ class OnionrUtils: def validateMetadata(metadata): '''Validate metadata meets onionr spec (does not validate proof value computation), take in either dictionary or json string''' # TODO, make this check sane sizes - return True + retData = False + + # convert to dict if it is json string + if type(metadata) is str: + try: + metadata = json.loads(metadata) + except json.JSONDecodeError: + pass + + # Validate metadata dict for invalid keys to sizes that are too large + if type(metadata) is dict: + for i in metadata: + try: + self._core.requirements.blockMetadataLengths[i] + except KeyError: + logger.warn('Block has invalid metadata key ' + i) + break + else: + if self._core.requirements.blockMetadataLengths[i] < len(metadata[i]): + logger.warn('Block metadata key ' + i + ' exceeded maximum size') + break + else: + # if metadata loop gets no errors, it does not break, therefore metadata is valid + retData = True + else: + logger.warn('In call to utils.validateMetadata, metadata must be JSON string or a dictionary object') + + return retData def validatePubKey(self, key): '''