1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-28 12:45:45 +01:00

Add support for multiple concurrent extensions with native messaging

This commit is contained in:
Hinton 2020-12-16 15:47:30 +01:00
parent 3f34bc52fa
commit c4185fe6ee
2 changed files with 24 additions and 5 deletions

View File

@ -248,7 +248,7 @@ export default class MainBackground {
this.analytics, this.notificationsService, this.systemService, this.vaultTimeoutService, this.analytics, this.notificationsService, this.systemService, this.vaultTimeoutService,
this.environmentService, this.policyService, this.userService); this.environmentService, this.policyService, this.userService);
this.nativeMessagingBackground = new NativeMessagingBackground(this.storageService, this.cryptoService, this.cryptoFunctionService, this.nativeMessagingBackground = new NativeMessagingBackground(this.storageService, this.cryptoService, this.cryptoFunctionService,
this.vaultTimeoutService, this.runtimeBackground, this.i18nService, this.userService, this.messagingService); this.vaultTimeoutService, this.runtimeBackground, this.i18nService, this.userService, this.messagingService, this.appIdService);
this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService, this.commandsBackground = new CommandsBackground(this, this.passwordGenerationService,
this.platformUtilsService, this.analytics, this.vaultTimeoutService); this.platformUtilsService, this.analytics, this.vaultTimeoutService);

View File

@ -12,6 +12,7 @@ import { SymmetricCryptoKey } from 'jslib/models/domain';
import { BrowserApi } from '../browser/browserApi'; import { BrowserApi } from '../browser/browserApi';
import RuntimeBackground from './runtime.background'; import RuntimeBackground from './runtime.background';
import { AppIdService } from 'jslib/abstractions';
const MessageValidTimeout = 10 * 1000; const MessageValidTimeout = 10 * 1000;
const EncryptionAlgorithm = 'sha1'; const EncryptionAlgorithm = 'sha1';
@ -25,13 +26,16 @@ export class NativeMessagingBackground {
private privateKey: ArrayBuffer = null; private privateKey: ArrayBuffer = null;
private secureSetupResolve: any = null; private secureSetupResolve: any = null;
private sharedSecret: SymmetricCryptoKey; private sharedSecret: SymmetricCryptoKey;
private appId: string;
constructor(private storageService: StorageService, private cryptoService: CryptoService, constructor(private storageService: StorageService, private cryptoService: CryptoService,
private cryptoFunctionService: CryptoFunctionService, private vaultTimeoutService: VaultTimeoutService, private cryptoFunctionService: CryptoFunctionService, private vaultTimeoutService: VaultTimeoutService,
private runtimeBackground: RuntimeBackground, private i18nService: I18nService, private userService: UserService, private runtimeBackground: RuntimeBackground, private i18nService: I18nService, private userService: UserService,
private messagingService: MessagingService) {} private messagingService: MessagingService, private appIdService: AppIdService) {}
async connect() { async connect() {
this.appId = await this.appIdService.getAppId();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.port = BrowserApi.connectNative('com.8bit.bitwarden'); this.port = BrowserApi.connectNative('com.8bit.bitwarden');
@ -58,6 +62,11 @@ export class NativeMessagingBackground {
this.port.disconnect(); this.port.disconnect();
break; break;
case 'setupEncryption': case 'setupEncryption':
// Ignore since it belongs to another device
if (message.appId !== this.appId) {
return;
}
const encrypted = Utils.fromB64ToArray(message.sharedSecret); const encrypted = Utils.fromB64ToArray(message.sharedSecret);
const decrypted = await this.cryptoFunctionService.rsaDecrypt(encrypted.buffer, this.privateKey, EncryptionAlgorithm); const decrypted = await this.cryptoFunctionService.rsaDecrypt(encrypted.buffer, this.privateKey, EncryptionAlgorithm);
@ -65,6 +74,11 @@ export class NativeMessagingBackground {
this.secureSetupResolve(); this.secureSetupResolve();
break; break;
case 'invalidateEncryption': case 'invalidateEncryption':
// Ignore since it belongs to another device
if (message.appId !== this.appId) {
return;
}
this.sharedSecret = null; this.sharedSecret = null;
this.privateKey = null; this.privateKey = null;
this.connected = false; this.connected = false;
@ -76,7 +90,12 @@ export class NativeMessagingBackground {
type: 'error', type: 'error',
}); });
default: default:
this.onMessage(message); // Ignore since it belongs to another device
if (message.appId !== this.appId) {
return;
}
this.onMessage(message.message);
} }
}); });
@ -118,7 +137,7 @@ export class NativeMessagingBackground {
message.timestamp = Date.now(); message.timestamp = Date.now();
const encrypted = await this.cryptoService.encrypt(JSON.stringify(message), this.sharedSecret); const encrypted = await this.cryptoService.encrypt(JSON.stringify(message), this.sharedSecret);
this.port.postMessage(encrypted); this.port.postMessage({appId: this.appId, message: encrypted});
} }
getResponse(): Promise<any> { getResponse(): Promise<any> {
@ -193,6 +212,6 @@ export class NativeMessagingBackground {
message.timestamp = Date.now(); message.timestamp = Date.now();
this.port.postMessage(message); this.port.postMessage({appId: this.appId, message: message});
} }
} }