Allow a resolver to provide the remote connection token

This commit is contained in:
Alex Dima 2020-10-29 21:28:04 +01:00
parent 40cf6489c9
commit 7b40975fd7
No known key found for this signature in database
GPG key ID: 6E58D7B045760DA0
12 changed files with 37 additions and 16 deletions

View file

@ -195,7 +195,7 @@ export function activate(context: vscode.ExtensionContext) {
proxyServer.listen(0, () => {
const port = (<net.AddressInfo>proxyServer.address()).port;
outputChannel.appendLine(`Going through proxy at port ${port}`);
res({ host: '127.0.0.1', port });
res(new vscode.ResolvedAuthority('127.0.0.1', port));
});
context.subscriptions.push({
dispose: () => {

View file

@ -17,11 +17,13 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot
public readonly onDidChangeConnectionData = this._onDidChangeConnectionData.event;
private readonly _cache: Map<string, ResolverResult>;
private readonly _connectionToken: string | undefined;
private readonly _connectionTokens: Map<string, string>;
constructor(resourceUriProvider: ((uri: URI) => URI) | undefined) {
constructor(connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined) {
super();
this._cache = new Map<string, ResolverResult>();
this._connectionToken = connectionToken;
this._connectionTokens = new Map<string, string>();
if (resourceUriProvider) {
RemoteAuthorities.setDelegate(resourceUriProvider);
@ -43,7 +45,7 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot
return null;
}
const resolverResult = this._cache.get(authority)!;
const connectionToken = this._connectionTokens.get(authority);
const connectionToken = this._connectionTokens.get(authority) || this._connectionToken;
return {
host: resolverResult.authority.host,
port: resolverResult.authority.port,
@ -52,11 +54,12 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot
}
private _doResolveAuthority(authority: string): ResolverResult {
const connectionToken = this._connectionTokens.get(authority) || this._connectionToken;
if (authority.indexOf(':') >= 0) {
const pieces = authority.split(':');
return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10) } };
return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10), connectionToken } };
}
return { authority: { authority, host: authority, port: 80 } };
return { authority: { authority, host: authority, port: 80, connectionToken } };
}
_clearResolvedAuthority(authority: string): void {

View file

@ -70,6 +70,7 @@ interface ISimpleConnectionOptions {
commit: string | undefined;
host: string;
port: number;
connectionToken: string | undefined;
reconnectionToken: string;
reconnectionProtocol: PersistentProtocol | null;
socketFactory: ISocketFactory;
@ -169,10 +170,9 @@ async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptio
});
options.logService.trace(`${logPrefix} 3/6. sending AuthRequest control message.`);
// TODO@vs-remote: use real nonce here
const authRequest: AuthRequest = {
type: 'auth',
auth: '00000000000000000000'
auth: options.connectionToken || '00000000000000000000'
};
protocol.sendControl(VSBuffer.fromString(JSON.stringify(authRequest)));
});
@ -254,11 +254,12 @@ export interface IConnectionOptions {
}
async function resolveConnectionOptions(options: IConnectionOptions, reconnectionToken: string, reconnectionProtocol: PersistentProtocol | null): Promise<ISimpleConnectionOptions> {
const { host, port } = await options.addressProvider.getAddress();
const { host, port, connectionToken } = await options.addressProvider.getAddress();
return {
commit: options.commit,
host: host,
port: port,
connectionToken: connectionToken,
reconnectionToken: reconnectionToken,
reconnectionProtocol: reconnectionProtocol,
socketFactory: options.socketFactory,
@ -270,6 +271,7 @@ async function resolveConnectionOptions(options: IConnectionOptions, reconnectio
export interface IAddress {
host: string;
port: number;
connectionToken: string | undefined;
}
export interface IAddressProvider {

View file

@ -12,6 +12,7 @@ export interface ResolvedAuthority {
readonly authority: string;
readonly host: string;
readonly port: number;
readonly connectionToken: string | undefined;
}
export interface ResolvedOptions {

View file

@ -87,6 +87,9 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot
if (this._resolveAuthorityRequests.has(resolvedAuthority.authority)) {
const request = this._resolveAuthorityRequests.get(resolvedAuthority.authority)!;
RemoteAuthorities.set(resolvedAuthority.authority, resolvedAuthority.host, resolvedAuthority.port);
if (resolvedAuthority.connectionToken) {
RemoteAuthorities.setConnectionToken(resolvedAuthority.authority, resolvedAuthority.connectionToken);
}
request.resolve({ authority: resolvedAuthority, options });
this._onDidChangeConnectionData.fire();
}

View file

@ -181,8 +181,9 @@ declare module 'vscode' {
export class ResolvedAuthority {
readonly host: string;
readonly port: number;
readonly connectionToken: string | undefined;
constructor(host: string, port: number);
constructor(host: string, port: number, connectionToken?: string);
}
export interface ResolvedOptions {

View file

@ -651,7 +651,8 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
const authority: ResolvedAuthority = {
authority: remoteAuthority,
host: result.host,
port: result.port
port: result.port,
connectionToken: result.connectionToken
};
const options: ResolvedOptions = {
extensionHostEnv: result.extensionHostEnv

View file

@ -433,16 +433,23 @@ export class Selection extends Range {
export class ResolvedAuthority {
readonly host: string;
readonly port: number;
readonly connectionToken: string | undefined;
constructor(host: string, port: number) {
constructor(host: string, port: number, connectionToken?: string) {
if (typeof host !== 'string' || host.length === 0) {
throw illegalArgument('host');
}
if (typeof port !== 'number' || port === 0 || Math.round(port) !== port) {
throw illegalArgument('port');
}
if (typeof connectionToken !== 'undefined') {
if (typeof connectionToken !== 'string' || connectionToken.length === 0 || !/^[0-9A-Za-z\-]+$/.test(connectionToken)) {
throw illegalArgument('connectionToken');
}
}
this.host = host;
this.port = Math.round(port);
this.connectionToken = connectionToken;
}
}

View file

@ -179,12 +179,14 @@ class BrowserMain extends Disposable {
const logService = new BufferLogService(getLogLevel(environmentService));
serviceCollection.set(ILogService, logService);
const connectionToken = environmentService.options.connectionToken || this.getCookieValue('vscode-tkn');
// Remote
const remoteAuthorityResolverService = new RemoteAuthorityResolverService(this.configuration.resourceUriProvider);
const remoteAuthorityResolverService = new RemoteAuthorityResolverService(connectionToken, this.configuration.resourceUriProvider);
serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService);
// Signing
const signService = new SignService(environmentService.options.connectionToken || this.getCookieValue('vscode-tkn'));
const signService = new SignService(connectionToken);
serviceCollection.set(ISignService, signService);
// Remote Agent

View file

@ -265,7 +265,8 @@ export class ExtensionHostManager extends Disposable {
authority: {
authority: remoteAuthority,
host: pieces[0],
port: parseInt(pieces[1], 10)
port: parseInt(pieces[1], 10),
connectionToken: undefined
}
});
}

View file

@ -92,7 +92,7 @@ export class RemoteExtensionHost extends Disposable implements IExtensionHost {
addressProvider: {
getAddress: async () => {
const { authority } = await this.remoteAuthorityResolverService.resolveAuthority(this._initDataProvider.remoteAuthority);
return { host: authority.host, port: authority.port };
return { host: authority.host, port: authority.port, connectionToken: authority.connectionToken };
}
},
signService: this._signService,

View file

@ -183,7 +183,7 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon
this._onReconnecting.fire(undefined);
}
const { authority } = await this._remoteAuthorityResolverService.resolveAuthority(this.remoteAuthority);
return { host: authority.host, port: authority.port };
return { host: authority.host, port: authority.port, connectionToken: authority.connectionToken };
}
},
signService: this._signService,