Explorar o código

Fix reuse of init parameters (#985)

It is possible that the accessor to .peerPermanentKeyBytes throws an
exception, resulting in an infinite reconnect loop. Instead of
retrieving reuse parameters from the SaltyRTC instance, we just store them
ourselves now.
Lennart Grahl %!s(int64=5) %!d(string=hai) anos
pai
achega
b4939457dd
Modificáronse 2 ficheiros con 23 adicións e 15 borrados
  1. 2 12
      src/controllers/status.ts
  2. 21 3
      src/services/webclient.ts

+ 2 - 12
src/controllers/status.ts

@@ -189,10 +189,6 @@ export class StatusController {
             this.scheduleStatusBar();
         }
 
-        // Get original keys
-        const originalKeyStore = this.webClientService.salty.keyStore;
-        const originalPeerPermanentKeyBytes = this.webClientService.salty.peerPermanentKeyBytes;
-
         // Soft reconnect: Does not reset the loaded data
         this.webClientService.stop({
             reason: DisconnectReason.SessionStopped,
@@ -200,8 +196,7 @@ export class StatusController {
             close: false,
         });
         this.webClientService.init({
-            keyStore: originalKeyStore,
-            peerTrustedKey: originalPeerPermanentKeyBytes,
+            reuseKeyStoreAndTrustedKey: true,
             resume: true,
         });
 
@@ -238,10 +233,6 @@ export class StatusController {
     private reconnectIos(): void {
         this.log.info(`Connection lost (iOS). Reconnect attempt #${++this.stateService.attempt}`);
 
-        // Get original keys
-        const originalKeyStore = this.webClientService.salty.keyStore;
-        const originalPeerPermanentKeyBytes = this.webClientService.salty.peerPermanentKeyBytes;
-
         // Delay connecting a bit to wait for old websocket to close
         // TODO: Make this more robust and hopefully faster
         const startTimeout = 500;
@@ -286,8 +277,7 @@ export class StatusController {
                 this.log.debug('Starting new connection without push');
             }
             this.webClientService.init({
-                keyStore: originalKeyStore,
-                peerTrustedKey: originalPeerPermanentKeyBytes,
+                reuseKeyStoreAndTrustedKey: true,
                 resume: true,
             });
 

+ 21 - 3
src/services/webclient.ts

@@ -259,6 +259,10 @@ export class WebClientService {
     private batteryStatusTimeout: ng.IPromise<void> = null;
 
     // Other
+    private initParameters: {
+        keyStore?: saltyrtc.KeyStore,
+        peerTrustedKey?: Uint8Array,
+    } = {};
     private config: threema.Config;
     private container: threema.Container.Factory;
     private typingInstance: threema.Container.Typing;
@@ -451,12 +455,26 @@ export class WebClientService {
     public init(flags: {
         keyStore?: saltyrtc.KeyStore,
         peerTrustedKey?: Uint8Array,
+        reuseKeyStoreAndTrustedKey?: boolean,
         resume: boolean,
     }): void {
         let keyStore = flags.keyStore;
+        let peerTrustedKey = flags.peerTrustedKey;
         let resumeSession = flags.resume;
+
+        // Reuse
+        if (flags.reuseKeyStoreAndTrustedKey) {
+            keyStore = this.initParameters.keyStore;
+            peerTrustedKey = this.initParameters.peerTrustedKey;
+        } else {
+            this.initParameters = {
+                keyStore: keyStore,
+                peerTrustedKey: peerTrustedKey,
+            };
+        }
         this.log.info(`Initializing (keyStore=${keyStore !== undefined ? 'yes' : 'no'}, peerTrustedKey=` +
-            `${flags.peerTrustedKey !== undefined ? 'yes' : 'no'}, resume=${resumeSession})`);
+        `${peerTrustedKey !== undefined ? 'yes' : 'no'}, reuseKeyStoreAndTrustedKey=` +
+        `${flags.reuseKeyStoreAndTrustedKey}, resume=${resumeSession})`);
 
         // Reset fields, blob cache, pending requests and pending timeouts in case the session
         // should explicitly not be resumed
@@ -539,8 +557,8 @@ export class WebClientService {
             .withKeyStore(keyStore)
             .usingTasks(tasks)
             .withPingInterval(30);
-        if (flags.peerTrustedKey !== undefined) {
-            builder = builder.withTrustedPeerKey(flags.peerTrustedKey);
+        if (peerTrustedKey !== undefined) {
+            builder = builder.withTrustedPeerKey(peerTrustedKey);
         }
         this.salty = builder.asInitiator();
         this.arpLog.info('Public key:', this.salty.permanentKeyHex);