CH-J Server Managermanagementul serverului peste SSH
Meniu
Sursă publicată

CH-J Server Manager

Navighează directoarele și fișierele pentru o anumită versiune a aplicației.

Descarcă sursa ZIP
CH-J / Server Manager 196 fișiere
core-20261013T133631Z-faa4ab45100e Adăugat: Data neînregistrată · Construit:
Fișiere
macNetworkIdentity.test.js Adăugat: Data neînregistrată 6,2 KB · 126 linii
Descarcă fișierul
1"use strict";
3const test = require("node:test");
4const assert = require("node:assert/strict");
5const fs = require("node:fs");
6const os = require("node:os");
7const path = require("node:path");
8const { uuidCommands, launcherUuid, prepareMacNetworkIdentity, verifyMacNetworkIdentity } = require("../scripts/macNetworkIdentity");
10function thin({ little = true, bits = 64, cpu = 0x100000c } = {}) {
11 const header = bits === 64 ? 32 : 28;
12 const bytes = Buffer.alloc(header + 24 + 16, 0);
13 const write = (value, offset) => little ? bytes.writeUInt32LE(value, offset) : bytes.writeUInt32BE(value, offset);
14 write(bits === 64 ? 0xfeedfacf : 0xfeedface, 0);
15 write(cpu, 4);
16 write(2, 12);
17 write(1, 16);
18 write(24, 20);
19 write(0x1b, header);
20 write(24, header + 4);
21 bytes.fill(0xab, header + 8, header + 24);
22 bytes.fill(0xcd, header + 24);
23 return bytes;
26function universal({ little = false, fat64 = false } = {}) {
27 const slices = [thin(), thin({ cpu: 0x1000007 })];
28 const stride = fat64 ? 32 : 20;
29 const header = 8 + slices.length * stride;
30 const bytes = Buffer.alloc(header + slices.reduce((sum, slice) => sum + slice.length, 0));
31 const write = (value, offset) => little ? bytes.writeUInt32LE(value, offset) : bytes.writeUInt32BE(value, offset);
32 const write64 = (value, offset) => little ? bytes.writeBigUInt64LE(BigInt(value), offset) : bytes.writeBigUInt64BE(BigInt(value), offset);
33 write(fat64 ? 0xcafebabf : 0xcafebabe, 0);
34 write(2, 4);
35 let offset = header;
36 slices.forEach((slice, i) => {
37 const cursor = 8 + i * stride;
38 write(slice.readUInt32LE(4), cursor);
39 if (fat64) { write64(offset, cursor + 8); write64(slice.length, cursor + 16); }
40 else { write(offset, cursor + 8); write(slice.length, cursor + 12); }
41 slice.copy(bytes, offset);
42 offset += slice.length;
43 });
44 return bytes;
47test("launcher UUID replacement preserves all other bytes for thin and universal Mach-O files", () => {
48 for (const little of [true, false]) {
49 for (const bytes of [thin({ little }), thin({ little, bits: 32 }), universal({ little }), universal({ little, fat64: true })]) {
50 const original = Buffer.from(bytes);
51 const commands = uuidCommands(bytes);
52 for (const entry of commands) launcherUuid(["de.ch-j.servermanager", "main", "payload"], entry).copy(bytes, entry.offset);
53 for (const entry of commands) original.copy(bytes, entry.offset, entry.offset, entry.offset + 16);
54 assert.deepEqual(bytes, original);
55 }
56 }
57});
59test("UUIDs are deterministic and differ across apps, payloads, launchers and architectures", () => {
60 const entry = uuidCommands(thin())[0];
61 const identity = ["de.ch-j.servermanager", "main", "payload"];
62 const expected = launcherUuid(identity, entry);
63 assert.deepEqual(launcherUuid(identity, entry), expected);
64 for (const changed of [["other.app", "main", "payload"], [identity[0], "helper", "payload"], [identity[0], "main", "new-payload"]]) {
65 assert.notDeepEqual(launcherUuid(changed, entry), expected);
66 }
67 assert.notDeepEqual(launcherUuid(identity, { ...entry, cpuType: 0x1000007 }), expected);
68 assert.equal(expected[6] >> 4, 8);
69 assert.equal(expected[8] >> 6, 2);
70});
72test("malformed Mach-O files fail before they can be patched", () => {
73 assert.throws(() => uuidCommands(Buffer.from("not a Mach-O")));
74 const missing = thin();
75 missing.writeUInt32LE(0x19, 32);
76 assert.throws(() => uuidCommands(missing), /exactly one LC_UUID/);
77 const badCommand = thin();
78 badCommand.writeUInt32LE(0, 36);
79 assert.throws(() => uuidCommands(badCommand), /load command/);
80 assert.throws(() => uuidCommands(thin().subarray(0, 50)), /bounds/);
81 const badSlice = universal();
82 badSlice.writeUInt32BE(1, 16);
83 assert.throws(() => uuidCommands(badSlice), /Overlapping/);
84 const hugeSlice = universal({ fat64: true });
85 hugeSlice.writeBigUInt64BE(2n ** 60n, 16);
86 assert.throws(() => uuidCommands(hugeSlice), /bounds/);
87});
89test("packaging validates plist, payload and all launchers and is idempotent", { skip: process.platform !== "darwin" }, (t) => {
90 const root = fs.mkdtempSync(path.join(os.tmpdir(), "chj-network-identity-"));
91 t.after(() => fs.rmSync(root, { recursive: true, force: true }));
92 const app = path.join(root, "Test.app");
93 const expected = { appId: "de.ch-j.servermanager", version: "0.0.1" };
94 function bundle(dir, id) {
95 fs.mkdirSync(path.join(dir, "Contents", "MacOS"), { recursive: true });
96 fs.writeFileSync(path.join(dir, "Contents", "Info.plist"), `<?xml version="1.0"?><plist version="1.0"><dict>
97 <key>CFBundleIdentifier</key><string>${id}</string>
98 <key>CFBundleExecutable</key><string>Test</string>
99 <key>CFBundleShortVersionString</key><string>0.0.1</string>
100 <key>NSLocalNetworkUsageDescription</key><string>SSH access to local servers.</string>
101 </dict></plist>`);
102 const executable = path.join(dir, "Contents", "MacOS", "Test");
103 fs.writeFileSync(executable, universal(), { mode: 0o755 });
104 return executable;
105 }
106 const executable = bundle(app, expected.appId);
107 bundle(path.join(app, "Contents", "Frameworks", "Helper.app"), `${expected.appId}.helper`);
108 const resources = path.join(app, "Contents", "Resources");
109 fs.mkdirSync(resources);
110 fs.writeFileSync(path.join(resources, "app.asar"), "first payload");
111 assert.throws(() => verifyMacNetworkIdentity(app, expected), /LC_UUID/);
112 const original = fs.readFileSync(executable);
113 assert.throws(() => prepareMacNetworkIdentity(app, { ...expected, appId: "wrong.id" }), /bundle ID/);
114 assert.throws(() => prepareMacNetworkIdentity(app, { ...expected, version: "9.9.9" }), /version/);
115 assert.deepEqual(fs.readFileSync(executable), original);
116 const prepared = prepareMacNetworkIdentity(app, expected);
117 assert.equal(new Set(prepared.map((entry) => entry.uuid)).size, 4);
118 const patched = fs.readFileSync(executable);
119 assert.deepEqual(verifyMacNetworkIdentity(app, expected), prepared);
120 assert.deepEqual(prepareMacNetworkIdentity(app, expected), prepared);
121 assert.deepEqual(fs.readFileSync(executable), patched);
122 assert.equal(fs.statSync(executable).mode & 0o777, 0o755);
123 fs.writeFileSync(path.join(resources, "app.asar"), "second payload");
124 assert.throws(() => verifyMacNetworkIdentity(app, expected), /LC_UUID/);
125 assert.notDeepEqual(prepareMacNetworkIdentity(app, expected), prepared);
126});
SHA-256daf691d15ff9d9ad2ec49b417e1424094a7e4ae35840b408d07f05084abdd573

CH-J Proprietary Software License 1.14 · Sursa este furnizată în cadrul CH-J Proprietary Software License 1.14. Disponibilitatea sa nu modifică termenii licenţei sau nu acordă drepturi suplimentare.

Archive SHA-256de757268dbc4f0226549f8b4f41f9b7e585c856ee97fa0d43b17a0e95c281449