mirror of
https://github.com/coder/code-server.git
synced 2026-06-23 02:17:11 +02:00
Update to VS Code 1.52.1
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as crypto from 'crypto';
|
||||
import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
export class ExtensionUrlTrustService implements IExtensionUrlTrustService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private trustedExtensionUrlPublicKeys = new Map<string, (crypto.KeyObject | string | null)[]>();
|
||||
|
||||
constructor(
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@ILogService private readonly logService: ILogService
|
||||
) { }
|
||||
|
||||
async isExtensionUrlTrusted(extensionId: string, url: string): Promise<boolean> {
|
||||
if (!this.productService.trustedExtensionUrlPublicKeys) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'There are no configured trusted keys');
|
||||
return false;
|
||||
}
|
||||
|
||||
const match = /^(.*)#([^#]+)$/.exec(url);
|
||||
|
||||
if (!match) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Uri has no fragment', url);
|
||||
return false;
|
||||
}
|
||||
|
||||
const [, originalUrl, fragment] = match;
|
||||
|
||||
let keys = this.trustedExtensionUrlPublicKeys.get(extensionId);
|
||||
|
||||
if (!keys) {
|
||||
keys = this.productService.trustedExtensionUrlPublicKeys[extensionId];
|
||||
|
||||
if (!keys || keys.length === 0) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Extension doesn\'t have any trusted keys', extensionId);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.trustedExtensionUrlPublicKeys.set(extensionId, [...keys]);
|
||||
}
|
||||
|
||||
const fragmentBuffer = Buffer.from(decodeURIComponent(fragment), 'base64');
|
||||
|
||||
if (fragmentBuffer.length <= 6) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Uri fragment is not a signature', url);
|
||||
return false;
|
||||
}
|
||||
|
||||
const timestampBuffer = fragmentBuffer.slice(0, 6);
|
||||
const timestamp = fragmentBuffer.readUIntBE(0, 6);
|
||||
const diff = Date.now() - timestamp;
|
||||
|
||||
if (diff < 0 || diff > 3_600_000) { // 1 hour
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Signed uri has expired', url);
|
||||
return false;
|
||||
}
|
||||
|
||||
const signatureBuffer = fragmentBuffer.slice(6);
|
||||
const verify = crypto.createVerify('SHA256');
|
||||
verify.write(timestampBuffer);
|
||||
verify.write(Buffer.from(originalUrl));
|
||||
verify.end();
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let key = keys[i];
|
||||
|
||||
if (key === null) { // failed to be parsed before
|
||||
continue;
|
||||
} else if (typeof key === 'string') { // needs to be parsed
|
||||
try {
|
||||
key = crypto.createPublicKey({ key: Buffer.from(key, 'base64'), format: 'der', type: 'spki' });
|
||||
keys[i] = key;
|
||||
} catch (err) {
|
||||
this.logService.warn('ExtensionUrlTrustService#isExtensionUrlTrusted', `Failed to parse trusted extension uri public key #${i + 1} for ${extensionId}:`, err);
|
||||
keys[i] = null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (verify.verify(key, signatureBuffer)) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Signed uri is valid', url);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Signed uri could not be verified', url);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user