mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-04 13:51:30 +00:00
142 lines
4.0 KiB
TypeScript
142 lines
4.0 KiB
TypeScript
import {
|
|
MAX_DISPATCH_WRAPPER_DEPTH,
|
|
resolveDispatchWrapperTrustPlan,
|
|
unwrapKnownDispatchWrapperInvocation,
|
|
} from "./dispatch-wrapper-resolution.js";
|
|
import {
|
|
extractShellWrapperInlineCommand,
|
|
isShellWrapperExecutable,
|
|
unwrapKnownShellMultiplexerInvocation,
|
|
} from "./shell-wrapper-resolution.js";
|
|
|
|
export type ExecWrapperTrustPlan = {
|
|
argv: string[];
|
|
policyArgv: string[];
|
|
wrapperChain: string[];
|
|
policyBlocked: boolean;
|
|
blockedWrapper?: string;
|
|
shellWrapperExecutable: boolean;
|
|
shellInlineCommand: string | null;
|
|
};
|
|
|
|
function blockedExecWrapperTrustPlan(params: {
|
|
argv: string[];
|
|
policyArgv?: string[];
|
|
wrapperChain: string[];
|
|
blockedWrapper: string;
|
|
}): ExecWrapperTrustPlan {
|
|
return {
|
|
argv: params.argv,
|
|
policyArgv: params.policyArgv ?? params.argv,
|
|
wrapperChain: params.wrapperChain,
|
|
policyBlocked: true,
|
|
blockedWrapper: params.blockedWrapper,
|
|
shellWrapperExecutable: false,
|
|
shellInlineCommand: null,
|
|
};
|
|
}
|
|
|
|
function finalizeExecWrapperTrustPlan(
|
|
argv: string[],
|
|
policyArgv: string[],
|
|
wrapperChain: string[],
|
|
policyBlocked: boolean,
|
|
blockedWrapper?: string,
|
|
): ExecWrapperTrustPlan {
|
|
const rawExecutable = argv[0]?.trim() ?? "";
|
|
const shellWrapperExecutable =
|
|
!policyBlocked && rawExecutable.length > 0 && isShellWrapperExecutable(rawExecutable);
|
|
return {
|
|
argv,
|
|
policyArgv,
|
|
wrapperChain,
|
|
policyBlocked,
|
|
blockedWrapper,
|
|
shellWrapperExecutable,
|
|
shellInlineCommand: shellWrapperExecutable ? extractShellWrapperInlineCommand(argv) : null,
|
|
};
|
|
}
|
|
|
|
export function resolveExecWrapperTrustPlan(
|
|
argv: string[],
|
|
maxDepth = MAX_DISPATCH_WRAPPER_DEPTH,
|
|
): ExecWrapperTrustPlan {
|
|
let current = argv;
|
|
let policyArgv = argv;
|
|
let sawShellMultiplexer = false;
|
|
const wrapperChain: string[] = [];
|
|
for (let depth = 0; depth < maxDepth; depth += 1) {
|
|
const dispatchPlan = resolveDispatchWrapperTrustPlan(current, maxDepth - wrapperChain.length);
|
|
if (dispatchPlan.policyBlocked) {
|
|
return blockedExecWrapperTrustPlan({
|
|
argv: dispatchPlan.argv,
|
|
policyArgv: dispatchPlan.argv,
|
|
wrapperChain,
|
|
blockedWrapper: dispatchPlan.blockedWrapper ?? current[0] ?? "unknown",
|
|
});
|
|
}
|
|
if (dispatchPlan.wrappers.length > 0) {
|
|
wrapperChain.push(...dispatchPlan.wrappers);
|
|
current = dispatchPlan.argv;
|
|
if (!sawShellMultiplexer) {
|
|
policyArgv = current;
|
|
}
|
|
if (wrapperChain.length >= maxDepth) {
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
const shellMultiplexerUnwrap = unwrapKnownShellMultiplexerInvocation(current);
|
|
if (shellMultiplexerUnwrap.kind === "blocked") {
|
|
return blockedExecWrapperTrustPlan({
|
|
argv: current,
|
|
policyArgv,
|
|
wrapperChain,
|
|
blockedWrapper: shellMultiplexerUnwrap.wrapper,
|
|
});
|
|
}
|
|
if (shellMultiplexerUnwrap.kind === "unwrapped") {
|
|
wrapperChain.push(shellMultiplexerUnwrap.wrapper);
|
|
if (!sawShellMultiplexer) {
|
|
// Preserve the real executable target for trust checks.
|
|
policyArgv = current;
|
|
sawShellMultiplexer = true;
|
|
}
|
|
current = shellMultiplexerUnwrap.argv;
|
|
if (wrapperChain.length >= maxDepth) {
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if (wrapperChain.length >= maxDepth) {
|
|
const dispatchOverflow = unwrapKnownDispatchWrapperInvocation(current);
|
|
if (dispatchOverflow.kind === "blocked" || dispatchOverflow.kind === "unwrapped") {
|
|
return blockedExecWrapperTrustPlan({
|
|
argv: current,
|
|
policyArgv,
|
|
wrapperChain,
|
|
blockedWrapper: dispatchOverflow.wrapper,
|
|
});
|
|
}
|
|
const shellMultiplexerOverflow = unwrapKnownShellMultiplexerInvocation(current);
|
|
if (
|
|
shellMultiplexerOverflow.kind === "blocked" ||
|
|
shellMultiplexerOverflow.kind === "unwrapped"
|
|
) {
|
|
return blockedExecWrapperTrustPlan({
|
|
argv: current,
|
|
policyArgv,
|
|
wrapperChain,
|
|
blockedWrapper: shellMultiplexerOverflow.wrapper,
|
|
});
|
|
}
|
|
}
|
|
|
|
return finalizeExecWrapperTrustPlan(current, policyArgv, wrapperChain, false);
|
|
}
|