diff --git a/volatility3/framework/constants/__init__.py b/volatility3/framework/constants/__init__.py index 2e6ae0261..429b79c3c 100644 --- a/volatility3/framework/constants/__init__.py +++ b/volatility3/framework/constants/__init__.py @@ -120,6 +120,9 @@ OFFLINE = False REMOTE_ISF_URL = None # 'http://localhost:8000/banners.json' """Remote URL to query for a list of ISF addresses""" +DOWNLOAD_TIMEOUT = 30 +"""Length of time (in seconds) to wait for another process to download a resource before using it""" + ### # DEPRECATED VALUES ### diff --git a/volatility3/framework/layers/resources.py b/volatility3/framework/layers/resources.py index 236d256f1..6121c2cff 100644 --- a/volatility3/framework/layers/resources.py +++ b/volatility3/framework/layers/resources.py @@ -177,33 +177,47 @@ class ResourceAccessor: + ".cache", ) + try: + content_length = int(fp.info().get("Content-Length", -1)) + except (AttributeError, ValueError): + # If our fp doesn't have an info member, carry on gracefully + content_length = -1 + if not os.path.exists(temp_filename): vollog.debug(f"Caching file at: {temp_filename}") + cache_file_size = -1 try: - content_length = fp.info().get("Content-Length", -1) - except AttributeError: - # If our fp doesn't have an info member, carry on gracefully - content_length = -1 - with open(temp_filename, "wb") as cache_file: - count = 0 - block = fp.read(block_size) - while block: - count += len(block) - if self._progress_callback: - self._progress_callback( - count * 100 / max(count, int(content_length)), - f"Reading file {url}", - ) - cache_file.write(block) + with open(temp_filename, "wb") as cache_file: + count = 0 block = fp.read(block_size) + while block: + count += len(block) + if self._progress_callback: + self._progress_callback( + count * 100 / max(count, int(content_length)), + f"Reading file {url}", + ) + cache_file.write(block) + block = fp.read(block_size) + cache_file.seek(0, os.SEEK_END) + cache_file_size = cache_file.tell() + finally: + if cache_file_size < content_length: + os.remove(temp_filename) + raise ValueError("Cached file did not download completely") else: - vollog.debug(f"Using already cached file at: {temp_filename}") + vollog.debug( + f"Trying to use already cached file at: {temp_filename}" + ) + # Re-open the cache with a different mode # Since we don't want people thinking they're able to save to the cache file, # open it in read mode only and allow breakages to happen if they wanted to write curfile = open(temp_filename, mode="rb") + # Validate the hash or delete the temp_filename and report an error + # Determine whether the file is a particular type of file, and if so, open it as such IMPORTED_MAGIC = False if HAS_MAGIC: