Example #1
0
    def testReadFileEntriesOnBinary(self):
        """Tests the _ReadFileEntries function on binary format."""
        output_writer = test_lib.TestOutputWriter()
        test_file = cpio.CPIOArchiveFile(output_writer=output_writer)
        test_file.file_format = 'bin-little-endian'

        test_file_path = self._GetTestFilePath(['cpio', 'syslog.bin.cpio'])
        with open(test_file_path, 'rb') as file_object:
            test_file._ReadFileEntries(file_object)

        self.assertEqual(len(test_file._file_entries), 1)
Example #2
0
    def testReadFileEntryOnNewASCII(self):
        """Tests the _ReadFileEntry function on new ASCII format."""
        output_writer = test_lib.TestOutputWriter()
        test_file = cpio.CPIOArchiveFile(output_writer=output_writer)
        test_file.file_format = 'newc'

        test_file_path = self._GetTestFilePath(['cpio', 'syslog.newc.cpio'])
        with open(test_file_path, 'rb') as file_object:
            file_entry = test_file._ReadFileEntry(file_object, 0)

        self.assertEqual(file_entry.data_size, 1247)
Example #3
0
    def testReadFileObjectOnPortableASCII(self):
        """Tests the ReadFileObject function on portable ASCII format."""
        output_writer = test_lib.TestOutputWriter()
        test_file = cpio.CPIOArchiveFile(debug=True,
                                         output_writer=output_writer)

        test_file_path = self._GetTestFilePath(['cpio', 'syslog.odc.cpio'])
        test_file.Open(test_file_path)

        self.assertEqual(test_file.file_format, 'odc')

        test_file.Close()
Example #4
0
    def testReadFileObjectOnNewASCIIWithCRC(self):
        """Tests the ReadFileObject function on new ASCII with CRC format."""
        output_writer = test_lib.TestOutputWriter()
        test_file = cpio.CPIOArchiveFile(debug=True,
                                         output_writer=output_writer)

        test_file_path = self._GetTestFilePath(['cpio', 'syslog.crc.cpio'])
        test_file.Open(test_file_path)

        self.assertEqual(test_file.file_format, 'crc')

        test_file.Close()
Example #5
0
    def testReadFileObjectOnBinary(self):
        """Tests the ReadFileObject function on binary format."""
        output_writer = test_lib.TestOutputWriter()
        test_file = cpio.CPIOArchiveFile(debug=True,
                                         output_writer=output_writer)

        test_file_path = self._GetTestFilePath(['cpio', 'syslog.bin.cpio'])
        test_file.Open(test_file_path)

        self.assertEqual(test_file.file_format, 'bin-little-endian')

        test_file.Close()
Example #6
0
    def testGetFileEntryByPathOnBinary(self):
        """Tests the GetFileEntryByPath function on binary format."""
        output_writer = test_lib.TestOutputWriter()
        test_file = cpio.CPIOArchiveFile(output_writer=output_writer)

        test_file_path = self._GetTestFilePath(['cpio', 'syslog.bin.cpio'])
        test_file.Open(test_file_path)

        file_entry = test_file.GetFileEntryByPath('syslog')
        self.assertIsNotNone(file_entry)

        file_entry = test_file.GetFileEntryByPath('bogus')
        self.assertIsNone(file_entry)

        test_file.Close()
Example #7
0
    def testGetFileEntriesOnBinary(self):
        """Tests the GetFileEntries function on binary format."""
        output_writer = test_lib.TestOutputWriter()
        test_file = cpio.CPIOArchiveFile(output_writer=output_writer)

        test_file_path = self._GetTestFilePath(['cpio', 'syslog.bin.cpio'])
        test_file.Open(test_file_path)

        file_entries = list(test_file.GetFileEntries())
        self.assertEqual(len(file_entries), 1)

        test_file.Close()

        file_entries = list(test_file.GetFileEntries())
        self.assertEqual(len(file_entries), 0)
Example #8
0
    def testFileEntryExistsByPathOnBinary(self):
        """Tests the FileEntryExistsByPath function on binary format."""
        output_writer = test_lib.TestOutputWriter()
        test_file = cpio.CPIOArchiveFile(output_writer=output_writer)

        test_file_path = self._GetTestFilePath(['cpio', 'syslog.bin.cpio'])
        test_file.Open(test_file_path)

        result = test_file.FileEntryExistsByPath('syslog')
        self.assertTrue(result)

        result = test_file.FileEntryExistsByPath('bogus')
        self.assertFalse(result)

        test_file.Close()
Example #9
0
    def testDebugPrintFileEntry(self):
        """Tests the _DebugPrintFileEntry function."""
        output_writer = test_lib.TestOutputWriter()
        test_file = cpio.CPIOArchiveFile(output_writer=output_writer)
        test_file.file_format = 'bin-little-endian'

        data_type_map = test_file._GetDataTypeMap(
            'cpio_binary_little_endian_file_entry')

        file_entry = data_type_map.CreateStructureValues(
            device_number=1,
            file_size=0,
            group_identifier=1001,
            inode_number=2,
            mode=0o777,
            modification_time=0,
            number_of_links=1,
            path_size=0,
            signature=0x71c7,
            special_device_number=0,
            user_identifier=1000)

        test_file._DebugPrintFileEntry(file_entry)

        test_file.file_format = 'newc'

        data_type_map = test_file._GetDataTypeMap('cpio_new_ascii_file_entry')

        file_entry = data_type_map.CreateStructureValues(
            checksum=0x12345678,
            device_major_number=3,
            device_minor_number=4,
            file_size=0,
            group_identifier=1001,
            inode_number=2,
            mode=0o777,
            modification_time=0,
            number_of_links=1,
            path_size=0,
            signature=b'070702',
            special_device_major_number=5,
            special_device_minor_number=5,
            user_identifier=1000)

        test_file._DebugPrintFileEntry(file_entry)
Example #10
0
    def HashFileEntries(self):
        """Hashes the file entries stored in the CPIO archive file."""
        stat_object = os.stat(self._path)

        file_object = open(self._path, 'rb')

        file_offset = 0
        file_size = stat_object.st_size

        # initrd files can consist of an uncompressed and compressed cpio archive.
        # Keeping the functionality in this script for now, but this likely
        # needs to be in a separate initrd hashing script.
        while file_offset < stat_object.st_size:
            file_object.seek(file_offset, os.SEEK_SET)
            signature_data = file_object.read(6)

            file_type = None
            if len(signature_data) > 2:
                if (signature_data[:2]
                        in (self._CPIO_SIGNATURE_BINARY_BIG_ENDIAN,
                            self._CPIO_SIGNATURE_BINARY_LITTLE_ENDIAN)
                        or signature_data
                        in (self._CPIO_SIGNATURE_PORTABLE_ASCII,
                            self._CPIO_SIGNATURE_NEW_ASCII,
                            self._CPIO_SIGNATURE_NEW_ASCII_WITH_CHECKSUM)):
                    file_type = 'cpio'
                elif signature_data[:2] == self._GZIP_SIGNATURE:
                    file_type = 'gzip'
                elif signature_data[:2] == self._BZIP_SIGNATURE:
                    file_type = 'bzip'
                elif signature_data == self._XZ_SIGNATURE:
                    file_type = 'xz'

            if not file_type:
                self._output_writer.WriteText(
                    'Unsupported file type at offset: 0x{0:08x}.\n'.format(
                        file_offset))
                return

            if file_type == 'cpio':
                file_object.seek(file_offset, os.SEEK_SET)
                cpio_file_object = file_object
            elif file_type in ('bzip', 'gzip', 'xz'):
                compressed_data_size = file_size - file_offset
                compressed_data_file_object = data_range.DataRange(
                    file_object,
                    data_offset=file_offset,
                    data_size=compressed_data_size)

                if file_type == 'bzip':
                    cpio_file_object = bz2.BZ2File(compressed_data_file_object)
                elif file_type == 'gzip':
                    cpio_file_object = gzip.GzipFile(
                        fileobj=compressed_data_file_object)  # pylint: disable=no-member
                elif file_type == 'xz' and lzma:
                    cpio_file_object = lzma.LZMAFile(
                        compressed_data_file_object)

            cpio_archive_file = cpio.CPIOArchiveFile(debug=self._debug)
            cpio_archive_file.ReadFileObject(cpio_file_object)

            for file_entry in sorted(cpio_archive_file.GetFileEntries()):
                if file_entry.data_size == 0:
                    continue

                sha256_context = hashlib.sha256()
                file_data = file_entry.read(4096)
                while file_data:
                    sha256_context.update(file_data)
                    file_data = file_entry.read(4096)

                self._output_writer.WriteText('{0:s}\t{1:s}\n'.format(
                    sha256_context.hexdigest(), file_entry.path))

            file_offset += cpio_archive_file.size

            padding_size = file_offset % 16
            if padding_size > 0:
                file_offset += 16 - padding_size

            cpio_archive_file.Close()
Example #11
0
def Main():
    """The main program function.

  Returns:
    bool: True if successful or False if not.
  """
    argument_parser = argparse.ArgumentParser(
        description=('Extracts information from CPIO archive files.'))

    argument_parser.add_argument('-d',
                                 '--debug',
                                 dest='debug',
                                 action='store_true',
                                 default=False,
                                 help='enable debug output.')

    argument_parser.add_argument(
        '--hash',
        dest='hash',
        action='store_true',
        default=False,
        help='calculate the SHA-256 sum of the file entries.')

    argument_parser.add_argument('source',
                                 nargs='?',
                                 action='store',
                                 metavar='PATH',
                                 default=None,
                                 help='path of the CPIO archive file.')

    options = argument_parser.parse_args()

    if not options.source:
        print('Source file missing.')
        print('')
        argument_parser.print_help()
        print('')
        return False

    logging.basicConfig(level=logging.INFO,
                        format='[%(levelname)s] %(message)s')

    output_writer = output_writers.StdoutWriter()

    try:
        output_writer.Open()
    except IOError as exception:
        print(
            'Unable to open output writer with error: {0!s}'.format(exception))
        print('')
        return False

    if options.hash:
        cpio_archive_file_hasher = CPIOArchiveFileHasher(
            options.source, debug=options.debug, output_writer=output_writer)

        cpio_archive_file_hasher.HashFileEntries()

    else:
        # TODO: move functionality to CPIOArchiveFileInfo.
        cpio_archive_file = cpio.CPIOArchiveFile(debug=options.debug,
                                                 output_writer=output_writer)
        cpio_archive_file.Open(options.source)

        output_writer.WriteText('CPIO archive information:\n')
        output_writer.WriteText('\tFormat\t\t: {0:s}\n'.format(
            cpio_archive_file.file_format))
        output_writer.WriteText('\tSize\t\t: {0:d} bytes\n'.format(
            cpio_archive_file.size))

        cpio_archive_file.Close()

    output_writer.WriteText('\n')
    output_writer.Close()

    return True