Пример #1
0
 public static void SaveOrUpdateSignalStore(SignalStore store)
 {
     lock (DBLock)
     {
         using (var ctx = new LibsignalDBContext())
         {
             var old = ctx.Store.SingleOrDefault();
             if (old != null)
             {
                 old.DeviceId           = store.DeviceId;
                 old.IdentityKeyPair    = store.IdentityKeyPair;
                 old.NextSignedPreKeyId = store.NextSignedPreKeyId;
                 old.Password           = store.Password;
                 old.PreKeyIdOffset     = store.PreKeyIdOffset;
                 old.Registered         = store.Registered;
                 old.RegistrationId     = store.RegistrationId;
                 old.SignalingKey       = store.SignalingKey;
                 old.Username           = store.Username;
             }
             else
             {
                 ctx.Store.Add(store);
             }
             ctx.SaveChanges();
         }
     }
 }
Пример #2
0
        public async Task Reacquire()
        {
            Logger.LogTrace("Reacquire() locking");
            CancelSource = new CancellationTokenSource();
            SemaphoreSlim.Wait(CancelSource.Token);
            try
            {
                GlobalResetEvent = LibUtils.OpenResetEventSet();
                LibUtils.Lock();
                GlobalResetEvent.Reset();
                LibsignalDBContext.ClearSessionCache();
                Instance = this;
                await Task.Run(async() =>
                {
                    List <Task> tasks = new List <Task>();
                    foreach (var f in Frames)
                    {
                        var conversations        = GetConversations();
                        var taskCompletionSource = new TaskCompletionSource <bool>();
                        await f.Key.RunAsync(CoreDispatcherPriority.Normal, () =>
                        {
                            try
                            {
                                f.Value.ReplaceConversationList(conversations);
                            }
                            catch (Exception e)
                            {
                                Logger.LogError("Reacquire() ReplaceConversationList() failed: {0}\n{1}", e.Message, e.StackTrace);
                            }
                            finally
                            {
                                taskCompletionSource.SetResult(false);
                            }
                        });
                        tasks.Add(taskCompletionSource.Task);
                    }
                    foreach (var t in tasks)
                    {
                        await t;
                    }
                    await RecoverDownloads();
                    Store = LibsignalDBContext.GetSignalStore();
                    if (Store != null)
                    {
                        LikelyHasValidStore = true;
                    }
                });

                if (LikelyHasValidStore)
                {
                    InitNetwork();
                }
                Running = true;
            }
            finally
            {
                SemaphoreSlim.Release();
                Logger.LogTrace("Reacquire() released");
            }
        }
        internal async Task OnNavigatedTo()
        {
            try
            {
                CancellationTokenSource cancelSource = new CancellationTokenSource();
                await Task.Run(async() =>
                {
                    string SignalingKey = Base64.EncodeBytes(Util.GetSecretBytes(52));
                    await App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.AccountManager.VerifyAccountWithCode(
                        cancelSource.Token,
                        App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.VerificationCode.Replace("-", ""),
                        SignalingKey, App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.SignalRegistrationId,
                        true, null);
                    SignalStore store = new SignalStore()
                    {
                        DeviceId           = 1,
                        IdentityKeyPair    = Base64.EncodeBytes(App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.IdentityKeyPair.serialize()),
                        NextSignedPreKeyId = 1,
                        Password           = App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.Password,
                        PreKeyIdOffset     = 1,
                        Registered         = true,
                        RegistrationId     = App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.SignalRegistrationId,
                        SignalingKey       = SignalingKey,
                        Username           = App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterPageInstance.FinalNumber,
                    };
                    LibsignalDBContext.SaveOrUpdateSignalStore(store);
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        App.Handle.Store = store;
                    }).AsTask().Wait();

                    /* create prekeys */
                    await LibsignalDBContext.RefreshPreKeys(
                        cancelSource.Token,
                        new SignalServiceAccountManager(App.ServiceConfiguration, store.Username, store.Password, (int)store.DeviceId, App.USER_AGENT));

                    /* reload again with prekeys and their offsets */
                    store = LibsignalDBContext.GetSignalStore();
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        App.Handle.Store = store;
                    }).AsTask().Wait();
                });

                var frontend = App.CurrentSignalWindowsFrontend(App.MainViewId);
                await App.Handle.Reacquire();

                View.Frame.Navigate(typeof(MainPage));
            }
            catch (Exception e)
            {
                Logger.LogError("OnNavigatedTo() failed: {0}\n{1}", e.Message, e.StackTrace);
                var           title   = "Verification failed";
                var           content = "Please enter the correct verification code.";
                MessageDialog dialog  = new MessageDialog(content, title);
                var           result  = dialog.ShowAsync();
                View.Frame.Navigate(typeof(RegisterPage));
            }
        }
Пример #4
0
 public void BackgroundAcquire()
 {
     CancelSource = new CancellationTokenSource();
     Instance     = this;
     SignalDBContext.FailAllPendingMessages();
     Store = LibsignalDBContext.GetSignalStore();
     InitNetwork();
     Running = true;
 }
Пример #5
0
        public async Task <bool> Acquire(CoreDispatcher d, ISignalFrontend w) //TODO wrap trycatch dispatch auth failure
        {
            Logger.LogTrace("Acquire() locking");
            CancelSource = new CancellationTokenSource();
            SemaphoreSlim.Wait(CancelSource.Token);
            try
            {
                GlobalResetEvent = LibUtils.OpenResetEventSet();
                LibUtils.Lock();
                GlobalResetEvent.Reset();
                MainWindowDispatcher = d;
                MainWindow           = w;
                Logger.LogDebug("Acquire() locked (global and local)");
                var getConversationsTask = Task.Run(() =>
                {
                    return(GetConversations()); // we want to display the conversations asap!
                });
                Instance = this;
                Frames.Add(d, w);
                w.ReplaceConversationList(await getConversationsTask);
                var failTask = Task.Run(() =>
                {
                    SignalDBContext.FailAllPendingMessages(); // TODO GetMessages needs to be protected by semaphoreslim as we fail defered
                });
                Store = await Task.Run(() =>
                {
                    return(LibsignalDBContext.GetSignalStore());
                });

                if (Store == null)
                {
                    return(false);
                }
                else
                {
                    LikelyHasValidStore = true;
                }
                var initNetwork = Task.Run(async() =>
                {
                    await InitNetwork();
                });
                var recoverDownloadsTask = Task.Run(() =>
                {
                    RecoverDownloads().Wait();
                });
                await failTask; // has to complete before messages are loaded
                await recoverDownloadsTask;
                Running = true;
                return(true);
            }
            finally
            {
                SemaphoreSlim.Release();
                Logger.LogTrace("Acquire() released");
            }
        }
Пример #6
0
        internal async Task OnNavigatedTo()
        {
            try
            {
                await Task.Run(() =>
                {
                    string SignalingKey = Base64.encodeBytes(Util.getSecretBytes(52));
                    App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.AccountManager.verifyAccountWithCode(
                        App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.VerificationCode,
                        SignalingKey, App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.SignalRegistrationId,
                        true);
                    SignalStore store = new SignalStore()
                    {
                        DeviceId           = 1,
                        IdentityKeyPair    = Base64.encodeBytes(App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.IdentityKeyPair.serialize()),
                        NextSignedPreKeyId = 1,
                        Password           = App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.Password,
                        PreKeyIdOffset     = 1,
                        Registered         = true,
                        RegistrationId     = App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterFinalizationPageInstance.SignalRegistrationId,
                        SignalingKey       = SignalingKey,
                        Username           = App.CurrentSignalWindowsFrontend(App.MainViewId).Locator.RegisterPageInstance.FinalNumber,
                    };
                    LibsignalDBContext.SaveOrUpdateSignalStore(store);
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        App.Store = store;
                        SignalLibHandle.Instance.Store = store;
                    }).AsTask().Wait();

                    /* create prekeys */
                    LibsignalDBContext.RefreshPreKeys(
                        new SignalServiceAccountManager(App.ServiceUrls, store.Username, store.Password, (int)store.DeviceId, App.USER_AGENT));

                    /* reload again with prekeys and their offsets */
                    store = LibsignalDBContext.GetSignalStore();
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        App.Store = store;
                    }).AsTask().Wait();
                });

                View.Frame.Navigate(typeof(MainPage));
            }
            catch (Exception e)
            {
                // TODO log exception
                var           title   = "Verification failed";
                var           content = "Please enter the correct verification code.";
                MessageDialog dialog  = new MessageDialog(content, title);
                var           result  = dialog.ShowAsync();
                View.Frame.Navigate(typeof(RegisterPage));
            }
        }
Пример #7
0
        public async Task Acquire(CoreDispatcher d, ISignalFrontend w) //TODO wrap trycatch dispatch auth failure
        {
            Logger.LogTrace("Acquire() locking");
            CancelSource = new CancellationTokenSource();
            SemaphoreSlim.Wait(CancelSource.Token);
            GlobalResetEvent = LibUtils.OpenResetEventSet();
            LibUtils.Lock();
            GlobalResetEvent.Reset();
            var getConversationsTask = Task.Run(() =>
            {
                return(GetConversations()); // we want to display the conversations asap!
            });

            Logger.LogDebug("Acquire() locked (global and local)");
            Instance = this;
            Frames.Add(d, w);
            w.ReplaceConversationList(await getConversationsTask);
            var failTask = Task.Run(() =>
            {
                SignalDBContext.FailAllPendingMessages(); // TODO GetMessages needs to be protected by semaphoreslim as we fail defered
            });

            Store = await Task.Run(() =>
            {
                return(LibsignalDBContext.GetSignalStore());
            });

            if (Store == null)
            {
                SemaphoreSlim.Release();
                throw new Exception("Signal Store has not been setup yet.");
            }
            await Task.Run(() =>
            {
                InitNetwork();
            });

            await failTask; // has to complete before messages are loaded

            Running = true;
            Logger.LogTrace("Acquire() releasing");
            SemaphoreSlim.Release();
        }
Пример #8
0
        public async Task BeginLinking()
        {
            try
            {
                CancelSource = new CancellationTokenSource();
                string deviceName = DeviceName;
                LinkingTask = Task.Run(() =>
                {
                    /* clean the database from stale values */
                    LibsignalDBContext.PurgeAccountData();

                    /* prepare qrcode */
                    string password             = Base64.encodeBytes(Util.getSecretBytes(18));
                    IdentityKeyPair tmpIdentity = KeyHelper.generateIdentityKeyPair();
                    SignalServiceAccountManager accountManager = new SignalServiceAccountManager(App.ServiceUrls, CancelSource.Token, "Signal-Windows");
                    string uuid     = accountManager.GetNewDeviceUuid(CancelSource.Token);
                    string tsdevice = "tsdevice:/?uuid=" + Uri.EscapeDataString(uuid) + "&pub_key=" + Uri.EscapeDataString(Base64.encodeBytesWithoutPadding(tmpIdentity.getPublicKey().serialize()));
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        View.SetQR(tsdevice);
                        QRVisible    = Visibility.Visible;
                        QRCodeString = tsdevice;
                    }).AsTask().Wait();

                    string tmpSignalingKey = Base64.encodeBytes(Util.getSecretBytes(52));
                    int registrationId     = (int)KeyHelper.generateRegistrationId(false);

                    NewDeviceLinkResult result = accountManager.FinishNewDeviceRegistration(tmpIdentity, tmpSignalingKey, password, false, true, registrationId, deviceName);
                    SignalStore store          = new SignalStore()
                    {
                        DeviceId           = (uint)result.DeviceId,
                        IdentityKeyPair    = Base64.encodeBytes(result.Identity.serialize()),
                        NextSignedPreKeyId = 1,
                        Password           = password,
                        PreKeyIdOffset     = 1,
                        Registered         = true,
                        RegistrationId     = (uint)registrationId,
                        SignalingKey       = tmpSignalingKey,
                        Username           = result.Number
                    };
                    LibsignalDBContext.SaveOrUpdateSignalStore(store);

                    /* reload registered state */
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        UIEnabled = false;
                        App.Store = store;
                    }).AsTask().Wait();

                    /* create prekeys */
                    LibsignalDBContext.RefreshPreKeys(new SignalServiceAccountManager(App.ServiceUrls, store.Username, store.Password, (int)store.DeviceId, App.USER_AGENT));

                    /* reload again with prekeys and their offsets */
                    store = LibsignalDBContext.GetSignalStore();
                    Debug.WriteLine("success!");
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        App.Store = store;
                        View.Finish(true);
                    }).AsTask().Wait();
                });
                await LinkingTask;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                Debug.WriteLine(e.StackTrace);
            }
        }
Пример #9
0
        public async Task BeginLinking()
        {
            try
            {
                CancelSource = new CancellationTokenSource();
                // clean the database from stale values
                await Task.Run(() =>
                {
                    LibsignalDBContext.PurgeAccountData();
                });

                (string password, IdentityKeyPair tmpIdentity) = await Task.Run(() =>
                {
                    string newPassword             = Base64.EncodeBytes(Util.GetSecretBytes(18));
                    IdentityKeyPair newTmpIdentity = KeyHelper.generateIdentityKeyPair();
                    return(newPassword, newTmpIdentity);
                });

                // fetch new device uuid
                SignalServiceAccountManager accountManager = new SignalServiceAccountManager(App.ServiceConfiguration, "Signal-Windows", new SignalWebSocketFactory());
                string uuid = await accountManager.GetNewDeviceUuid(CancelSource.Token, new SignalWebSocketFactory());

                string tsdevice = "tsdevice:/?uuid=" + Uri.EscapeDataString(uuid) + "&pub_key=" + Uri.EscapeDataString(Base64.EncodeBytesWithoutPadding(tmpIdentity.getPublicKey().serialize()));

                View.SetQR(tsdevice); //TODO generate qrcode in worker task
                QRVisible    = Visibility.Visible;
                QRCodeString = tsdevice;

                string tmpSignalingKey = Base64.EncodeBytes(Util.GetSecretBytes(52));
                int    registrationId  = (int)KeyHelper.generateRegistrationId(false);

                var provisionMessage = await accountManager.GetProvisioningMessage(CancelSource.Token, tmpIdentity);

                int deviceId = await accountManager.FinishNewDeviceRegistration(CancelSource.Token, provisionMessage, tmpSignalingKey, password, false, true, registrationId, View.GetDeviceName());

                SignalStore store = new SignalStore()
                {
                    DeviceId           = (uint)deviceId,
                    IdentityKeyPair    = Base64.EncodeBytes(provisionMessage.Identity.serialize()),
                    NextSignedPreKeyId = 1,
                    Password           = password,
                    PreKeyIdOffset     = 1,
                    Registered         = true,
                    RegistrationId     = (uint)registrationId,
                    SignalingKey       = tmpSignalingKey,
                    Username           = provisionMessage.Number
                };
                await Task.Run(() =>
                {
                    LibsignalDBContext.SaveOrUpdateSignalStore(store);
                });

                // reload registered state
                UIEnabled        = false;
                App.Handle.Store = store;

                // create prekeys
                await LibsignalDBContext.RefreshPreKeys(CancelSource.Token, new SignalServiceAccountManager(App.ServiceConfiguration, store.Username, store.Password, (int)store.DeviceId, App.USER_AGENT));

                // reload again with prekeys and their offsets
                App.Handle.Store = LibsignalDBContext.GetSignalStore();
                await View.Finish(true);
            }
            catch (Exception e)
            {
                var line = new StackTrace(e, true).GetFrames()[0].GetFileLineNumber();
                Logger.LogError("BeginLinking() failed in line {0}: {1}\n{2}", line, e.Message, e.StackTrace);
            }
        }
Пример #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="e"></param>
        /// <param name="launched">
        /// If OnLaunched this is true
        /// If OnActivated this is false
        /// </param>
        /// <returns></returns>
        private async Task OnLaunchedOrActivated(IActivatedEventArgs e, bool launched = true)
        {
            Debug.WriteLine("Signal-Windows " + LocalFolder.Path.ToString());
            Window.Current.Activated += Current_Activated;
            WindowActive              = true;
            Frame rootFrame = Window.Current.Content as Frame;

            // App-Initialisierung nicht wiederholen, wenn das Fenster bereits Inhalte enthält.
            // Nur sicherstellen, dass das Fenster aktiv ist.
            if (rootFrame == null)
            {
                // Frame erstellen, der als Navigationskontext fungiert und zum Parameter der ersten Seite navigieren
                rootFrame = new Frame();

                rootFrame.NavigationFailed += OnNavigationFailed;

                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    //TODO: Zustand von zuvor angehaltener Anwendung laden
                }

                // Den Frame im aktuellen Fenster platzieren
                Window.Current.Content = rootFrame;
            }

            if (launched)
            {
                LaunchActivatedEventArgs args = e as LaunchActivatedEventArgs;
                if (args.PrelaunchActivated == false)
                {
                    if (rootFrame.Content == null)
                    {
                        // Wenn der Navigationsstapel nicht wiederhergestellt wird, zur ersten Seite navigieren
                        // und die neue Seite konfigurieren, indem die erforderlichen Informationen als Navigationsparameter
                        // übergeben werden
                        Store = await Init;
                        if (Store == null || !Store.Registered)
                        {
                            rootFrame.Navigate(typeof(StartPage), args.Arguments);
                        }
                        else
                        {
                            rootFrame.Navigate(typeof(MainPage), args.Arguments);
                        }
                    }
                }
            }
            else
            {
                if (e is ToastNotificationActivatedEventArgs)
                {
                    var         args        = e as ToastNotificationActivatedEventArgs;
                    QueryString queryString = QueryString.Parse(args.Argument);
                    if (!(rootFrame.Content is MainPage))
                    {
                        rootFrame.Navigate(typeof(MainPage), queryString);
                    }
                }
            }
            TileUpdateManager.CreateTileUpdaterForApplication().Clear();
            // Sicherstellen, dass das aktuelle Fenster aktiv ist
            Window.Current.Activate();
        }