Ejemplo n.º 1
0
    def testIterateVolumes(self):
        """Test the iterate volumes functionality."""
        volume_system = apfs_volume_system.APFSVolumeSystem()

        volume_system.Open(self._apfs_container_path_spec)

        self.assertEqual(volume_system.number_of_volumes, 1)

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

        self.assertEqual(volume.number_of_attributes, 2)
        self.assertEqual(volume.identifier, 'apfs1')

        expected_value = '44b5f357-e9b3-483d-893c-3802306b5132'
        volume_attribute = volume.GetAttribute('identifier')
        self.assertIsNotNone(volume_attribute)
        self.assertEqual(volume_attribute.value, expected_value)

        volume_attribute = volume.GetAttribute('name')
        self.assertIsNotNone(volume_attribute)
        self.assertEqual(volume_attribute.value, 'SingleVolume')

        volume = volume_system.GetVolumeByIndex(99)
        self.assertIsNone(volume)
Ejemplo n.º 2
0
    def testIterateVolumes(self):
        """Test the iterate volumes functionality."""
        volume_system = apfs_volume_system.APFSVolumeSystem()

        volume_system.Open(self._apfs_container_path_spec)

        self.assertEqual(volume_system.number_of_volumes, 1)

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

        self.assertEqual(volume.number_of_attributes, 2)
        self.assertEqual(volume.identifier, 'apfs1')

        expected_value = '5a4d7f50-726e-4fe9-8c57-8898f0cbaf72'
        volume_attribute = volume.GetAttribute('identifier')
        self.assertIsNotNone(volume_attribute)
        self.assertEqual(volume_attribute.value, expected_value)

        volume_attribute = volume.GetAttribute('name')
        self.assertIsNotNone(volume_attribute)
        self.assertEqual(volume_attribute.value, 'apfs_test')

        volume = volume_system.GetVolumeByIndex(99)
        self.assertIsNone(volume)
Ejemplo n.º 3
0
    def _GetAPFSVolumeIdentifiers(self, scan_node, options):
        """Determines the APFS volume identifiers.

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

    Returns:
      list[str]: APFS volume identifiers.

    Raises:
      ScannerError: if the format of or within the source is not supported
          or the the scan node is invalid.
      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 = apfs_volume_system.APFSVolumeSystem()
        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='apfs')

                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. APFS volumes found but no mediator to '
                    'determine how they should be used.')

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

        return self._NormalizedVolumeIdentifiers(volume_system,
                                                 volume_identifiers,
                                                 prefix='apfs')
Ejemplo n.º 4
0
    def _GetAPFSVolumeIdentifiers(self, scan_node):
        """Determines the APFS volume identifiers.

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

    Returns:
      list[str]: APFS volume identifiers.

    Raises:
      SourceScannerError: if the format of or within the source is not
          supported or the the scan node is invalid.
      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 = apfs_volume_system.APFSVolumeSystem()
        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 = range(1, volume_system.number_of_volumes + 1)
            else:
                volumes = self._ParseVolumeIdentifiersString(self._volumes,
                                                             prefix='apfs')

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

            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._PromptUserForAPFSVolumeIdentifiers(
                    volume_system, volume_identifiers)
            except KeyboardInterrupt:
                raise errors.UserAbort('File system scan aborted.')

        return self._NormalizedVolumeIdentifiers(volume_system,
                                                 volume_identifiers,
                                                 prefix='apfs')
Ejemplo n.º 5
0
    def testPrintAPFSVolumeIdentifiersOverview(self):
        """Tests the _PrintAPFSVolumeIdentifiersOverview function."""
        test_path = self._GetTestFilePath(['apfs.dmg'])
        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_tsk_partition_path_spec = path_spec_factory.Factory.NewPathSpec(
            definitions.TYPE_INDICATOR_TSK_PARTITION,
            location='/p1',
            parent=test_raw_path_spec)
        test_apfs_container_path_spec = path_spec_factory.Factory.NewPathSpec(
            definitions.TYPE_INDICATOR_APFS_CONTAINER,
            location='/',
            parent=test_tsk_partition_path_spec)

        volume_system = apfs_volume_system.APFSVolumeSystem()
        volume_system.Open(test_apfs_container_path_spec)

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

        test_mediator = command_line.CLIVolumeScannerMediator(
            output_writer=test_output_writer)

        test_mediator._PrintAPFSVolumeIdentifiersOverview(
            volume_system, ['apfs1'])

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

        expected_output_data = [
            b'The following Apple File System (APFS) volumes were found:', b'',
            b'Identifier      Name', b'apfs1           SingleVolume', 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.º 6
0
    def _GetAPFSVolumeIdentifiers(self, scan_node):
        """Determines the APFS volume identifiers.

    Args:
      scan_node (SourceScanNode): scan node.

    Returns:
      list[str]: APFS volume identifiers.

    Raises:
      ScannerError: if the format of or within the source is not supported
          or the the scan node is invalid.
      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 = apfs_volume_system.APFSVolumeSystem()
        volume_system.Open(scan_node.path_spec)

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

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

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

        return self._NormalizedVolumeIdentifiers(volume_system,
                                                 volume_identifiers,
                                                 prefix='apfs')
Ejemplo n.º 7
0
    def testGetAPFSVolumeIdentifiers(self):
        """Tests the GetAPFSVolumeIdentifiers function."""
        test_path = self._GetTestFilePath(['apfs.dmg'])
        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_tsk_partition_path_spec = path_spec_factory.Factory.NewPathSpec(
            definitions.TYPE_INDICATOR_TSK_PARTITION,
            location='/p1',
            parent=test_raw_path_spec)
        test_apfs_container_path_spec = path_spec_factory.Factory.NewPathSpec(
            definitions.TYPE_INDICATOR_APFS_CONTAINER,
            location='/',
            parent=test_tsk_partition_path_spec)

        volume_system = apfs_volume_system.APFSVolumeSystem()
        volume_system.Open(test_apfs_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.GetAPFSVolumeIdentifiers(
            volume_system, ['apfs1'])

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

        # Test selection of single volume.
        input_file_object = io.BytesIO(b'apfs1\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.GetAPFSVolumeIdentifiers(
            volume_system, ['apfs1'])

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

        # Test selection of single volume with invalid input on first attempt.
        input_file_object = io.BytesIO(b'bogus\napfs1\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.GetAPFSVolumeIdentifiers(
            volume_system, ['apfs1'])

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

        # 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.GetAPFSVolumeIdentifiers(
            volume_system, ['apfs1'])

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

        # 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.GetAPFSVolumeIdentifiers(
            volume_system, ['apfs1'])

        self.assertEqual(volume_identifiers, [])
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
  def testGetAPFSVolumeIdentifiers(self):
    """Tests the GetAPFSVolumeIdentifiers function."""
    test_file_path = self._GetTestFilePath(['apfs.dmg'])
    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_tsk_partition_path_spec = path_spec_factory.Factory.NewPathSpec(
        dfvfs_definitions.PREFERRED_GPT_BACK_END, location='/p1',
        parent=test_raw_path_spec)
    test_apfs_container_path_spec = path_spec_factory.Factory.NewPathSpec(
        dfvfs_definitions.TYPE_INDICATOR_APFS_CONTAINER, location='/',
        parent=test_tsk_partition_path_spec)

    volume_system = apfs_volume_system.APFSVolumeSystem()
    volume_system.Open(test_apfs_container_path_spec)

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

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

    test_mediator = storage_media_tool.StorageMediaToolMediator(
        input_reader=test_input_reader, output_writer=test_output_writer)

    volume_identifiers = test_mediator.GetAPFSVolumeIdentifiers(
        volume_system, ['apfs1'])

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

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

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

    test_mediator = storage_media_tool.StorageMediaToolMediator(
        input_reader=test_input_reader, output_writer=test_output_writer)

    volume_identifiers = test_mediator.GetAPFSVolumeIdentifiers(
        volume_system, ['apfs1'])

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

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

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

    test_mediator = storage_media_tool.StorageMediaToolMediator(
        input_reader=test_input_reader, output_writer=test_output_writer)

    volume_identifiers = test_mediator.GetAPFSVolumeIdentifiers(
        volume_system, ['apfs1'])

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

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

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

    test_mediator = storage_media_tool.StorageMediaToolMediator(
        input_reader=test_input_reader, output_writer=test_output_writer)

    volume_identifiers = test_mediator.GetAPFSVolumeIdentifiers(
        volume_system, ['apfs1'])

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

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

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

    test_mediator = storage_media_tool.StorageMediaToolMediator(
        input_reader=test_input_reader, output_writer=test_output_writer)

    volume_identifiers = test_mediator.GetAPFSVolumeIdentifiers(
        volume_system, ['apfs1'])

    self.assertEqual(volume_identifiers, [])