From c4185fe6ee54194ae923d617be94c0ae45bdbebe Mon Sep 17 00:00:00 2001 From: Hinton Date: Wed, 16 Dec 2020 15:47:30 +0100 Subject: [PATCH] Add support for multiple concurrent extensions with native messaging --- src/background/main.background.ts | 2 +- src/background/nativeMessaging.background.ts | 27 +++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/background/main.background.ts b/src/background/main.background.ts index 07b80e35bd..a929d52749 100644 --- a/src/background/main.background.ts +++ b/src/background/main.background.ts @@ -248,7 +248,7 @@ export default class MainBackground { this.analytics, this.notificationsService, this.systemService, this.vaultTimeoutService, this.environmentService, this.policyService, this.userService); 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.platformUtilsService, this.analytics, this.vaultTimeoutService); diff --git a/src/background/nativeMessaging.background.ts b/src/background/nativeMessaging.background.ts index 88397c0538..6cebf49dfd 100644 --- a/src/background/nativeMessaging.background.ts +++ b/src/background/nativeMessaging.background.ts @@ -12,6 +12,7 @@ import { SymmetricCryptoKey } from 'jslib/models/domain'; import { BrowserApi } from '../browser/browserApi'; import RuntimeBackground from './runtime.background'; +import { AppIdService } from 'jslib/abstractions'; const MessageValidTimeout = 10 * 1000; const EncryptionAlgorithm = 'sha1'; @@ -25,13 +26,16 @@ export class NativeMessagingBackground { private privateKey: ArrayBuffer = null; private secureSetupResolve: any = null; private sharedSecret: SymmetricCryptoKey; + private appId: string; constructor(private storageService: StorageService, private cryptoService: CryptoService, private cryptoFunctionService: CryptoFunctionService, private vaultTimeoutService: VaultTimeoutService, private runtimeBackground: RuntimeBackground, private i18nService: I18nService, private userService: UserService, - private messagingService: MessagingService) {} + private messagingService: MessagingService, private appIdService: AppIdService) {} async connect() { + this.appId = await this.appIdService.getAppId(); + return new Promise((resolve, reject) => { this.port = BrowserApi.connectNative('com.8bit.bitwarden'); @@ -58,6 +62,11 @@ export class NativeMessagingBackground { this.port.disconnect(); break; case 'setupEncryption': + // Ignore since it belongs to another device + if (message.appId !== this.appId) { + return; + } + const encrypted = Utils.fromB64ToArray(message.sharedSecret); const decrypted = await this.cryptoFunctionService.rsaDecrypt(encrypted.buffer, this.privateKey, EncryptionAlgorithm); @@ -65,6 +74,11 @@ export class NativeMessagingBackground { this.secureSetupResolve(); break; case 'invalidateEncryption': + // Ignore since it belongs to another device + if (message.appId !== this.appId) { + return; + } + this.sharedSecret = null; this.privateKey = null; this.connected = false; @@ -76,7 +90,12 @@ export class NativeMessagingBackground { type: 'error', }); 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(); 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 { @@ -193,6 +212,6 @@ export class NativeMessagingBackground { message.timestamp = Date.now(); - this.port.postMessage(message); + this.port.postMessage({appId: this.appId, message: message}); } }