Skip to content

Commit

Permalink
Load local certificates (microsoft/vscode-remote-release#9176)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrmarti committed Nov 13, 2023
1 parent e889f69 commit 9c2b932
Show file tree
Hide file tree
Showing 18 changed files with 66 additions and 31 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"@parcel/watcher": "2.1.0",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/policy-watcher": "^1.1.4",
"@vscode/proxy-agent": "^0.17.5",
"@vscode/proxy-agent": "^0.18.0",
"@vscode/ripgrep": "^1.15.6",
"@vscode/spdlog": "^0.13.12",
"@vscode/sqlite3": "5.1.6-vscode",
Expand Down
2 changes: 1 addition & 1 deletion remote/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"@microsoft/1ds-post-js": "^3.2.13",
"@parcel/watcher": "2.1.0",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/proxy-agent": "^0.17.5",
"@vscode/proxy-agent": "^0.18.0",
"@vscode/ripgrep": "^1.15.6",
"@vscode/spdlog": "^0.13.12",
"@vscode/vscode-languagedetection": "1.0.21",
Expand Down
8 changes: 4 additions & 4 deletions remote/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@
resolved "https://registry.yarnpkg.com/@vscode/iconv-lite-umd/-/iconv-lite-umd-0.7.0.tgz#d2f1e0664ee6036408f9743fee264ea0699b0e48"
integrity sha512-bRRFxLfg5dtAyl5XyiVWz/ZBPahpOpPrNYnnHpOpUZvam4tKH35wdhP4Kj6PbM0+KdliOsPzbGWpkxcdpNB/sg==

"@vscode/proxy-agent@^0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.17.5.tgz#a59f6087a39795425b2601c9ee95bcb0338154e6"
integrity sha512-plKfR1i9ce09aro1/yvK3Ckiu84Cj5ViuLqJ/7VRT6E9w5xP2YUPcgrCy+u7FGorKZmJb+wQ1L6f/cdJ7axulw==
"@vscode/proxy-agent@^0.18.0":
version "0.18.0"
resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.18.0.tgz#08c1adc4707844788738e87814a425c1f553d695"
integrity sha512-lOBA4Ns6PqJtX6LCUpKiwxkx3uhPoOdChtSSvO0hujON1sPBdSjyAwECoEWlUAk8FTJ3040ClPoLsDn9gUw2lw==
dependencies:
"@tootallnate/once" "^3.0.0"
agent-base "^7.0.1"
Expand Down
1 change: 1 addition & 0 deletions src/vs/platform/native/common/native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export interface ICommonNativeHostService {

// Connectivity
resolveProxy(url: string): Promise<string | undefined>;
loadCertificates(): Promise<string[]>;
findFreePort(startPort: number, giveUpAfter: number, timeout: number, stride?: number): Promise<number>;

// Registry (windows only)
Expand Down
5 changes: 5 additions & 0 deletions src/vs/platform/native/electron-main/nativeHostMainService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { WindowProfiler } from 'vs/platform/profiling/electron-main/windowProfil
import { IV8Profile } from 'vs/platform/profiling/common/profiling';
import { IAuxiliaryWindowsMainService, isAuxiliaryWindow } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindows';
import { IAuxiliaryWindow } from 'vs/platform/auxiliaryWindow/electron-main/auxiliaryWindow';
import { loadSystemCertificates } from '@vscode/proxy-agent';

export interface INativeHostMainService extends AddFirstParameterToFunctions<ICommonNativeHostService, Promise<unknown> /* only methods, not events */, number | undefined /* window ID */> { }

Expand Down Expand Up @@ -756,6 +757,10 @@ export class NativeHostMainService extends Disposable implements INativeHostMain
return session?.resolveProxy(url);
}

async loadCertificates(_windowId: number | undefined): Promise<string[]> {
return loadSystemCertificates({ log: this.logService });
}

findFreePort(windowId: number | undefined, startPort: number, giveUpAfter: number, timeout: number, stride = 1): Promise<number> {
return findFreePort(startPort, giveUpAfter, timeout, stride);
}
Expand Down
4 changes: 4 additions & 0 deletions src/vs/platform/request/browser/requestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@ export class RequestService extends AbstractRequestService implements IRequestSe
async resolveProxy(url: string): Promise<string | undefined> {
return undefined; // not implemented in the web
}

async loadCertificates(): Promise<string[]> {
return []; // not implemented in the web
}
}
2 changes: 2 additions & 0 deletions src/vs/platform/request/common/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export interface IRequestService {
request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext>;

resolveProxy(url: string): Promise<string | undefined>;
loadCertificates(): Promise<string[]>;
}

class LoggableHeaders {
Expand Down Expand Up @@ -79,6 +80,7 @@ export abstract class AbstractRequestService extends Disposable implements IRequ

abstract request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext>;
abstract resolveProxy(url: string): Promise<string | undefined>;
abstract loadCertificates(): Promise<string[]>;
}

export function isSuccess(context: IRequestContext): boolean {
Expand Down
4 changes: 4 additions & 0 deletions src/vs/platform/request/common/requestIpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class RequestChannel implements IServerChannel {
return <RequestResponse>[{ statusCode: res.statusCode, headers: res.headers }, buffer];
});
case 'resolveProxy': return this.service.resolveProxy(args[0]);
case 'loadCertificates': return this.service.loadCertificates();
}
throw new Error('Invalid call');
}
Expand All @@ -54,4 +55,7 @@ export class RequestChannelClient implements IRequestService {
return this.channel.call<string | undefined>('resolveProxy', [url]);
}

async loadCertificates(): Promise<string[]> {
return this.channel.call<string[]>('loadCertificates');
}
}
5 changes: 5 additions & 0 deletions src/vs/platform/request/node/requestService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ILogService, ILoggerService } from 'vs/platform/log/common/log';
import { AbstractRequestService, IRequestService } from 'vs/platform/request/common/request';
import { Agent, getProxyAgent } from 'vs/platform/request/node/proxy';
import { createGunzip } from 'zlib';
import { loadSystemCertificates } from '@vscode/proxy-agent';

interface IHTTPConfiguration {
proxy?: string;
Expand Down Expand Up @@ -109,6 +110,10 @@ export class RequestService extends AbstractRequestService implements IRequestSe
async resolveProxy(url: string): Promise<string | undefined> {
return undefined; // currently not implemented in node
}

async loadCertificates(): Promise<string[]> {
return loadSystemCertificates({ log: this.logService });
}
}

async function getNodeRequest(options: IRequestOptions): Promise<IRawRequestFunction> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ export class UserDataSyncTestServer implements IRequestService {
constructor(private readonly rateLimit = Number.MAX_SAFE_INTEGER, private readonly retryAfter?: number) { }

async resolveProxy(url: string): Promise<string | undefined> { return url; }
async loadCertificates(): Promise<string[]> { return []; }

async request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
if (this._requests.length === this.rateLimit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ suite('UserDataSyncRequestsSession', () => {
const requestService: IRequestService = {
_serviceBrand: undefined,
async request() { return { res: { headers: {} }, stream: newWriteableBufferStream() }; },
async resolveProxy() { return undefined; }
async resolveProxy() { return undefined; },
async loadCertificates() { return []; }
};

test('too many requests are thrown when limit exceeded', async () => {
Expand Down
4 changes: 4 additions & 0 deletions src/vs/workbench/api/browser/mainThreadWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ export class MainThreadWorkspace implements MainThreadWorkspaceShape {
return this._requestService.resolveProxy(url);
}

$loadCertificates(): Promise<string[]> {
return this._requestService.loadCertificates();
}

// --- trust ---

$requestWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<boolean | undefined> {
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,7 @@ export interface MainThreadWorkspaceShape extends IDisposable {
$saveAll(includeUntitled?: boolean): Promise<boolean>;
$updateWorkspaceFolders(extensionName: string, index: number, deleteCount: number, workspaceFoldersToAdd: { uri: UriComponents; name?: string }[]): Promise<void>;
$resolveProxy(url: string): Promise<string | undefined>;
$loadCertificates(): Promise<string[]>;
$requestWorkspaceTrust(options?: WorkspaceTrustRequestOptions): Promise<boolean | undefined>;
$registerEditSessionIdentityProvider(handle: number, scheme: string): void;
$unregisterEditSessionIdentityProvider(handle: number): void;
Expand Down
5 changes: 5 additions & 0 deletions src/vs/workbench/api/common/extHostWorkspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export interface IExtHostWorkspaceProvider {
resolveWorkspaceFolder(uri: vscode.Uri): Promise<vscode.WorkspaceFolder | undefined>;
getWorkspaceFolders2(): Promise<vscode.WorkspaceFolder[] | undefined>;
resolveProxy(url: string): Promise<string | undefined>;
loadCertificates(): Promise<string[]>;
}

function isFolderEqual(folderA: URI, folderB: URI, extHostFileSystemInfo: IExtHostFileSystemInfo): boolean {
Expand Down Expand Up @@ -578,6 +579,10 @@ export class ExtHostWorkspace implements ExtHostWorkspaceShape, IExtHostWorkspac
return this._proxy.$resolveProxy(url);
}

loadCertificates(): Promise<string[]> {
return this._proxy.$loadCertificates();
}

// --- trust ---

get trusted(): boolean {
Expand Down
37 changes: 17 additions & 20 deletions src/vs/workbench/api/node/proxyResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionS
import { URI } from 'vs/base/common/uri';
import { ILogService, LogLevel as LogServiceLevel } from 'vs/platform/log/common/log';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { LogLevel, createHttpPatch, createProxyResolver, createTlsPatch, ProxySupportSetting, ProxyAgentParams, createNetPatch } from '@vscode/proxy-agent';
import { LogLevel, createHttpPatch, createProxyResolver, createTlsPatch, ProxySupportSetting, ProxyAgentParams, createNetPatch, loadSystemCertificates } from '@vscode/proxy-agent';

const systemCertificatesV2Default = false;

Expand All @@ -35,24 +35,9 @@ export function connectProxyResolver(
lookupProxyAuthorization: lookupProxyAuthorization.bind(undefined, extHostLogService, mainThreadTelemetry, configProvider, {}, initData.remote.isRemote),
getProxyURL: () => configProvider.getConfiguration('http').get('proxy'),
getProxySupport: () => configProvider.getConfiguration('http').get<ProxySupportSetting>('proxySupport') || 'off',
getSystemCertificatesV1: () => certSettingV1(configProvider),
getSystemCertificatesV2: () => certSettingV2(configProvider),
log: (level, message, ...args) => {
switch (level) {
case LogLevel.Trace: extHostLogService.trace(message, ...args); break;
case LogLevel.Debug: extHostLogService.debug(message, ...args); break;
case LogLevel.Info: extHostLogService.info(message, ...args); break;
case LogLevel.Warning: extHostLogService.warn(message, ...args); break;
case LogLevel.Error: extHostLogService.error(message, ...args); break;
case LogLevel.Critical: extHostLogService.error(message, ...args); break;
case LogLevel.Off: break;
default: never(level, message, args); break;
}
function never(level: never, message: string, ...args: any[]) {
extHostLogService.error('Unknown log level', level);
extHostLogService.error(message, ...args);
}
},
addCertificatesV1: () => certSettingV1(configProvider),
addCertificatesV2: () => certSettingV2(configProvider),
log: extHostLogService,
getLogLevel: () => {
const level = extHostLogService.getLevel();
switch (level) {
Expand All @@ -71,7 +56,19 @@ export function connectProxyResolver(
},
proxyResolveTelemetry: () => { },
useHostProxy: doUseHostProxy,
addCertificates: [],
loadAdditionalCertificates: async () => {
const promises: Promise<string[]>[] = [];
if (initData.remote.isRemote) {
promises.push(loadSystemCertificates({ log: extHostLogService }));
}
if (doUseHostProxy) {
extHostLogService.trace('ProxyResolver#loadAdditionalCertificates: Loading certificates from main process');
const certs = extHostWorkspace.loadCertificates(); // Loading from main process to share cache.
certs.then(certs => extHostLogService.trace('ProxyResolver#loadAdditionalCertificates: Loaded certificates from main process', certs.length));
promises.push(certs);
}
return (await Promise.all(promises)).flat();
},
env: process.env,
};
const resolveProxy = createProxyResolver(params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export class NativeRequestService extends RequestService {
override async resolveProxy(url: string): Promise<string | undefined> {
return this.nativeHostService.resolveProxy(url);
}

override async loadCertificates(): Promise<string[]> {
return this.nativeHostService.loadCertificates();
}
}

registerSingleton(IRequestService, NativeRequestService, InstantiationType.Delayed);
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export class TestNativeHostService implements INativeHostService {
async openDevTools(options?: Electron.OpenDevToolsOptions | undefined): Promise<void> { }
async toggleDevTools(): Promise<void> { }
async resolveProxy(url: string): Promise<string | undefined> { return undefined; }
async loadCertificates(): Promise<string[]> { return []; }
async findFreePort(startPort: number, giveUpAfter: number, timeout: number, stride?: number): Promise<number> { return -1; }
async readClipboardText(type?: 'selection' | 'clipboard' | undefined): Promise<string> { return ''; }
async writeClipboardText(text: string, type?: 'selection' | 'clipboard' | undefined): Promise<void> { }
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1392,10 +1392,10 @@
bindings "^1.5.0"
node-addon-api "^6.0.0"

"@vscode/proxy-agent@^0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.17.5.tgz#a59f6087a39795425b2601c9ee95bcb0338154e6"
integrity sha512-plKfR1i9ce09aro1/yvK3Ckiu84Cj5ViuLqJ/7VRT6E9w5xP2YUPcgrCy+u7FGorKZmJb+wQ1L6f/cdJ7axulw==
"@vscode/proxy-agent@^0.18.0":
version "0.18.0"
resolved "https://registry.yarnpkg.com/@vscode/proxy-agent/-/proxy-agent-0.18.0.tgz#08c1adc4707844788738e87814a425c1f553d695"
integrity sha512-lOBA4Ns6PqJtX6LCUpKiwxkx3uhPoOdChtSSvO0hujON1sPBdSjyAwECoEWlUAk8FTJ3040ClPoLsDn9gUw2lw==
dependencies:
"@tootallnate/once" "^3.0.0"
agent-base "^7.0.1"
Expand Down

0 comments on commit 9c2b932

Please sign in to comment.