def _preprocess(self, _, required_states): # Late loading the partition processor to avoid loading dfVFS unnecessarily. from turbinia.processors import partitions # We need to enumerate partitions in preprocessing so the path_specs match # the parent evidence location for each task. try: # We should only get one path_spec here since we're specifying the location. path_specs = partitions.Enumerate(self.parent_evidence, self.partition_location) except TurbiniaException as e: log.error(e) if len(path_specs) > 1: path_specs_dicts = [ path_spec.CopyToDict() for path_spec in path_specs ] raise TurbiniaException( 'Found more than one path_spec for {0:s} {1:s}: {2!s}'.format( self.parent_evidence.name, self.partition_location, path_specs_dicts)) elif len(path_specs) == 1: self.path_spec = path_specs[0] log.debug('Found path_spec {0!s} for parent evidence {1:s}'.format( self.path_spec.CopyToDict(), self.parent_evidence.name)) else: raise TurbiniaException( 'Could not find path_spec for location {0:s}'.format( self.partition_location)) # In attaching a partition, we create a new loopback device using the # partition offset and size. if EvidenceState.ATTACHED in required_states or self.has_child_evidence: # Check for encryption encryption_type = partitions.GetPartitionEncryptionType( self.path_spec) if encryption_type == 'BDE': self.device_path = mount_local.PreprocessBitLocker( self.parent_evidence.device_path, partition_offset=self.partition_offset, credentials=self.parent_evidence.credentials) if not self.device_path: log.error('Could not decrypt partition.') else: self.device_path = mount_local.PreprocessLosetup( self.parent_evidence.device_path, partition_offset=self.partition_offset, partition_size=self.partition_size, lv_uuid=self.lv_uuid) if self.device_path: self.state[EvidenceState.ATTACHED] = True self.local_path = self.device_path if EvidenceState.MOUNTED in required_states or self.has_child_evidence: self.mount_path = mount_local.PreprocessMountPartition( self.device_path, self.path_spec.type_indicator) if self.mount_path: self.local_path = self.mount_path self.state[EvidenceState.MOUNTED] = True
def _preprocess(self, _, required_states): # Late loading the partition processor to avoid loading dfVFS unnecessarily. from turbinia.processors import partitions # We need to enumerate partitions in preprocessing so the path_specs match # the parent evidence location for each task. try: path_specs = partitions.Enumerate(self.parent_evidence) except TurbiniaException as e: log.error(e) path_spec = partitions.GetPathSpecByLocation(path_specs, self.partition_location) if path_spec: self.path_spec = path_spec # In attaching a partition, we create a new loopback device using the # partition offset and size. if EvidenceState.ATTACHED in required_states or self.has_child_evidence: # Check for encryption encryption_type = partitions.GetPartitionEncryptionType(path_spec) if encryption_type == 'BDE': self.device_path = mount_local.PreprocessBitLocker( self.parent_evidence.device_path, partition_offset=self.partition_offset, credentials=self.parent_evidence.credentials) if not self.device_path: log.error('Could not decrypt partition.') else: self.device_path = mount_local.PreprocessLosetup( self.parent_evidence.device_path, partition_offset=self.partition_offset, partition_size=self.partition_size, lv_uuid=self.lv_uuid) if self.device_path: self.state[EvidenceState.ATTACHED] = True self.local_path = self.device_path if EvidenceState.MOUNTED in required_states or self.has_child_evidence: self.mount_path = mount_local.PreprocessMountPartition( self.device_path, self.path_spec.type_indicator) if self.mount_path: self.local_path = self.mount_path self.state[EvidenceState.MOUNTED] = True
def testPreprocessBitLocker(self, _, mock_path_exists, mock_path_isdir, mock_subprocess, mock_mkdtemp, mock_config): """Test PreprocessBitLocker method.""" mock_config.MOUNT_DIR_PREFIX = '/mnt/turbinia' mock_path_exists.side_effect = _mock_bitlocker_returns mock_mkdtemp.return_value = '/mnt/turbinia/turbinia0ckdntz0' current_path = os.path.abspath(os.path.dirname(__file__)) source_path = os.path.join(current_path, '..', '..', 'test_data', 'mbr.raw') credentials = [('password', '123456')] mock_path_isdir.return_value = True device = mount_local.PreprocessBitLocker(source_path, partition_offset=65536, credentials=credentials) expected_args = [ 'sudo', 'bdemount', '-o', '65536', '-p', '123456', '-X', 'allow_other', source_path, '/mnt/turbinia/turbinia0ckdntz0' ] mock_subprocess.assert_called_once_with(expected_args) self.assertEqual(device, '/mnt/turbinia/turbinia0ckdntz0/bde1') # Test with recovery password mock_subprocess.reset_mock() credentials = [('recovery_password', '123456')] mount_local.PreprocessBitLocker(source_path, partition_offset=65536, credentials=credentials) expected_args = [ 'sudo', 'bdemount', '-o', '65536', '-r', '123456', '-X', 'allow_other', source_path, '/mnt/turbinia/turbinia0ckdntz0' ] mock_subprocess.assert_called_once_with(expected_args) # Test if source does not exist with self.assertRaises(TurbiniaException): mount_local.PreprocessBitLocker('/dev/loop0p4', partition_offset=65536, credentials=credentials) # Test if mount path not directory mock_path_isdir.return_value = False with self.assertRaises(TurbiniaException): mount_local.PreprocessBitLocker(source_path, partition_offset=65536, credentials=credentials) mock_path_isdir.return_value = True # Test decryption failure mock_subprocess.reset_mock() mock_subprocess.side_effect = CalledProcessError(1, 'bdemount') device = mount_local.PreprocessBitLocker(source_path, partition_offset=65536, credentials=credentials) self.assertEqual(device, None) # Test with unsupported credential type mock_subprocess.reset_mock() credentials = [('startup_key', 'key.BEK')] mount_local.PreprocessBitLocker(source_path, partition_offset=65536, credentials=credentials) mock_subprocess.assert_not_called()