XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
"""Offline image-policy negative controls; actual boot acceptance is recorded separately."""
import copy
import json
from pathlib import Path
import subprocess
import struct
import tempfile
import unittest
import zlib

from ReadImage import verify_single_edition

ROOT = Path(__file__).resolve().parents[2]


class SingleEditionImageTests(unittest.TestCase):
    def fixture(self, edition='Desktop'):
        paths = sorted(['EFI/BOOT/BOOTX64.EFI', 'EFI/XFE/Limine.efi', 'System/Kernel.elf', 'System/BootShim.json', 'Limine.conf'])
        manifest = {'Edition': edition, 'DeploymentPolicy': 'SingleEditionOnly', 'ImageBytes': 134217728,
            'BootEntries': [edition], 'DefaultBootEntry': edition, 'BootMenuTimeoutSeconds': 0,
            'Resolution': '1280x800', 'IndependentKernelBuild': {'Edition': edition}}
        config = ('timeout: 0\nserial: yes\nverbose: no\nterse: yes\nquiet: yes\nfirmware_logo: no\n\n'
            f'/XFESystem {edition}\n    protocol: limine\n    resolution: 1280x800x32\n    path: boot():/System/Kernel.elf\n')
        return {'FilePaths': paths}, {'Limine.conf': config.encode()}, manifest

    def test_each_edition_has_one_kernel_and_no_selection_menu(self):
        for edition in ('Console', 'Desktop'):
            with self.subTest(edition=edition):
                result = verify_single_edition(*self.fixture(edition))
                self.assertEqual(edition, result['Edition'])
                self.assertFalse(result['SystemSelectionMenu'])

    def usb_fixture(self, edition='Desktop'):
        inspection, files, manifest = self.fixture(edition)
        inspection['FilePaths'] = sorted(inspection['FilePaths'] + ['Workspace.bin', 'UserFiles/UsbHello.dll'])
        inspection['FileFirstLbas'] = {'Workspace.bin': 4096}
        manifest.update(UsbWorkspace=True, ImageBytes=268435456, WorkspaceBytes=67108864, WorkspaceFirstLba=4096)
        workspace = bytearray(67108864)
        struct.pack_into('<QIII', workspace, 0, 0x5357425355454658, 1, 131072, 65535)
        struct.pack_into('<I', workspace, 20, zlib.crc32(workspace[:20]))
        files['Workspace.bin'] = workspace
        return inspection, files, manifest

    def test_usb_workspace_keeps_exactly_one_edition(self):
        for edition in ('Console', 'Desktop'):
            proof = verify_single_edition(*self.usb_fixture(edition))
            self.assertTrue(proof['UsbWorkspace'])
            self.assertEqual(proof['KernelCount'], 1)
            self.assertFalse(proof['SystemSelectionMenu'])

    def test_usb_workspace_checksum_extent_and_size_are_required(self):
        for change in ('crc', 'extent', 'size'):
            inspection, files, manifest = self.usb_fixture()
            if change == 'crc': files['Workspace.bin'][20] ^= 1
            elif change == 'extent': manifest['WorkspaceFirstLba'] += 1
            else: manifest['WorkspaceBytes'] -= 512
            with self.subTest(change=change), self.assertRaises(AssertionError):
                verify_single_edition(inspection, files, manifest)

    def test_dual_or_mislabeled_kernel_is_rejected(self):
        for edition in ('Dual', 'Unknown'):
            inspection, files, manifest = self.fixture(); manifest['Edition'] = edition
            with self.subTest(edition=edition), self.assertRaises(AssertionError):
                verify_single_edition(inspection, files, manifest)
        inspection, files, manifest = self.fixture(); manifest['IndependentKernelBuild']['Edition'] = 'Console'
        with self.assertRaises(AssertionError): verify_single_edition(inspection, files, manifest)

    def test_multiple_boot_entries_are_rejected(self):
        inspection, files, manifest = self.fixture(); manifest['BootEntries'].append('Console')
        with self.assertRaises(AssertionError): verify_single_edition(inspection, files, manifest)

    def test_second_kernel_in_manifest_is_rejected(self):
        for key in ('ConsoleKernelPath', 'ConsoleKernelSha256', 'IndependentConsoleKernelBuild'):
            inspection, files, manifest = self.fixture(); manifest[key] = 'second kernel'
            with self.subTest(key=key), self.assertRaises(AssertionError):
                verify_single_edition(inspection, files, manifest)

    def test_hidden_second_kernel_in_actual_fat_inventory_is_rejected(self):
        inspection, files, manifest = self.fixture(); inspection['FilePaths'].append('System/Console.elf')
        with self.assertRaises(AssertionError): verify_single_edition(inspection, files, manifest)

    def test_menu_and_kernel_path_changes_are_rejected(self):
        _, baseline, _ = self.fixture()
        for config in (baseline['Limine.conf'] + b'\n/XFESystem Console\n',
                       baseline['Limine.conf'].replace(b'quiet: yes', b'quiet: no'),
                       baseline['Limine.conf'].replace(b'System/Kernel.elf', b'System/Console.elf')):
            inspection, files, manifest = self.fixture(); files['Limine.conf'] = config
            with self.subTest(config=config), self.assertRaises(AssertionError):
                verify_single_edition(inspection, files, manifest)

    def test_timeout_and_old_dual_size_are_rejected(self):
        for changes in ({'BootMenuTimeoutSeconds': 10}, {'ImageBytes': 268435456}, {'DeploymentPolicy': 'Dual'}):
            inspection, files, manifest = self.fixture(); manifest.update(changes)
            with self.subTest(changes=changes), self.assertRaises(AssertionError):
                verify_single_edition(inspection, files, manifest)

    def test_old_combined_image_cli_cannot_write_output(self):
        with tempfile.TemporaryDirectory() as folder:
            output = Path(folder)/'System.img'
            result = subprocess.run(['dotnet', str(ROOT/'Tools/CSharpBoot/bin/Release/net10.0/PackImage.dll'),
                'Desktop.elf', str(output), '1280x800', '--independent-kernel', '--console-kernel', 'Console.elf'],
                capture_output=True, text=True)
            self.assertNotEqual(0, result.returncode)
            self.assertIn('dual-system images are no longer generated', result.stderr)
            self.assertFalse(output.exists())

    def test_old_dual_media_profile_is_rejected_before_disk_access(self):
        for write in (False, True):
            with self.subTest(write=write), tempfile.TemporaryDirectory() as folder:
                log = Path(folder)/'Rejected.json'
                result = subprocess.run(['powershell.exe', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass',
                    '-File', str(ROOT/'scripts/physical-media.ps1'), '-ImageProfile', 'IndependentDualCSharp256',
                    '-ResultPath', str(log), *(['-Write'] if write else [])], capture_output=True)
                self.assertNotEqual(0, result.returncode)
                receipt = json.loads(log.read_text(encoding='utf-8-sig'))
                self.assertFalse(receipt['PhysicalDiskOpened'])
                self.assertTrue(receipt['HandlesClosed'])
                self.assertEqual('failed', receipt['Status'])
                self.assertIn('Dual-system deployment was retired', receipt['Error'])


if __name__ == '__main__':
    unittest.main()