示例#1
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");
            }
        }
示例#2
0
        public async Task Reacquire()
        {
            Logger.LogTrace("Reacquire() locking");
            CancelSource = new CancellationTokenSource();
            SemaphoreSlim.Wait(CancelSource.Token);
            GlobalResetEvent = LibUtils.OpenResetEventSet();
            LibUtils.Lock();
            GlobalResetEvent.Reset();
            LibsignalDBContext.ClearSessionCache();
            Instance = this;
            await Task.Run(() =>
            {
                List <Task> tasks = new List <Task>();
                foreach (var f in Frames)
                {
                    var conversations = GetConversations();
                    tasks.Add(f.Key.RunTaskAsync(() =>
                    {
                        f.Value.ReplaceConversationList(conversations);
                    }));
                }
                Task.WaitAll(tasks.ToArray());
                InitNetwork();
            });

            Running = true;
            Logger.LogTrace("Reacquire() releasing");
            SemaphoreSlim.Release();
        }
示例#3
0
        internal async void BackButton_Click(object sender, BackRequestedEventArgs e)
        {
            if (UIEnabled)
            {
                CancelSource.Cancel();
                if (LinkingTask != null)
                {
                    try
                    {
                        await LinkingTask;
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.Message);
                        Debug.WriteLine(ex.StackTrace);
                    }
                }
                await Task.Run(() =>
                {
                    LibsignalDBContext.PurgeAccountData();
                });

                View.Frame.GoBack();
                e.Handled = true;
            }
        }
        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 PurgeAccountData()
 {
     Logger.LogTrace("PurgeAccountData() locking");
     SemaphoreSlim.Wait(CancelSource.Token);
     Logger.LogTrace("PurgeAccountData() locked");
     LibsignalDBContext.PurgeAccountData();
     SemaphoreSlim.Release();
     Logger.LogTrace("PurgeAccountData() released");
 }
示例#6
0
 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");
            }
        }
        private async Task HandleSessionResetMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp)
        {
            SignalMessageDirection type;
            SignalContact          author;
            SignalMessageStatus    status;
            SignalConversation     conversation;
            string prefix;
            string conversationId;
            Guid?  conversationGuid;
            long   composedTimestamp;

            if (isSync)
            {
                var sent = content.SynchronizeMessage.Sent;
                type              = SignalMessageDirection.Synced;
                status            = SignalMessageStatus.Confirmed;
                composedTimestamp = sent.Timestamp;
                author            = null;
                prefix            = "You have";
                conversationId    = sent.Destination.E164;
                conversationGuid  = sent.Destination.Uuid;
            }
            else
            {
                status = 0;
                type   = SignalMessageDirection.Incoming;
                author = await SignalDBContext.GetOrCreateContactLocked(content.Sender.E164, content.Sender.Uuid);

                prefix            = $"{author.ThreadDisplayName} has";
                composedTimestamp = envelope.GetTimestamp();
                conversationId    = content.Sender.E164;
                conversationGuid  = content.Sender.Uuid;
            }
            LibsignalDBContext.DeleteAllSessions(conversationId);
            conversation = await SignalDBContext.GetOrCreateContactLocked(conversationId, conversationGuid);

            SignalMessage sm = new SignalMessage()
            {
                Direction = type,
                Type      = SignalMessageType.SessionReset,
                Status    = status,
                Author    = author,
                Content   = new SignalMessageContent()
                {
                    Content = $"{prefix} reset the session."
                },
                ThreadId          = conversationId,
                ThreadGuid        = conversationGuid,
                DeviceId          = (uint)envelope.GetSourceDevice(),
                Receipts          = 0,
                ComposedTimestamp = composedTimestamp,
                ReceivedTimestamp = timestamp,
            };
            await SignalLibHandle.Instance.SaveAndDispatchSignalMessage(sm, null, conversation);
        }
示例#9
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));
            }
        }
示例#10
0
        internal void HandleOutgoingKeyChangeLocked(string user, string identity)
        {
            Logger.LogTrace("HandleOutgoingKeyChange() locking");
            SemaphoreSlim.Wait(CancelSource.Token);
            Logger.LogTrace("HandleOutgoingKeyChange() locked");
            var messages = LibsignalDBContext.InsertIdentityChangedMessagesLocked(user);

            LibsignalDBContext.SaveIdentityLocked(new SignalProtocolAddress(user, 1), identity);
            DispatchHandleIdentityKeyChange(messages);
            SemaphoreSlim.Release();
            Logger.LogTrace("HandleOutgoingKeyChange() released");
        }
示例#11
0
        private void HandleSessionResetMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp)
        {
            SignalMessageDirection type;
            SignalContact          author;
            SignalMessageStatus    status;
            string prefix;
            string conversationId;
            long   composedTimestamp;

            if (isSync)
            {
                var sent = content.SynchronizeMessage.getSent().ForceGetValue();
                type              = SignalMessageDirection.Synced;
                status            = SignalMessageStatus.Confirmed;
                composedTimestamp = sent.getTimestamp();
                author            = null;
                prefix            = "You have";
                conversationId    = sent.getDestination().ForceGetValue();
            }
            else
            {
                status            = 0;
                type              = SignalMessageDirection.Incoming;
                author            = SignalDBContext.GetOrCreateContactLocked(envelope.getSource(), timestamp, this);
                prefix            = $"{author.ThreadDisplayName} has";
                composedTimestamp = envelope.getTimestamp();
                conversationId    = envelope.getSource();
            }
            LibsignalDBContext.DeleteAllSessions(conversationId);

            SignalMessage sm = new SignalMessage()
            {
                Direction = type,
                Type      = SignalMessageType.SessionReset,
                Status    = status,
                Author    = author,
                Content   = new SignalMessageContent()
                {
                    Content = $"{prefix} reset the session."
                },
                ThreadId          = conversationId,
                DeviceId          = (uint)envelope.getSourceDevice(),
                Receipts          = 0,
                ComposedTimestamp = composedTimestamp,
                ReceivedTimestamp = timestamp,
            };

            Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() =>
            {
                await UIHandleIncomingMessage(sm);
            }).AsTask().Wait();
        }
        private SignalServiceAccountManager InitRegistration(bool voice)
        {
            LibsignalDBContext.PurgeAccountData();
            SignalServiceAccountManager accountManager = new SignalServiceAccountManager(App.ServiceUrls, App.ViewModels.RegisterPageInstance.FinalNumber, Password, 1 /*device id isn't actually used*/, App.USER_AGENT);

            if (voice)
            {
                accountManager.requestVoiceVerificationCode();
            }
            else
            {
                accountManager.requestSmsVerificationCode();
            }
            return(accountManager);
        }
示例#13
0
 /// <summary>
 /// Initialisiert das Singletonanwendungsobjekt. Dies ist die erste Zeile von erstelltem Code
 /// und daher das logische Äquivalent von main() bzw. WinMain().
 /// </summary>
 public App()
 {
     this.InitializeComponent();
     this.Suspending += OnSuspending;
     try
     {
         Init = Task.Run(() =>
         {
             SignalDBContext.Migrate();
             LibsignalDBContext.Migrate();
             return(LibsignalDBContext.GetSignalStore());
         });
     }
     catch (Exception e)
     {
         Debug.WriteLine(e.Message);
         Debug.WriteLine(e.StackTrace);
     }
 }
示例#14
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();
        }
示例#15
0
        internal async Task HandleOutgoingKeyChangeLocked(string user, string identity)
        {
            Logger.LogTrace("HandleOutgoingKeyChange() locking");
            await SemaphoreSlim.WaitAsync(CancelSource.Token);

            try
            {
                Logger.LogTrace("HandleOutgoingKeyChange() locked");
                await LibsignalDBContext.SaveIdentityLocked(new SignalProtocolAddress(user, 1), identity);
            }
            catch (Exception e)
            {
                Logger.LogError("HandleOutgoingKeyChangeLocked() failed: {0}\n{1}", e.Message, e.StackTrace);
            }
            finally
            {
                SemaphoreSlim.Release();
            }
            Logger.LogTrace("HandleOutgoingKeyChange() released");
        }
示例#16
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);
            }
        }
示例#17
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);
            }
        }
        /// <summary>
        /// Reads pending messages from the <see cref="OutgoingQueue"/> and attempts to send them
        /// </summary>
        public void HandleOutgoingMessages()
        {
            Debug.WriteLine("HandleOutgoingMessages starting...");
            CancellationToken token = CancelSource.Token;

            while (!token.IsCancellationRequested)
            {
                SignalMessage outgoingSignalMessage = null;
                try
                {
                    outgoingSignalMessage = OutgoingQueue.Take(token);
                    SignalServiceDataMessage message = new SignalServiceDataMessage()
                    {
                        Body             = outgoingSignalMessage.Content.Content,
                        Timestamp        = outgoingSignalMessage.ComposedTimestamp,
                        ExpiresInSeconds = (int)outgoingSignalMessage.ExpiresAt
                    };

                    if (!outgoingSignalMessage.ThreadId.EndsWith("="))
                    {
                        if (!token.IsCancellationRequested)
                        {
                            MessageSender.sendMessage(new SignalServiceAddress(outgoingSignalMessage.ThreadId), message);
                            outgoingSignalMessage.Status = SignalMessageStatus.Confirmed;
                        }
                    }
                    else
                    {
                        List <SignalServiceAddress> recipients = new List <SignalServiceAddress>();
                        SignalGroup g = SignalDBContext.GetOrCreateGroupLocked(outgoingSignalMessage.ThreadId, 0, this);
                        foreach (GroupMembership sc in g.GroupMemberships)
                        {
                            if (sc.Contact.ThreadId != App.Store.Username)
                            {
                                recipients.Add(new SignalServiceAddress(sc.Contact.ThreadId));
                            }
                        }
                        message.Group = new SignalServiceGroup()
                        {
                            GroupId = Base64.decode(g.ThreadId),
                            Type    = SignalServiceGroup.GroupType.DELIVER
                        };
                        if (!token.IsCancellationRequested)
                        {
                            MessageSender.sendMessage(recipients, message);
                            outgoingSignalMessage.Status = SignalMessageStatus.Confirmed;
                        }
                    }
                }
                catch (OperationCanceledException e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                    Debug.WriteLine("HandleOutgoingMessages finished");
                    return;
                }
                catch (EncapsulatedExceptions exceptions)
                {
                    outgoingSignalMessage.Status = SignalMessageStatus.Confirmed;
                    Debug.WriteLine(exceptions.Message);
                    Debug.WriteLine(exceptions.StackTrace);
                    IList <UntrustedIdentityException> identityExceptions = exceptions.getUntrustedIdentityExceptions();
                    if (exceptions.getNetworkExceptions().Count > 0)
                    {
                        outgoingSignalMessage.Status = SignalMessageStatus.Failed_Network;
                    }
                    if (identityExceptions.Count > 0)
                    {
                        outgoingSignalMessage.Status = SignalMessageStatus.Failed_Identity;
                    }
                    foreach (UntrustedIdentityException e in identityExceptions)
                    {
                        Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() =>
                        {
                            await MainPage.NotifyNewIdentity(e.getE164Number());
                        }).AsTask().Wait();
                        LibsignalDBContext.SaveIdentityLocked(new SignalProtocolAddress(e.getE164Number(), 1), Base64.encodeBytes(e.getIdentityKey().serialize()));
                    }
                }
                catch (RateLimitException e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                    outgoingSignalMessage.Status = SignalMessageStatus.Failed_Ratelimit;
                }
                catch (UntrustedIdentityException e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                    outgoingSignalMessage.Status = SignalMessageStatus.Failed_Identity;
                    Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() =>
                    {
                        await MainPage.NotifyNewIdentity(e.getE164Number());
                    }).AsTask().Wait();
                    LibsignalDBContext.SaveIdentityLocked(new SignalProtocolAddress(e.getE164Number(), 1), Base64.encodeBytes(e.getIdentityKey().serialize()));
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                    outgoingSignalMessage.Status = SignalMessageStatus.Failed_Unknown;
                }
                SignalDBContext.UpdateMessageStatus(outgoingSignalMessage, this);
            }
            Debug.WriteLine("HandleOutgoingMessages finished");
        }
示例#19
0
 static App()
 {
     // TODO enforce these have begun before initializing
     Task.Run(() => { SignalDBContext.Migrate(); });
     Task.Run(() => { LibsignalDBContext.Migrate(); });
 }