From edfe5d03bb6a33e3ab941fade9eb4f3cdeae1815 Mon Sep 17 00:00:00 2001 From: Tyler Leonhardt Date: Wed, 12 Jan 2022 12:54:21 -0800 Subject: [PATCH] delegate encryption and credentials to server if we have a remote --- src/vs/base/parts/ipc/common/ipc.ts | 2 +- src/vs/code/browser/workbench/workbench.ts | 3 ++- src/vs/code/electron-main/app.ts | 2 +- src/vs/code/electron-main/auth.ts | 2 +- .../encryptionMainService.ts | 0 .../server/remoteExtensionHostAgentServer.ts | 20 +++++++++++++++++-- src/vs/workbench/browser/web.main.ts | 6 +++++- .../encryption/browser/encryptionService.ts | 18 ++++++++++++++++- 8 files changed, 45 insertions(+), 8 deletions(-) rename src/vs/platform/encryption/{electron-main => node}/encryptionMainService.ts (100%) diff --git a/src/vs/base/parts/ipc/common/ipc.ts b/src/vs/base/parts/ipc/common/ipc.ts index 601baa8e2c0..4d6b5e2df0e 100644 --- a/src/vs/base/parts/ipc/common/ipc.ts +++ b/src/vs/base/parts/ipc/common/ipc.ts @@ -1056,7 +1056,7 @@ export namespace ProxyChannel { export interface ICreateServiceChannelOptions extends IProxyOptions { } - export function fromService(service: unknown, options?: ICreateServiceChannelOptions): IServerChannel { + export function fromService(service: unknown, options?: ICreateServiceChannelOptions): IServerChannel { const handler = service as { [key: string]: unknown }; const disableMarshalling = options && options.disableMarshalling; diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts index 3086cd1b0dd..ec954fdf319 100644 --- a/src/vs/code/browser/workbench/workbench.ts +++ b/src/vs/code/browser/workbench/workbench.ts @@ -462,6 +462,7 @@ function doCreateUri(path: string, queryValues: Map): URI { } : undefined, workspaceProvider: WorkspaceProvider.create(config), urlCallbackProvider: new LocalStorageURLCallbackProvider(), - credentialsProvider: new LocalStorageCredentialsProvider() + // if we have a remote authority, we will use the remote side for storing secrets + credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider() }); })(); diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 7d5206d7500..73231eb026e 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -36,7 +36,7 @@ import { ElectronExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/el import { IDiagnosticsService } from 'vs/platform/diagnostics/common/diagnostics'; import { DialogMainService, IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogMainService'; import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; -import { EncryptionMainService, IEncryptionMainService } from 'vs/platform/encryption/electron-main/encryptionMainService'; +import { EncryptionMainService, IEncryptionMainService } from 'vs/platform/encryption/node/encryptionMainService'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService'; import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper'; diff --git a/src/vs/code/electron-main/auth.ts b/src/vs/code/electron-main/auth.ts index 8a4dddfed33..9fdb8fbe25d 100644 --- a/src/vs/code/electron-main/auth.ts +++ b/src/vs/code/electron-main/auth.ts @@ -9,7 +9,7 @@ import { Event } from 'vs/base/common/event'; import { hash } from 'vs/base/common/hash'; import { Disposable } from 'vs/base/common/lifecycle'; import { generateUuid } from 'vs/base/common/uuid'; -import { IEncryptionMainService } from 'vs/platform/encryption/electron-main/encryptionMainService'; +import { IEncryptionMainService } from 'vs/platform/encryption/node/encryptionMainService'; import { ILogService } from 'vs/platform/log/common/log'; import { IProductService } from 'vs/platform/product/common/productService'; import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows'; diff --git a/src/vs/platform/encryption/electron-main/encryptionMainService.ts b/src/vs/platform/encryption/node/encryptionMainService.ts similarity index 100% rename from src/vs/platform/encryption/electron-main/encryptionMainService.ts rename to src/vs/platform/encryption/node/encryptionMainService.ts diff --git a/src/vs/server/remoteExtensionHostAgentServer.ts b/src/vs/server/remoteExtensionHostAgentServer.ts index 21f1f71bdea..3e0d350e543 100644 --- a/src/vs/server/remoteExtensionHostAgentServer.ts +++ b/src/vs/server/remoteExtensionHostAgentServer.ts @@ -52,7 +52,7 @@ import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemPro import { IFileService } from 'vs/platform/files/common/files'; import { IProductService } from 'vs/platform/product/common/productService'; import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment'; -import { IPCServer, ClientConnectionEvent, IMessagePassingProtocol, StaticRouter } from 'vs/base/parts/ipc/common/ipc'; +import { IPCServer, ClientConnectionEvent, IMessagePassingProtocol, StaticRouter, ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; import { Emitter, Event } from 'vs/base/common/event'; import { RemoteAgentEnvironmentChannel } from 'vs/server/remoteAgentEnvironmentImpl'; import { RemoteAgentFileSystemProviderChannel } from 'vs/server/remoteFileSystemProviderServer'; @@ -79,6 +79,10 @@ import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService'; import { IRemoteTelemetryService, RemoteNullTelemetryService, RemoteTelemetryService } from 'vs/server/remoteTelemetryService'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; +import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; +import { CredentialsMainService } from 'vs/platform/credentials/node/credentialsMainService'; +import { IEncryptionService } from 'vs/workbench/services/encryption/common/encryptionService'; +import { EncryptionMainService } from 'vs/platform/encryption/node/encryptionMainService'; const SHUTDOWN_TIMEOUT = 5 * 60 * 1000; @@ -288,13 +292,13 @@ export class RemoteExtensionHostAgentServer extends Disposable { services.set(IRequestService, new SyncDescriptor(RequestService)); let appInsightsAppender: ITelemetryAppender = NullAppender; + const machineId = await getMachineId(); if (supportsTelemetry(this._productService, this._environmentService)) { if (this._productService.aiConfig && this._productService.aiConfig.asimovKey) { appInsightsAppender = new AppInsightsAppender(eventPrefix, null, this._productService.aiConfig.asimovKey); this._register(toDisposable(() => appInsightsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data } - const machineId = await getMachineId(); const config: ITelemetryServiceConfig = { appenders: [appInsightsAppender], commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, this._productService.commit, this._productService.version + '-remote', machineId, this._productService.msftInternalDomains, this._environmentService.installSourcePath, 'remoteAgent'), @@ -329,6 +333,12 @@ export class RemoteExtensionHostAgentServer extends Disposable { ); services.set(IPtyService, ptyService); + const encryptionService = instantiationService.createInstance(EncryptionMainService, machineId); + services.set(IEncryptionService, encryptionService); + + const credentialsService = instantiationService.createInstance(CredentialsMainService); + services.set(ICredentialsService, credentialsService); + return instantiationService.invokeFunction(accessor => { const remoteExtensionEnvironmentChannel = new RemoteAgentEnvironmentChannel(this._connectionToken, this._environmentService, extensionManagementCLIService, this._logService, accessor.get(IRemoteTelemetryService), appInsightsAppender, this._productService); this._socketServer.registerChannel('remoteextensionsenvironment', remoteExtensionEnvironmentChannel); @@ -344,6 +354,12 @@ export class RemoteExtensionHostAgentServer extends Disposable { const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => this._getUriTransformer(ctx.remoteAuthority)); this._socketServer.registerChannel('extensions', channel); + const encryptionChannel = ProxyChannel.fromService(accessor.get(IEncryptionService)); + this._socketServer.registerChannel('encryption', encryptionChannel); + + const credentialsChannel = ProxyChannel.fromService(accessor.get(ICredentialsService)); + this._socketServer.registerChannel('credentials', credentialsChannel); + // clean up deprecated extensions (extensionManagementService as ExtensionManagementService).removeDeprecatedExtensions(); diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index e361eb6ee71..5180434eba9 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -68,6 +68,7 @@ import { mixin, safeStringify } from 'vs/base/common/objects'; import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; import { IndexedDB } from 'vs/base/browser/indexedDB'; import { BrowserCredentialsService } from 'vs/workbench/services/credentials/browser/credentialsService'; +import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; class BrowserMain extends Disposable { @@ -268,7 +269,10 @@ class BrowserMain extends Disposable { // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // Credentials Service - const credentialsService = new BrowserCredentialsService(environmentService); + const credentialsService = environmentService.remoteAuthority + // If we have a remote authority, we can use the CredentialsService on the remote side + ? ProxyChannel.toService(remoteAgentService.getConnection()!.getChannel('credentials')) + : new BrowserCredentialsService(environmentService); serviceCollection.set(ICredentialsService, credentialsService); // Userdata Initialize Service diff --git a/src/vs/workbench/services/encryption/browser/encryptionService.ts b/src/vs/workbench/services/encryption/browser/encryptionService.ts index bac7ca6afe8..6d48fa6a807 100644 --- a/src/vs/workbench/services/encryption/browser/encryptionService.ts +++ b/src/vs/workbench/services/encryption/browser/encryptionService.ts @@ -3,13 +3,29 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { ILogService } from 'vs/platform/log/common/log'; import { IEncryptionService } from 'vs/workbench/services/encryption/common/encryptionService'; +import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; -export class EncryptionService { +export class EncryptionService implements IEncryptionService { declare readonly _serviceBrand: undefined; + constructor( + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + @IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService, + @ILogService logService: ILogService + ) { + // This allows the remote side to handle any encryption requests + if (environmentService.remoteAuthority) { + logService.trace('EncryptionService#constructor - Detected remote environment, registering proxy for encryption instead'); + return ProxyChannel.toService(remoteAgentService.getConnection()!.getChannel('encryption')); + } + } + encrypt(value: string): Promise { return Promise.resolve(value); }