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(); } } }
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)); } }
public void BackgroundAcquire() { CancelSource = new CancellationTokenSource(); Instance = this; SignalDBContext.FailAllPendingMessages(); Store = LibsignalDBContext.GetSignalStore(); InitNetwork(); Running = true; }
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"); } }
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)); } }
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(); }
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); } }
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); } }
/// <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(); }