Ejemplo n.º 1
0
  def _GetLVMVolumeIdentifiers(self, scan_node, options):
    """Determines the LVM volume identifiers.

    Args:
      scan_node (SourceScanNode): scan node.
      options (VolumeScannerOptions): volume scanner options.

    Returns:
      list[str]: LVM volume identifiers.

    Raises:
      ScannerError: if the scan node is invalid or the scanner does not know
          how to proceed.
      UserAbort: if the user requested to abort.
    """
    if not scan_node or not scan_node.path_spec:
      raise errors.ScannerError('Invalid scan node.')

    volume_system = lvm_volume_system.LVMVolumeSystem()
    volume_system.Open(scan_node.path_spec)

    volume_identifiers = self._source_scanner.GetVolumeIdentifiers(
        volume_system)
    if not volume_identifiers:
      return []

    if options.volumes:
      if options.volumes == ['all']:
        volumes = range(1, volume_system.number_of_volumes + 1)
      else:
        volumes = options.volumes

      try:
        selected_volumes = self._NormalizedVolumeIdentifiers(
            volume_system, volumes, prefix='lvm')

        if not set(selected_volumes).difference(volume_identifiers):
          return selected_volumes
      except errors.ScannerError as exception:
        if self._mediator:
          self._mediator.PrintWarning('{0!s}'.format(exception))

    if len(volume_identifiers) > 1:
      if not self._mediator:
        raise errors.ScannerError(
            'Unable to proceed. LVM volumes found but no mediator to '
            'determine how they should be used.')

      try:
        volume_identifiers = self._mediator.GetLVMVolumeIdentifiers(
            volume_system, volume_identifiers)
      except KeyboardInterrupt:
        raise errors.UserAbort('File system scan aborted.')

    return self._NormalizedVolumeIdentifiers(
        volume_system, volume_identifiers, prefix='lvm')
Ejemplo n.º 2
0
    def _GetLVMVolumeIdentifiers(self, scan_node):
        """Determines the LVM volume identifiers.

    Args:
      scan_node (dfvfs.SourceScanNode): scan node.

    Returns:
      list[str]: LVM volume identifiers.

    Raises:
      SourceScannerError: if the scan node is invalid or more than 1 volume
          was found but no volumes were specified.
      UserAbort: if the user requested to abort.
    """
        if not scan_node or not scan_node.path_spec:
            raise errors.SourceScannerError('Invalid scan node.')

        volume_system = lvm_volume_system.LVMVolumeSystem()
        volume_system.Open(scan_node.path_spec)

        volume_identifiers = self._source_scanner.GetVolumeIdentifiers(
            volume_system)
        if not volume_identifiers:
            return []

        # TODO: refactor self._volumes to use scan options.
        if self._volumes:
            if self._volumes == 'all':
                volumes = volume_system.volume_identifiers
            else:
                volumes = self._mediator.ParseVolumeIdentifiersString(
                    self._volumes, prefix='lvm')

            selected_volume_identifiers = self._NormalizedVolumeIdentifiers(
                volume_system, volumes, prefix='lvm')

            if not set(selected_volume_identifiers).difference(
                    volume_identifiers):
                return selected_volume_identifiers

        if len(volume_identifiers) > 1:
            if self._unattended_mode:
                raise errors.SourceScannerError(
                    'More than 1 volume found but no volumes specified.')

            try:
                volume_identifiers = self._mediator.GetLVMVolumeIdentifiers(
                    volume_system, volume_identifiers)
            except KeyboardInterrupt:
                raise errors.UserAbort('File system scan aborted.')

        return self._NormalizedVolumeIdentifiers(volume_system,
                                                 volume_identifiers,
                                                 prefix='lvm')
Ejemplo n.º 3
0
  def testPrintLVMVolumeIdentifiersOverview(self):
    """Tests the _PrintLVMVolumeIdentifiersOverview function."""
    test_file_path = self._GetTestFilePath(['lvm.raw'])
    self._SkipIfPathNotExists(test_file_path)

    test_os_path_spec = path_spec_factory.Factory.NewPathSpec(
        dfvfs_definitions.TYPE_INDICATOR_OS, location=test_file_path)
    test_raw_path_spec = path_spec_factory.Factory.NewPathSpec(
        dfvfs_definitions.TYPE_INDICATOR_RAW, parent=test_os_path_spec)
    test_lvm_path_spec = path_spec_factory.Factory.NewPathSpec(
        dfvfs_definitions.TYPE_INDICATOR_LVM, location='/',
        parent=test_raw_path_spec)

    volume_system = lvm_volume_system.LVMVolumeSystem()
    volume_system.Open(test_lvm_path_spec)

    file_object = io.BytesIO()
    test_output_writer = tools.FileObjectOutputWriter(file_object)

    test_mediator = storage_media_tool.StorageMediaToolMediator(
        output_writer=test_output_writer)

    test_mediator._PrintLVMVolumeIdentifiersOverview(
        volume_system, ['lvm1', 'lvm2'])

    file_object.seek(0, os.SEEK_SET)
    output_data = file_object.read()

    expected_output_data = [
        b'The following Logical Volume Manager (LVM) volumes were found:',
        b'',
        b'Identifier',
        b'lvm1',
        b'lvm2',
        b'',
        b'']

    if not win32console:
      # Using join here since Python 3 does not support format of bytes.
      expected_output_data[2] = b''.join([
          b'\x1b[1m', expected_output_data[2], b'\x1b[0m'])

    self.assertEqual(output_data.split(b'\n'), expected_output_data)
Ejemplo n.º 4
0
    def testIterateVolumes(self):
        """Test the iterate volumes functionality."""
        volume_system = lvm_volume_system.LVMVolumeSystem()

        volume_system.Open(self._lvm_path_spec)

        self.assertEqual(volume_system.number_of_volumes, 2)

        volume = volume_system.GetVolumeByIndex(1)
        self.assertIsNotNone(volume)

        self.assertEqual(volume.number_of_extents, 1)
        self.assertEqual(volume.number_of_attributes, 1)
        self.assertEqual(volume.identifier, u'lvm2')

        expected_value = u'bJxmc8-JEMZ-jXT9-oVeY-40AY-ROro-mCO8Zz'
        volume_attribute = volume.GetAttribute(u'identifier')
        self.assertIsNotNone(volume_attribute)
        self.assertEqual(volume_attribute.value, expected_value)

        volume = volume_system.GetVolumeByIndex(7)
        self.assertIsNone(volume)
Ejemplo n.º 5
0
  def testIterateVolumes(self):
    """Test the iterate volumes functionality."""
    volume_system = lvm_volume_system.LVMVolumeSystem()

    volume_system.Open(self._lvm_path_spec)

    self.assertEqual(volume_system.number_of_volumes, 2)

    volume = volume_system.GetVolumeByIndex(0)
    self.assertIsNotNone(volume)

    self.assertEqual(volume.number_of_extents, 1)
    self.assertEqual(volume.number_of_attributes, 1)
    self.assertEqual(volume.identifier, 'lvm1')

    expected_value = 'RI0pgm-rdy4-XxcL-5eoK-Easc-fgPq-CWaEJb'
    volume_attribute = volume.GetAttribute('identifier')
    self.assertIsNotNone(volume_attribute)
    self.assertEqual(volume_attribute.value, expected_value)

    volume = volume_system.GetVolumeByIndex(99)
    self.assertIsNone(volume)
Ejemplo n.º 6
0
    def testIterateVolumes(self):
        """Test the iterate volumes functionality."""
        volume_system = lvm_volume_system.LVMVolumeSystem()

        volume_system.Open(self._lvm_path_spec)

        self.assertEqual(volume_system.number_of_volumes, 1)

        volume = volume_system.GetVolumeByIndex(0)
        self.assertIsNotNone(volume)

        self.assertEqual(volume.number_of_extents, 1)
        self.assertEqual(volume.number_of_attributes, 1)
        self.assertEqual(volume.identifier, 'lvm1')

        expected_value = '0MUZZr-7jgO-iFwW-sSG3-Rb8W-w5td-qAOF8e'
        volume_attribute = volume.GetAttribute('identifier')
        self.assertIsNotNone(volume_attribute)
        self.assertEqual(volume_attribute.value, expected_value)

        volume = volume_system.GetVolumeByIndex(99)
        self.assertIsNone(volume)
Ejemplo n.º 7
0
    def testGetLVMVolumeIdentifiers(self):
        """Tests the GetLVMVolumeIdentifiers function."""
        test_path = self._GetTestFilePath(['lvm.raw'])
        self._SkipIfPathNotExists(test_path)

        test_os_path_spec = path_spec_factory.Factory.NewPathSpec(
            definitions.TYPE_INDICATOR_OS, location=test_path)
        test_raw_path_spec = path_spec_factory.Factory.NewPathSpec(
            definitions.TYPE_INDICATOR_RAW, parent=test_os_path_spec)
        test_lvm_container_path_spec = path_spec_factory.Factory.NewPathSpec(
            definitions.TYPE_INDICATOR_LVM,
            location='/',
            parent=test_raw_path_spec)

        volume_system = lvm_volume_system.LVMVolumeSystem()
        volume_system.Open(test_lvm_container_path_spec)

        # Test selection of single volume.
        input_file_object = io.BytesIO(b'1\n')
        test_input_reader = command_line.FileObjectInputReader(
            input_file_object)

        output_file_object = io.BytesIO()
        test_output_writer = command_line.FileObjectOutputWriter(
            output_file_object)

        test_mediator = command_line.CLIVolumeScannerMediator(
            input_reader=test_input_reader, output_writer=test_output_writer)

        volume_identifiers = test_mediator.GetLVMVolumeIdentifiers(
            volume_system, ['lvm1'])

        self.assertEqual(volume_identifiers, ['lvm1'])

        # Test selection of single volume.
        input_file_object = io.BytesIO(b'lvm1\n')
        test_input_reader = command_line.FileObjectInputReader(
            input_file_object)

        output_file_object = io.BytesIO()
        test_output_writer = command_line.FileObjectOutputWriter(
            output_file_object)

        test_mediator = command_line.CLIVolumeScannerMediator(
            input_reader=test_input_reader, output_writer=test_output_writer)

        volume_identifiers = test_mediator.GetLVMVolumeIdentifiers(
            volume_system, ['lvm1'])

        self.assertEqual(volume_identifiers, ['lvm1'])

        # Test selection of single volume with invalid input on first attempt.
        input_file_object = io.BytesIO(b'bogus\nlvm1\n')
        test_input_reader = command_line.FileObjectInputReader(
            input_file_object)

        output_file_object = io.BytesIO()
        test_output_writer = command_line.FileObjectOutputWriter(
            output_file_object)

        test_mediator = command_line.CLIVolumeScannerMediator(
            input_reader=test_input_reader, output_writer=test_output_writer)

        volume_identifiers = test_mediator.GetLVMVolumeIdentifiers(
            volume_system, ['lvm1'])

        self.assertEqual(volume_identifiers, ['lvm1'])

        # Test selection of all volumes.
        input_file_object = io.BytesIO(b'all\n')
        test_input_reader = command_line.FileObjectInputReader(
            input_file_object)

        output_file_object = io.BytesIO()
        test_output_writer = command_line.FileObjectOutputWriter(
            output_file_object)

        test_mediator = command_line.CLIVolumeScannerMediator(
            input_reader=test_input_reader, output_writer=test_output_writer)

        volume_identifiers = test_mediator.GetLVMVolumeIdentifiers(
            volume_system, ['lvm1', 'lvm2'])

        self.assertEqual(volume_identifiers, ['lvm1', 'lvm2'])

        # Test selection of no volumes.
        input_file_object = io.BytesIO(b'\n')
        test_input_reader = command_line.FileObjectInputReader(
            input_file_object)

        output_file_object = io.BytesIO()
        test_output_writer = command_line.FileObjectOutputWriter(
            output_file_object)

        test_mediator = command_line.CLIVolumeScannerMediator(
            input_reader=test_input_reader, output_writer=test_output_writer)

        volume_identifiers = test_mediator.GetLVMVolumeIdentifiers(
            volume_system, ['lvm1'])

        self.assertEqual(volume_identifiers, [])
Ejemplo n.º 8
0
    def _ProcessPartition(self, path_spec):
        """Generate RawDiskPartition from a PathSpec.

    Args:
      path_spec (dfvfs.PathSpec): dfVFS path spec.

    Returns:
      A new RawDiskPartition evidence item and a list of strings containing
      partition information to add to the status report.
    """
        status_report = []

        fs_path_spec = path_spec
        fs_location = None
        partition_location = None
        volume_index = None
        partition_index = None
        partition_offset = None
        partition_size = None
        lv_uuid = None

        # File system location / identifier
        is_lvm = False
        fs_location = getattr(path_spec, 'location', None)
        while path_spec.HasParent():
            type_indicator = path_spec.type_indicator
            if type_indicator == dfvfs_definitions.TYPE_INDICATOR_APFS_CONTAINER:
                # APFS volume index
                volume_index = getattr(path_spec, 'volume_index', None)

            if type_indicator in (
                    dfvfs_definitions.TYPE_INDICATOR_GPT,
                    dfvfs_definitions.TYPE_INDICATOR_LVM,
                    dfvfs_definitions.TYPE_INDICATOR_TSK_PARTITION):
                if fs_location in ('\\', '/'):
                    # Partition location / identifier
                    fs_location = getattr(path_spec, 'location', None)
                partition_location = getattr(path_spec, 'location', None)
                # Partition index
                partition_index = getattr(path_spec, 'part_index', None)

                if type_indicator == dfvfs_definitions.TYPE_INDICATOR_TSK_PARTITION:
                    volume_system = tsk_volume_system.TSKVolumeSystem()
                elif type_indicator == dfvfs_definitions.TYPE_INDICATOR_LVM:
                    is_lvm = True
                    volume_system = lvm_volume_system.LVMVolumeSystem()
                else:
                    volume_system = gpt_volume_system.GPTVolumeSystem()
                try:
                    volume_system.Open(path_spec)
                    volume_identifier = partition_location.replace('/', '')
                    volume = volume_system.GetVolumeByIdentifier(
                        volume_identifier)

                    if is_lvm:
                        # LVM Logical Volume UUID
                        lv_uuid = volume.GetAttribute('identifier')
                        if lv_uuid:
                            lv_uuid = lv_uuid.value

                    partition_offset = volume.extents[0].offset
                    partition_size = volume.extents[0].size
                except dfvfs_errors.VolumeSystemError as e:
                    raise TurbiniaException(
                        'Could not process partition: {0!s}'.format(e))
                break

            path_spec = path_spec.parent

        status_report.append(fmt.heading5('{0!s}:'.format(fs_location)))
        status_report.append(
            fmt.bullet('Filesystem: {0!s}'.format(
                fs_path_spec.type_indicator)))
        if volume_index is not None:
            status_report.append(
                fmt.bullet('Volume index: {0!s}'.format(volume_index)))
        if partition_index is not None:
            status_report.append(
                fmt.bullet('Partition index: {0!s}'.format(partition_index)))
            status_report.append(
                fmt.bullet('Partition offset: {0!s}'.format(partition_offset)))
            status_report.append(
                fmt.bullet('Partition size: {0!s}'.format(partition_size)))
        if volume_index is None and partition_index is None:
            status_report.append(
                fmt.bullet('Source evidence is a volume image'))

        # Not setting path_spec here as it will need to be generated for each task
        partition_evidence = DiskPartition(partition_location=fs_location,
                                           partition_offset=partition_offset,
                                           partition_size=partition_size,
                                           lv_uuid=lv_uuid)

        return partition_evidence, status_report
Ejemplo n.º 9
0
    def _ScanVolumeSystemRoot(self, scan_context, scan_node, options,
                              base_path_specs):
        """Scans a volume system root scan node for volume and file systems.

    Args:
      scan_context (SourceScannerContext): source scanner context.
      scan_node (SourceScanNode): volume system root scan node.
      options (VolumeScannerOptions): volume scanner options.
      base_path_specs (list[PathSpec]): file system base path specifications.

    Raises:
      dfvfs.ScannerError: if the scan node is invalid, the scan node type is not
          supported or if a sub scan node cannot be retrieved.
    """
        if not scan_node or not scan_node.path_spec:
            raise dfvfs_errors.ScannerError('Invalid scan node.')

        if scan_node.type_indicator == (
                dfvfs_definitions.TYPE_INDICATOR_APFS_CONTAINER):
            volume_system = apfs_volume_system.APFSVolumeSystem()
            volume_system.Open(scan_node.path_spec)

            volume_identifiers = self._GetVolumeIdentifiers(
                volume_system, options)

        elif scan_node.type_indicator == dfvfs_definitions.TYPE_INDICATOR_GPT:
            volume_identifiers = self._GetPartitionIdentifiers(
                scan_node, options)

        elif scan_node.type_indicator == dfvfs_definitions.TYPE_INDICATOR_LVM:
            volume_system = lvm_volume_system.LVMVolumeSystem()
            volume_system.Open(scan_node.path_spec)

            volume_identifiers = self._GetVolumeIdentifiers(
                volume_system, options)

        elif scan_node.type_indicator == dfvfs_definitions.TYPE_INDICATOR_VSHADOW:
            volume_system = vshadow_volume_system.VShadowVolumeSystem()
            volume_system.Open(scan_node.path_spec)

            volume_identifiers = self._GetVolumeSnapshotIdentifiers(
                volume_system, options)
            # Process VSS stores (snapshots) starting with the most recent one.
            volume_identifiers.reverse()

            # TODO: difference with dfVFS for current VSS volume support.
            if not options.snapshots_only and self._mediator and volume_identifiers:
                snapshots_only = not self._mediator.PromptUserForVSSCurrentVolume(
                )
                options.snapshots_only = snapshots_only
                self._snapshots_only = snapshots_only

        else:
            raise dfvfs_errors.ScannerError(
                'Unsupported volume system type: {0:s}.'.format(
                    scan_node.type_indicator))

        for volume_identifier in volume_identifiers:
            location = '/{0:s}'.format(volume_identifier)
            sub_scan_node = scan_node.GetSubNodeByLocation(location)
            if not sub_scan_node:
                raise dfvfs_errors.ScannerError(
                    'Scan node missing for volume identifier: {0:s}.'.format(
                        volume_identifier))

            self._ScanVolume(scan_context, sub_scan_node, options,
                             base_path_specs)