mirror of
https://github.com/morluto/rea.git
synced 2026-11-09 00:07:18 +00:00
* docs: organize canonical documentation layout (URGENTE) Group all existing authored guides by domain and ownership, expose complete navigation, and preserve their public routes. Update physical path consumers and release configuration while retaining historical records. Document domain-based specs and ADR slugs without global numbering. Co-Authored-By: Codex <noreply@openai.com> * fix(docs): honor home layout in all-page route verification * style: format reviewed source changes * fix(docs): preserve routes and navigation cache inputs * fix: repair the static-check failures on the default branch (#2895) * fix: repair the static-check failures on the default branch The default branch fails its own required `Static checks` job three ways, so every pull request reports that job as failed regardless of its own change. - `npm run format:check` reports `src/domain/functionComparison.test.ts` and `src/ida/IdaOperationRunner.ts`. - `npm run lint` reports a duplicate `import { join } from "node:path"` in `tests/boundary/mcp/ghidraInventoryMcp.test.ts` (lines 4 and 17). - `npm run typecheck` reports `format: "devin"` missing from the client format union in `src/application/SupportedClients.ts`, and an unchecked index in `tests/boundary/cli/clientProfileLifecycle.test.ts`, whose pair array is inferred as `string[][]`. Apply the pinned formatter, drop the duplicate import, list the `"devin"` format that its own definition already uses, and mark the pair array `as const`. Validation: `npm run check:fast` and `npm run format:check` pass. * fix(setup): keep Devin on the JSON configuration dialect --------- Co-authored-by: 吴佳浩 <wujiahao@supremind.com> Co-authored-by: morluto <76467478+morluto@users.noreply.github.com> * fix(docs): update links after guide relocation * docs: correct verified documentation route counts * fix(docs): update browser capture guide link after move (#2820) Refresh gettext protected-link comments alongside the authored href. Co-authored-by: Codex <noreply@openai.com> * fix(docs): include http3 lab in stable routes * fix(docs): preserve historical release evidence and links * fix(ghidra): restore Windows verifier identity import * docs(wakaru): preserve pinned upstream policy link * docs(index): retain recently added guide links * docs(mcp): preserve parent retention clarification * fix(cli): preserve standalone import guidance * fix(test): preserve translated guide link drift coverage --------- Co-authored-by: Matheus Breguêz <matbrgz@gmail.com> Co-authored-by: Codex <noreply@openai.com> Co-authored-by: morluto <17176810+morluto@users.noreply.github.com> Co-authored-by: 吴佳浩Alben <35291372+XiaoBinGan@users.noreply.github.com> Co-authored-by: 吴佳浩 <wujiahao@supremind.com>
315 lines
9.5 KiB
JavaScript
315 lines
9.5 KiB
JavaScript
import { isDeepStrictEqual, promisify } from "node:util";
|
|
import { resolve } from "node:path";
|
|
import { pathToFileURL, fileURLToPath } from "node:url";
|
|
import { execFile } from "node:child_process";
|
|
|
|
export const verifyPacketPage = (first, next, oracle) => {
|
|
if (
|
|
first.artifact.sha256 !== oracle.sha256 ||
|
|
next.artifact.sha256 !== oracle.sha256 ||
|
|
first.output_window.matching_packets !== oracle.matching_packets ||
|
|
next.output_window.matching_packets !== oracle.matching_packets ||
|
|
!isDeepStrictEqual(
|
|
packetFacts("postgres", first).rows,
|
|
oracle.rows.slice(0, 12),
|
|
) ||
|
|
!isDeepStrictEqual(
|
|
packetFacts("postgres", next).rows,
|
|
oracle.rows.slice(12, 24),
|
|
)
|
|
)
|
|
throw new Error(
|
|
"Packet pages differ from independently parsed original matches",
|
|
);
|
|
};
|
|
|
|
export const PACKET_ARTIFACTS = {
|
|
"wireshark-pgsql-jdbc.pcap": {
|
|
kind: "postgres",
|
|
fields: ["tcp.srcport", "tcp.dstport", "tcp.flags"],
|
|
extra: ["tcp.len"],
|
|
protocol: "tcp",
|
|
query: "tcp.flags",
|
|
discovered: "tcp.flags",
|
|
filter: "tcp.port == 5432",
|
|
},
|
|
"wireshark-dns.cap": {
|
|
kind: "dns",
|
|
fields: [
|
|
"dns.id",
|
|
"dns.flags.response",
|
|
"dns.flags.rcode",
|
|
"dns.qry.name",
|
|
"dns.qry.type",
|
|
],
|
|
extra: ["dns.resp.name", "dns.resp.ttl", "udp.srcport", "udp.dstport"],
|
|
protocol: "dns",
|
|
query: "dns.flags.rcode",
|
|
discovered: "dns.flags.rcode",
|
|
filter: "dns.flags.response == 1 && dns.flags.rcode != 0",
|
|
},
|
|
"wireshark-dhcp.pcap": {
|
|
kind: "dhcp",
|
|
fields: [
|
|
"dhcp.id",
|
|
"dhcp.option.dhcp",
|
|
"dhcp.ip.your",
|
|
"dhcp.option.dhcp_server_id",
|
|
],
|
|
extra: [
|
|
"dhcp.type",
|
|
"dhcp.ip.client",
|
|
"dhcp.hw.mac_addr",
|
|
"udp.srcport",
|
|
"udp.dstport",
|
|
],
|
|
protocol: "dhcp",
|
|
query: "Option 53:",
|
|
discovered: "dhcp.option.dhcp",
|
|
filter: "dhcp",
|
|
},
|
|
};
|
|
|
|
export const packetRequest = (artifact, path, selection) => {
|
|
const descriptor = PACKET_ARTIFACTS[artifact];
|
|
if (!descriptor) throw new Error("Unknown pinned packet question");
|
|
const baseline = selection === "baseline";
|
|
return {
|
|
path,
|
|
fields: baseline
|
|
? [...descriptor.fields, ...descriptor.extra]
|
|
: descriptor.fields,
|
|
display_filter:
|
|
descriptor.kind === "postgres" && baseline
|
|
? `${descriptor.filter} && frame.number <= 2000`
|
|
: descriptor.kind === "dns" && baseline
|
|
? "dns"
|
|
: descriptor.filter,
|
|
...(descriptor.kind === "postgres" && !baseline
|
|
? { packet_limit: 2000, match_limit: 12 }
|
|
: {}),
|
|
};
|
|
};
|
|
|
|
const number = (row, field) => {
|
|
const value = row[field];
|
|
if (
|
|
!Array.isArray(value) ||
|
|
value.length !== 1 ||
|
|
!/^(?:[0-9]+|0x[0-9a-f]+)$/iu.test(value[0])
|
|
)
|
|
throw new Error(`Expected one recorded integer for ${field}`);
|
|
const parsed = Number(value[0]);
|
|
if (!Number.isSafeInteger(parsed))
|
|
throw new Error(`Unsafe recorded integer for ${field}`);
|
|
return parsed;
|
|
};
|
|
|
|
export const packetFacts = (kind, report) => {
|
|
let packets = report.packets;
|
|
if (kind === "postgres") packets = packets.slice(0, 12);
|
|
if (kind === "dns")
|
|
packets = packets.filter(
|
|
(row) =>
|
|
number(row, "dns.flags.response") === 1 &&
|
|
number(row, "dns.flags.rcode") !== 0,
|
|
);
|
|
return {
|
|
kind,
|
|
matching_packets:
|
|
kind === "dns" ? packets.length : report.output_window.matching_packets,
|
|
rows: packets.map((row) => {
|
|
const frame = number(row, "frame.number");
|
|
if (kind === "postgres")
|
|
return {
|
|
frame,
|
|
source_port: number(row, "tcp.srcport"),
|
|
destination_port: number(row, "tcp.dstport"),
|
|
flags: number(row, "tcp.flags"),
|
|
};
|
|
if (kind === "dns") {
|
|
const names = row["dns.qry.name"];
|
|
const types = row["dns.qry.type"];
|
|
if (
|
|
!Array.isArray(names) ||
|
|
names.length === 0 ||
|
|
!Array.isArray(types) ||
|
|
types.length !== names.length
|
|
)
|
|
throw new Error(
|
|
"The fixed DNS question requires recorded names and types; missing fields are unknown",
|
|
);
|
|
return {
|
|
frame,
|
|
id: number(row, "dns.id"),
|
|
rcode: number(row, "dns.flags.rcode"),
|
|
names,
|
|
types: types.map((value) => number({ type: [value] }, "type")),
|
|
};
|
|
}
|
|
const server = row["dhcp.option.dhcp_server_id"];
|
|
const address = row["dhcp.ip.your"];
|
|
if (
|
|
!Array.isArray(address) ||
|
|
address.length !== 1 ||
|
|
(server !== undefined &&
|
|
(!Array.isArray(server) || server.length !== 1))
|
|
)
|
|
throw new Error("Expected recorded DHCP address scalar");
|
|
return {
|
|
frame,
|
|
id: number(row, "dhcp.id"),
|
|
message_type: number(row, "dhcp.option.dhcp"),
|
|
your_address: address[0],
|
|
...(server === undefined ? {} : { server_identifier: server[0] }),
|
|
};
|
|
}),
|
|
};
|
|
};
|
|
|
|
export const measurePacketEntry = async ({
|
|
values,
|
|
call,
|
|
inputSha,
|
|
catalogDefinitions,
|
|
}) => {
|
|
const descriptor = PACKET_ARTIFACTS[values.artifact];
|
|
const { parseEvidence } = await import(
|
|
pathToFileURL(resolve(values["runtime-root"], "dist/domain/evidence.js"))
|
|
.href
|
|
);
|
|
const { inspectPacketCaptureInputSchema, packetCaptureSchema } = await import(
|
|
pathToFileURL(
|
|
resolve(values["runtime-root"], "dist/domain/captures/packetCapture.js"),
|
|
).href
|
|
);
|
|
const { inspectPacketFieldsInputSchema, packetFieldsCatalogSchema } =
|
|
await import(
|
|
pathToFileURL(
|
|
resolve(values["runtime-root"], "dist/domain/captures/packetFields.js"),
|
|
).href
|
|
);
|
|
const observations = [];
|
|
const selection = values["packet-selection"];
|
|
const checked = (evidence, operation, input, schema) => {
|
|
parseEvidence(evidence);
|
|
const report = schema.parse(evidence.normalized_result);
|
|
if (
|
|
evidence.operation !== operation ||
|
|
!isDeepStrictEqual(evidence.parameters, input) ||
|
|
!isDeepStrictEqual(report.selection, input)
|
|
)
|
|
throw new Error(
|
|
"Packet Evidence operation or choices differs from the request",
|
|
);
|
|
if (
|
|
operation === "inspect_packet_capture" &&
|
|
(evidence.subject?.local_path !== values.path ||
|
|
evidence.subject?.digest?.sha256 !== inputSha ||
|
|
report.artifact.path !== values.path ||
|
|
report.artifact.sha256 !== inputSha)
|
|
)
|
|
throw new Error("Packet Evidence identifies different capture bytes");
|
|
if (
|
|
operation === "inspect_packet_fields" &&
|
|
(evidence.subject?.local_path !== report.tool.path ||
|
|
evidence.subject?.digest?.sha256 !== report.tool.sha256)
|
|
)
|
|
throw new Error("Field discovery identifies a different executable");
|
|
observations.push({
|
|
evidence_id: evidence.evidence_id,
|
|
operation,
|
|
selection: report.selection,
|
|
output_window: report.output_window,
|
|
read_scope: report.read_scope ?? null,
|
|
limitations: evidence.limitations,
|
|
});
|
|
return report;
|
|
};
|
|
if (selection === "discovery") {
|
|
const input = inspectPacketFieldsInputSchema.parse({
|
|
kind: "fields",
|
|
protocol: descriptor.protocol,
|
|
query: descriptor.query,
|
|
limit: 1,
|
|
});
|
|
const found = checked(
|
|
await call("inspect_packet_fields", input),
|
|
"inspect_packet_fields",
|
|
input,
|
|
packetFieldsCatalogSchema,
|
|
);
|
|
if (
|
|
!found.records.some((row) => row.abbreviation === descriptor.discovered)
|
|
)
|
|
throw new Error(
|
|
"Selected installation does not advertise the required protocol field",
|
|
);
|
|
}
|
|
const input = inspectPacketCaptureInputSchema.parse(
|
|
packetRequest(values.artifact, values.path, selection),
|
|
);
|
|
for (const name of [
|
|
"inspect_packet_capture",
|
|
...(selection === "discovery" ? ["inspect_packet_fields"] : []),
|
|
])
|
|
if (!catalogDefinitions.has(name))
|
|
throw new Error(`Missing live packet contract ${name}`);
|
|
const report = checked(
|
|
await call("inspect_packet_capture", input),
|
|
"inspect_packet_capture",
|
|
input,
|
|
packetCaptureSchema,
|
|
);
|
|
const facts = packetFacts(descriptor.kind, report);
|
|
if (selection === "pages") {
|
|
const { stdout } = await promisify(execFile)(
|
|
"python3",
|
|
[
|
|
fileURLToPath(new URL("./packet-oracle.py", import.meta.url)),
|
|
"postgres",
|
|
values.path,
|
|
"--row-limit",
|
|
"24",
|
|
],
|
|
{ timeout: 30_000, maxBuffer: 128 * 1024 },
|
|
);
|
|
const oracle = JSON.parse(stdout);
|
|
const nextInput = inspectPacketCaptureInputSchema.parse({
|
|
...input,
|
|
match_offset: 12,
|
|
});
|
|
const next = checked(
|
|
await call("inspect_packet_capture", nextInput),
|
|
"inspect_packet_capture",
|
|
nextInput,
|
|
packetCaptureSchema,
|
|
);
|
|
const repeated = checked(
|
|
await call("inspect_packet_capture", input),
|
|
"inspect_packet_capture",
|
|
input,
|
|
packetCaptureSchema,
|
|
);
|
|
verifyPacketPage(report, next, oracle);
|
|
if (
|
|
!isDeepStrictEqual(report.packets, repeated.packets) ||
|
|
!isDeepStrictEqual(report.output_window, repeated.output_window) ||
|
|
next.artifact.sha256 !== report.artifact.sha256 ||
|
|
next.output_window.matching_packets !==
|
|
report.output_window.matching_packets ||
|
|
Number(next.packets[0]?.["frame.number"]?.[0]) <=
|
|
Number(report.packets.at(-1)?.["frame.number"]?.[0])
|
|
)
|
|
throw new Error(
|
|
"Packet page order, digest or repeated observations changed",
|
|
);
|
|
}
|
|
return {
|
|
artifact_sha256: inputSha,
|
|
facts,
|
|
delivery_observations: observations,
|
|
evidence_ids: [...new Set(observations.map((row) => row.evidence_id))],
|
|
};
|
|
};
|