Skip to content

Commit

Permalink
Added support for resource for as data stream #254
Browse files Browse the repository at this point in the history
  • Loading branch information
joachimmetz committed Jan 14, 2022
1 parent a28741f commit 725b9d6
Show file tree
Hide file tree
Showing 15 changed files with 325 additions and 136 deletions.
2 changes: 1 addition & 1 deletion config/dpkg/control
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Homepage: https://github.com/log2timeline/dfvfs

Package: python3-dfvfs
Architecture: all
Depends: libbde-python3 (>= 20140531), libewf-python3 (>= 20131210), libfsapfs-python3 (>= 20201107), libfsext-python3 (>= 20220112), libfshfs-python3 (>= 20220113), libfsntfs-python3 (>= 20211229), libfsxfs-python3 (>= 20220113), libfvde-python3 (>= 20160719), libfwnt-python3 (>= 20210717), libluksde-python3 (>= 20200101), libmodi-python3 (>= 20210405), libphdi-python3 (>= 20220110), libqcow-python3 (>= 20201213), libsigscan-python3 (>= 20191221), libsmdev-python3 (>= 20140529), libsmraw-python3 (>= 20140612), libvhdi-python3 (>= 20201014), libvmdk-python3 (>= 20140421), libvsgpt-python3 (>= 20211115), libvshadow-python3 (>= 20160109), libvslvm-python3 (>= 20160109), python3-cffi-backend (>= 1.9.1), python3-cryptography (>= 2.0.2), python3-dfdatetime (>= 20211113), python3-dtfabric (>= 20170524), python3-idna (>= 2.5), python3-pytsk3 (>= 20210419), python3-pyxattr (>= 0.7.2), python3-yaml (>= 3.10), ${misc:Depends}
Depends: libbde-python3 (>= 20140531), libewf-python3 (>= 20131210), libfsapfs-python3 (>= 20201107), libfsext-python3 (>= 20220112), libfshfs-python3 (>= 20220114), libfsntfs-python3 (>= 20211229), libfsxfs-python3 (>= 20220113), libfvde-python3 (>= 20160719), libfwnt-python3 (>= 20210717), libluksde-python3 (>= 20200101), libmodi-python3 (>= 20210405), libphdi-python3 (>= 20220110), libqcow-python3 (>= 20201213), libsigscan-python3 (>= 20191221), libsmdev-python3 (>= 20140529), libsmraw-python3 (>= 20140612), libvhdi-python3 (>= 20201014), libvmdk-python3 (>= 20140421), libvsgpt-python3 (>= 20211115), libvshadow-python3 (>= 20160109), libvslvm-python3 (>= 20160109), python3-cffi-backend (>= 1.9.1), python3-cryptography (>= 2.0.2), python3-dfdatetime (>= 20211113), python3-dtfabric (>= 20170524), python3-idna (>= 2.5), python3-pytsk3 (>= 20210419), python3-pyxattr (>= 0.7.2), python3-yaml (>= 3.10), ${misc:Depends}
Description: Python 3 module of dfVFS
dfVFS, or Digital Forensics Virtual File System, provides read-only access to
file-system objects from various storage media types and file formats. The goal
Expand Down
2 changes: 1 addition & 1 deletion dependencies.ini
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ version_property: get_version()
[pyfshfs]
dpkg_name: libfshfs-python3
l2tbinaries_name: libfshfs
minimum_version: 20220113
minimum_version: 20220114
pypi_name: libfshfs-python
rpm_name: libfshfs-python3
version_property: get_version()
Expand Down
34 changes: 34 additions & 0 deletions dfvfs/vfs/hfs_data_stream.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
"""The HFS data stream implementation."""

from dfvfs.vfs import data_stream


class HFSDataStream(data_stream.DataStream):
"""File system data stream that uses pyfshfs."""

def __init__(self, fshfs_data_stream):
"""Initializes the data stream.
Args:
fshfs_data_stream (pyfshfs.data_stream): HFS data stream.
"""
super(HFSDataStream, self).__init__()
self._fshfs_data_stream = fshfs_data_stream
self._name = ''

if fshfs_data_stream:
self._name = 'rsrc'

@property
def name(self):
"""str: name."""
return self._name

def IsDefault(self):
"""Determines if the data stream is the default (data fork) data stream.
Returns:
bool: True if the data stream is the default (data fork) data stream.
"""
return not self._fshfs_data_stream
21 changes: 21 additions & 0 deletions dfvfs/vfs/hfs_file_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from dfvfs.vfs import extent
from dfvfs.vfs import file_entry
from dfvfs.vfs import hfs_attribute
from dfvfs.vfs import hfs_data_stream
from dfvfs.vfs import hfs_directory


Expand Down Expand Up @@ -84,6 +85,26 @@ def _GetAttributes(self):

return self._attributes

def _GetDataStreams(self):
"""Retrieves the data streams.
Returns:
list[HFSDataStream]: data streams.
"""
if self._data_streams is None:
self._data_streams = []

if self.entry_type == definitions.FILE_ENTRY_TYPE_FILE:
data_stream = hfs_data_stream.HFSDataStream(None)
self._data_streams.append(data_stream)

fshfs_data_stream = self._fshfs_file_entry.get_resource_fork()
if fshfs_data_stream:
data_stream = hfs_data_stream.HFSDataStream(fshfs_data_stream)
self._data_streams.append(data_stream)

return self._data_streams

def _GetDirectory(self):
"""Retrieves a directory.
Expand Down
8 changes: 4 additions & 4 deletions dfvfs/vfs/ntfs_data_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ class NTFSDataStream(data_stream.DataStream):
"""File system data stream that uses pyfsntfs."""

def __init__(self, fsntfs_data_stream):
"""Initializes the data stream object.
"""Initializes the data stream.
Args:
fsntfs_data_stream (pyfsntfs.data_stream): NTFS data stream.
"""
super(NTFSDataStream, self).__init__()
self._fsntfs_data_stream = fsntfs_data_stream
self._name = getattr(fsntfs_data_stream, 'name', None) or ''

@property
def name(self):
"""str: name."""
return getattr(self._fsntfs_data_stream, 'name', '')
return self._name

def IsDefault(self):
"""Determines if the data stream is the default data stream.
Returns:
bool: True if the data stream is the default data stream.
"""
return not self._fsntfs_data_stream
return not bool(self._name)
39 changes: 15 additions & 24 deletions dfvfs/vfs/tsk_data_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,39 @@
class TSKDataStream(data_stream.DataStream):
"""File system data stream that uses pytsk3."""

def __init__(self, file_system, pytsk_attribute):
def __init__(self, pytsk_attribute):
"""Initializes a data stream.
Args:
file_system (TSKFileSystem): file system.
pytsk_attribute (pytsk3.Attribute): TSK attribute.
"""
super(TSKDataStream, self).__init__()
self._file_system = file_system
self._tsk_attribute = pytsk_attribute
self._name = ''

@property
def name(self):
"""str: name."""
if self._tsk_attribute:
if pytsk_attribute:
# The value of the attribute name will be None for the default
# data stream.
attribute_name = getattr(self._tsk_attribute.info, 'name', None)
if attribute_name:
attribute_name = getattr(pytsk_attribute.info, 'name', None)
attribute_type = getattr(pytsk_attribute.info, 'type', None)
if attribute_type == pytsk3.TSK_FS_ATTR_TYPE_HFS_RSRC:
self._name = 'rsrc'

elif attribute_name:
try:
# pytsk3 returns an UTF-8 encoded byte string.
return attribute_name.decode('utf8')
self._name = attribute_name.decode('utf8')
except UnicodeError:
pass

return ''
@property
def name(self):
"""str: name."""
return self._name

def IsDefault(self):
"""Determines if the data stream is the default data stream.
Returns:
bool: True if the data stream is the default data stream, false if not.
"""
if not self._tsk_attribute or not self._file_system:
return True

if self._file_system.IsHFS():
attribute_type = getattr(self._tsk_attribute.info, 'type', None)
return attribute_type in (
pytsk3.TSK_FS_ATTR_TYPE_HFS_DEFAULT, pytsk3.TSK_FS_ATTR_TYPE_HFS_DATA)

if self._file_system.IsNTFS():
return not bool(self.name)

return True
return not bool(self._name)
12 changes: 6 additions & 6 deletions dfvfs/vfs/tsk_file_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,12 +365,13 @@ def _GetDataStreams(self):
"""
if self._data_streams is None:
if self._file_system.IsHFS():
known_data_attribute_types = [
known_data_attribute_types = (
pytsk3.TSK_FS_ATTR_TYPE_HFS_DEFAULT,
pytsk3.TSK_FS_ATTR_TYPE_HFS_DATA]
pytsk3.TSK_FS_ATTR_TYPE_HFS_DATA,
pytsk3.TSK_FS_ATTR_TYPE_HFS_RSRC)

elif self._file_system.IsNTFS():
known_data_attribute_types = [pytsk3.TSK_FS_ATTR_TYPE_NTFS_DATA]
known_data_attribute_types = (pytsk3.TSK_FS_ATTR_TYPE_NTFS_DATA, )

else:
known_data_attribute_types = None
Expand All @@ -382,7 +383,7 @@ def _GetDataStreams(self):

if not known_data_attribute_types:
if tsk_fs_meta_type == pytsk3.TSK_FS_META_TYPE_REG:
data_stream = tsk_data_stream.TSKDataStream(self._file_system, None)
data_stream = tsk_data_stream.TSKDataStream(None)
self._data_streams.append(data_stream)

else:
Expand All @@ -397,8 +398,7 @@ def _GetDataStreams(self):

attribute_type = getattr(pytsk_attribute.info, 'type', None)
if attribute_type in known_data_attribute_types:
data_stream = tsk_data_stream.TSKDataStream(
self._file_system, pytsk_attribute)
data_stream = tsk_data_stream.TSKDataStream(pytsk_attribute)
self._data_streams.append(data_stream)

return self._data_streams
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ libbde-python >= 20140531
libewf-python >= 20131210
libfsapfs-python >= 20201107
libfsext-python >= 20220112
libfshfs-python >= 20220113
libfshfs-python >= 20220114
libfsntfs-python >= 20211229
libfsxfs-python >= 20220113
libfvde-python >= 20160719
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ requires = libbde-python3 >= 20140531
libewf-python3 >= 20131210
libfsapfs-python3 >= 20201107
libfsext-python3 >= 20220112
libfshfs-python3 >= 20220113
libfshfs-python3 >= 20220114
libfsntfs-python3 >= 20211229
libfsxfs-python3 >= 20220113
libfvde-python3 >= 20160719
Expand Down
28 changes: 28 additions & 0 deletions tests/vfs/hfs_data_stream.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Tests for the data stream implementation using pyfshfs."""

import unittest

from dfvfs.vfs import hfs_data_stream

from tests import test_lib as shared_test_lib


class HFSDataStreamTest(shared_test_lib.BaseTestCase):
"""Tests the HFS data stream."""

def testName(self):
"""Test the name property."""
test_data_stream = hfs_data_stream.HFSDataStream(None)
self.assertEqual(test_data_stream.name, '')

def testIsDefault(self):
"""Test the IsDefault function."""
test_data_stream = hfs_data_stream.HFSDataStream(None)
result = test_data_stream.IsDefault()
self.assertTrue(result)


if __name__ == '__main__':
unittest.main()
Loading

0 comments on commit 725b9d6

Please sign in to comment.