-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
4ca7bf0
commit 71c3e23
Showing
37 changed files
with
1,710 additions
and
184 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# -*- coding: utf-8 -*- | ||
"""The Core Storage (CS) credentials.""" | ||
|
||
from dfvfs.credentials import credentials | ||
from dfvfs.credentials import manager | ||
from dfvfs.lib import definitions | ||
|
||
|
||
class CSCredentials(credentials.Credentials): | ||
"""Core Storage (CS) credentials.""" | ||
|
||
# TODO: add support for key_data credential, needs pyfvde update. | ||
CREDENTIALS = frozenset([ | ||
'encrypted_root_plist', 'password', 'recovery_password']) | ||
|
||
TYPE_INDICATOR = definitions.TYPE_INDICATOR_CS | ||
|
||
|
||
manager.CredentialsManager.RegisterCredentials(CSCredentials()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
# -*- coding: utf-8 -*- | ||
"""The Core Storage (CS) file-like object.""" | ||
|
||
import os | ||
|
||
from dfvfs.file_io import file_io | ||
from dfvfs.lib import cs_helper | ||
from dfvfs.lib import errors | ||
from dfvfs.resolver import resolver | ||
|
||
|
||
class CSFile(file_io.FileIO): | ||
"""File input/output (IO) object using pyfvde.""" | ||
|
||
def __init__(self, resolver_context, path_spec): | ||
"""Initializes a file input/output (IO) object. | ||
Args: | ||
resolver_context (Context): resolver context. | ||
path_spec (PathSpec): a path specification. | ||
""" | ||
super(CSFile, self).__init__(resolver_context, path_spec) | ||
self._file_system = None | ||
self._fvde_logical_volume = None | ||
|
||
def _Close(self): | ||
"""Closes the file-like object.""" | ||
self._fvde_logical_volume = None | ||
|
||
self._file_system = None | ||
|
||
def _Open(self, mode='rb'): | ||
"""Opens the file-like object defined by path specification. | ||
Args: | ||
mode (Optional[str]): file access mode. | ||
Raises: | ||
AccessError: if the access to open the file was denied. | ||
IOError: if the file-like object could not be opened. | ||
OSError: if the file-like object could not be opened. | ||
PathSpecError: if the path specification is incorrect. | ||
""" | ||
volume_index = cs_helper.CSPathSpecGetVolumeIndex(self._path_spec) | ||
if volume_index is None: | ||
raise errors.PathSpecError( | ||
'Unable to retrieve volume index from path specification.') | ||
|
||
self._file_system = resolver.Resolver.OpenFileSystem( | ||
self._path_spec, resolver_context=self._resolver_context) | ||
fvde_volume_group = self._file_system.GetFVDEVolumeGroup() | ||
|
||
if (volume_index < 0 or | ||
volume_index >= fvde_volume_group.number_of_logical_volumes): | ||
raise errors.PathSpecError(( | ||
'Unable to retrieve logical volume index: {0:d} from path ' | ||
'specification.').format(volume_index)) | ||
|
||
self._fvde_logical_volume = fvde_volume_group.get_logical_volume( | ||
volume_index) | ||
|
||
self._UnlockFVDELogicalVolume(self._fvde_logical_volume, self._path_spec) | ||
|
||
def _UnlockFVDELogicalVolume(self, fvde_logical_volume, path_spec): | ||
"""Unlocks the Core Storage (CS) logical volume if necessary. | ||
Args: | ||
fvde_logical_volume (pyfvde.logical_volume): Core Storage (CS) logical | ||
volume. | ||
path_spec (PathSpec): path specification. | ||
""" | ||
if fvde_logical_volume.is_locked(): | ||
resolver.Resolver.key_chain.ExtractCredentialsFromPathSpec(path_spec) | ||
|
||
password = resolver.Resolver.key_chain.GetCredential( | ||
path_spec, 'password') | ||
if password: | ||
fvde_logical_volume.set_password(password) | ||
|
||
recovery_password = resolver.Resolver.key_chain.GetCredential( | ||
path_spec, 'recovery_password') | ||
if recovery_password: | ||
fvde_logical_volume.set_recovery_password(recovery_password) | ||
|
||
fvde_logical_volume.unlock() | ||
|
||
@property | ||
def is_locked(self): | ||
"""bool: True if the volume is locked.""" | ||
return self._fvde_logical_volume.is_locked() | ||
|
||
# Note: that the following functions do not follow the style guide | ||
# because they are part of the file-like object interface. | ||
# pylint: disable=invalid-name | ||
|
||
def read(self, size=None): | ||
"""Reads a byte string from the file-like object at the current offset. | ||
The function will read a byte string of the specified size or | ||
all of the remaining data if no size was specified. | ||
Args: | ||
size (Optional[int]): number of bytes to read, where None is all | ||
remaining data. | ||
Returns: | ||
bytes: data read. | ||
Raises: | ||
IOError: if the read failed. | ||
OSError: if the read failed. | ||
""" | ||
if not self._is_open: | ||
raise IOError('Not opened.') | ||
|
||
return self._fvde_logical_volume.read(size) | ||
|
||
def seek(self, offset, whence=os.SEEK_SET): | ||
"""Seeks to an offset within the file-like object. | ||
Args: | ||
offset (int): offset to seek to. | ||
whence (Optional(int)): value that indicates whether offset is an absolute | ||
or relative position within the file. | ||
Raises: | ||
IOError: if the seek failed. | ||
OSError: if the seek failed. | ||
""" | ||
if not self._is_open: | ||
raise IOError('Not opened.') | ||
|
||
self._fvde_logical_volume.seek(offset, whence) | ||
|
||
def get_offset(self): | ||
"""Retrieves the current offset into the file-like object. | ||
Returns: | ||
int: current offset into the file-like object. | ||
Raises: | ||
IOError: if the file-like object has not been opened. | ||
OSError: if the file-like object has not been opened. | ||
""" | ||
if not self._is_open: | ||
raise IOError('Not opened.') | ||
|
||
return self._fvde_logical_volume.get_offset() | ||
|
||
def get_size(self): | ||
"""Retrieves the size of the file-like object. | ||
Returns: | ||
int: size of the file-like object data. | ||
Raises: | ||
IOError: if the file-like object has not been opened. | ||
OSError: if the file-like object has not been opened. | ||
""" | ||
if not self._is_open: | ||
raise IOError('Not opened.') | ||
|
||
return self._fvde_logical_volume.size |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# -*- coding: utf-8 -*- | ||
"""Helper function for Core Storage (CS) support.""" | ||
|
||
|
||
_CS_LOCATION_PREFIX = '/cs' | ||
_CS_LOCATION_PREFIX_LENGTH = len(_CS_LOCATION_PREFIX) | ||
|
||
|
||
def CSPathSpecGetVolumeIndex(path_spec): | ||
"""Retrieves the volume index from the path specification. | ||
Args: | ||
path_spec (PathSpec): path specification. | ||
Returns: | ||
int: volume index or None if not available. | ||
""" | ||
volume_index = getattr(path_spec, 'volume_index', None) | ||
|
||
if volume_index is None: | ||
location = getattr(path_spec, 'location', None) | ||
|
||
if location is None or not location.startswith(_CS_LOCATION_PREFIX): | ||
return None | ||
|
||
volume_index = None | ||
try: | ||
volume_index = int(location[_CS_LOCATION_PREFIX_LENGTH:], 10) - 1 | ||
except ValueError: | ||
pass | ||
|
||
if volume_index is None or volume_index < 0: | ||
return None | ||
|
||
return volume_index |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.