src/vs/platform/sandbox/common/terminalSandboxService.ts

185 LOC · 159 covered · 26 uncovered · 14 ranges · 1052 concepts · 1 introducers · 489 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- terminalSandboxEngine.ts ×71
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { CancellationToken } from '../../../base/common/cancellation.js';
7 > import { Event } from '../../../base/common/event.js';
8 > import { URI } from '../../../base/common/uri.js';
9 > import { OperatingSystem, OS } from '../../../base/common/platform.js';
10 > import { createDecorator } from '../../instantiation/common/instantiation.js';
11 > import { TerminalCapability } from '../../terminal/common/capabilities/capabilities.js';
12 >
13 > export const ITerminalSandboxService = createDecorator<ITerminalSandboxService>('terminalSandboxService');
14 >
15 > export interface ITerminalSandboxResolvedNetworkDomains {
16 > allowedDomains: string[];
17 > deniedDomains: string[];
18 > }
19 >
20 > export const enum TerminalSandboxPrerequisiteCheck {
21 > Config = 'config',
22 > Dependencies = 'dependencies',
23 > Bubblewrap = 'bubblewrap',
24 > }
25 >
26 > export const enum TerminalSandboxPreCheckRemediation {
27 > DisableUnprivilagedusernamespaceRestriction = 'disableUserNamespaceRestriction',
28 > }
29 >
30 > export interface ITerminalSandboxPrerequisiteCheckResult {
31 > enabled: boolean;
32 > sandboxConfigPath: string | undefined;
33 > failedCheck: TerminalSandboxPrerequisiteCheck | undefined;
34 > missingDependencies?: string[];
35 > canInstallMissingDependencies?: boolean;
36 > remediations?: readonly TerminalSandboxPreCheckRemediation[];
37 > detail?: string;
38 > }
39 >
40 > export interface ITerminalSandboxWrapResult {
41 > command: string;
42 > isSandboxWrapped: boolean;
43 > blockedDomains?: string[];
44 > deniedDomains?: string[];
45 > requiresUnsandboxConfirmation?: boolean;
46 > requiresAllowNetworkConfirmation?: boolean;
47 > }
48 >
49 > export type TerminalSandboxFileAccessPermission = 'read' | 'write';
50 >
51 > export interface ITerminalSandboxFileAccessCheckResult {
52 > allowed: boolean;
53 > denied: string[];
54 > }
55 >
56 > export interface ITerminalSandboxPrecheckInputs {
57 > /**
58 > * Whether the current caller is using the default approval permission flow.
59 > */
60 > readonly isDefaultApprovalPermissionEnabled?: boolean;
61 > }
62 >
63 > export interface ITerminalSandboxCommand {
64 > /**
65 > * Normalized command name without path or executable suffix.
66 > * For example, `/usr/bin/git` and `git.exe` both normalize to `git`.
67 > */
68 > keyword: string;
69 > /**
70 > * Command arguments after the executable token. These are used for
71 > * argument-sensitive sandbox allow-list rules, such as matching a specific
72 > * subcommand while ignoring global options.
73 > */
74 > args: readonly string[];
75 > }
76 >
77 > /**
78 > * Abstraction over terminal operations needed by the install flow.
79 > * Provided by the browser-layer caller so the common-layer service
80 > * does not import browser types directly.
81 > */
82 > export interface ISandboxDependencyInstallTerminal {
83 > sendText(text: string, addNewLine?: boolean): Promise<void>;
84 > focus(): void;
85 > capabilities: {
86 > get(id: TerminalCapability.CommandDetection): { onCommandFinished: Event<{ exitCode: number | undefined }> } | undefined;
87 > onDidAddCapability: Event<{ id: TerminalCapability }>;
88 > };
89 > onDidInputData: Event<string>;
90 > onDisposed: Event<unknown>;
91 > }
92 >
93 > export interface ISandboxDependencyInstallOptions {
94 > /**
95 > * Creates or obtains a terminal for running the install command.
96 > */
97 > createTerminal(): Promise<ISandboxDependencyInstallTerminal>;
98 > /**
99 > * Focuses the terminal for password entry.
100 > */
101 > focusTerminal(terminal: ISandboxDependencyInstallTerminal): Promise<void>;
102 > }
103 >
104 > export interface ISandboxDependencyInstallResult {
105 > exitCode: number | undefined;
106 > }
107 >
108 > export interface ITerminalSandboxService {
109 > readonly _serviceBrand: undefined;
110 > isEnabled(precheckInputs?: ITerminalSandboxPrecheckInputs): Promise<boolean>;
111 > isSandboxAllowNetworkEnabled(precheckInputs?: ITerminalSandboxPrecheckInputs): Promise<boolean>;
112 > getOS(): Promise<OperatingSystem>;
113 > checkForSandboxingPrereqs(forceRefresh?: boolean, precheckInputs?: ITerminalSandboxPrecheckInputs): Promise<ITerminalSandboxPrerequisiteCheckResult>;
114 > /**
115 > * Wraps a command line for sandbox execution. Command details are optional,
116 > * but when provided they are used to derive command-specific read/write
117 > * allow-list entries. When explicitly requested, `requestAllowNetwork`
118 > * retains sandbox execution while using a network-unrestricted config.
119 > */
120 > wrapCommand(command: string, requestUnsandboxedExecution?: boolean, shell?: string, cwd?: URI, commandDetails?: readonly ITerminalSandboxCommand[], requestAllowNetwork?: boolean): Promise<ITerminalSandboxWrapResult>;
121 > checkFileAccess(permission: TerminalSandboxFileAccessPermission, paths: readonly string[], precheckInputs?: ITerminalSandboxPrecheckInputs): Promise<ITerminalSandboxFileAccessCheckResult>;
122 > getSandboxConfigPath(forceRefresh?: boolean, precheckInputs?: ITerminalSandboxPrecheckInputs): Promise<string | undefined>;
123 > getTempDir(): URI | undefined;
124 > setNeedsForceUpdateConfigFile(): void;
125 > getResolvedNetworkDomains(): ITerminalSandboxResolvedNetworkDomains;
126 > getMissingSandboxDependencies(): Promise<string[]>;
127 > installMissingSandboxDependencies(missingDependencies: string[], sessionResource: URI | undefined, token: CancellationToken, options: ISandboxDependencyInstallOptions): Promise<ISandboxDependencyInstallResult>;
128 > runSandboxRemediation(remediation: TerminalSandboxPreCheckRemediation, sessionResource: URI | undefined, token: CancellationToken, options: ISandboxDependencyInstallOptions): Promise<ISandboxDependencyInstallResult>;
129 > }
130 >
131 > export class NullTerminalSandboxService implements ITerminalSandboxService {
132 > readonly _serviceBrand: undefined;
133 >
134 > async isEnabled(): Promise<boolean> {
135 return false;
136 }
138 > async isSandboxAllowNetworkEnabled(): Promise<boolean> {
139 return false;
140 }
142 > async getOS(): Promise<OperatingSystem> {
143 return OS;
144 }
146 > async checkForSandboxingPrereqs(): Promise<ITerminalSandboxPrerequisiteCheckResult> {
147 return { enabled: false, sandboxConfigPath: undefined, failedCheck: undefined };
148 }
150 > async wrapCommand(command: string): Promise<ITerminalSandboxWrapResult> {
151 return { command, isSandboxWrapped: false };
152 }
154 > async checkFileAccess(): Promise<ITerminalSandboxFileAccessCheckResult> {
155 return { allowed: true, denied: [] };
156 }
158 > async getSandboxConfigPath(): Promise<string | undefined> {
159 return undefined;
160 }
162 > getTempDir(): URI | undefined {
163 return undefined;
164 }
166 > setNeedsForceUpdateConfigFile(): void {
167 // No-op.
168 }
170 > getResolvedNetworkDomains(): ITerminalSandboxResolvedNetworkDomains {
171 return { allowedDomains: [], deniedDomains: [] };
172 }
174 > async getMissingSandboxDependencies(): Promise<string[]> {
175 return [];
176 }
178 > async installMissingSandboxDependencies(): Promise<ISandboxDependencyInstallResult> {
179 return { exitCode: undefined };
180 }
182 > async runSandboxRemediation(): Promise<ISandboxDependencyInstallResult> {
183 return { exitCode: undefined };
184 }