Beispiel #1
0
        private async Task HandleMessage(SignalServiceEnvelope envelope)
        {
            var cipher = new SignalServiceCipher(new SignalServiceAddress(SignalLibHandle.Instance.Store.Username), new Store(), LibUtils.GetCertificateValidator());
            // TODO: Starting to get messages of an unknown type which causes Decrypt to return null, so handle the null case for now.
            var  content   = cipher.Decrypt(envelope);
            long timestamp = Util.CurrentTimeMillis();

            if (content == null)
            {
                //TODO callmessages
                Logger.LogWarning("HandleMessage() received unrecognized message");
                return;
            }
            if (content.Message != null)
            {
                SignalServiceDataMessage message = content.Message;
                if (message.EndSession)
                {
                    await HandleSessionResetMessage(envelope, content, message, false, timestamp);
                }
                else if (message.IsGroupUpdate())
                {
                    if (message.Group.Type == SignalServiceGroup.GroupType.UPDATE)
                    {
                        await HandleGroupUpdateMessage(envelope, content, message, false, timestamp);
                    }
                    else if (message.Group.Type == SignalServiceGroup.GroupType.QUIT)
                    {
                        await HandleGroupLeaveMessage(envelope, content, message, false, timestamp);
                    }
                    else if (message.Group.Type == SignalServiceGroup.GroupType.REQUEST_INFO)
                    {
                        Logger.LogWarning("Received REQUEST_INFO request");
                    }
                }
                else if (message.ExpirationUpdate)
                {
                    await HandleExpirationUpdateMessage(envelope, content, message, false, timestamp);
                }
                else
                {
                    await HandleSignalMessage(envelope, content, message, false, timestamp);
                }
            }
            else if (content.SynchronizeMessage != null)
            {
                if (content.SynchronizeMessage.Sent != null)
                {
                    var syncMessage = content.SynchronizeMessage.Sent;
                    var dataMessage = syncMessage.Message;

                    if (dataMessage.EndSession)
                    {
                        await HandleSessionResetMessage(envelope, content, dataMessage, true, timestamp);
                    }
                    else if (dataMessage.IsGroupUpdate())
                    {
                        if (dataMessage.Group.Type == SignalServiceGroup.GroupType.UPDATE)
                        {
                            await HandleGroupUpdateMessage(envelope, content, dataMessage, true, timestamp);
                        }
                        else if (dataMessage.Group.Type == SignalServiceGroup.GroupType.QUIT)
                        {
                            await HandleGroupLeaveMessage(envelope, content, dataMessage, true, timestamp);
                        }
                        else if (dataMessage.Group.Type == SignalServiceGroup.GroupType.REQUEST_INFO)
                        {
                            Logger.LogWarning("Received synced REQUEST_INFO request");
                        }
                    }
                    else if (dataMessage.ExpirationUpdate)
                    {
                        await HandleExpirationUpdateMessage(envelope, content, dataMessage, true, timestamp);
                    }
                    else
                    {
                        await HandleSignalMessage(envelope, content, dataMessage, true, timestamp);
                    }
                }
                else if (content.SynchronizeMessage.Reads != null)
                {
                    var readMessages = content.SynchronizeMessage.Reads;
                    foreach (var readMessage in readMessages)
                    {
                        try
                        {
                            await HandleSyncedReadMessage(readMessage);
                        }
                        catch (Exception e)
                        {
                            Logger.LogError("HandleReadMessage failed: {0}\n{1}", e.Message, e.StackTrace);
                        }
                    }
                }
                else if (content.SynchronizeMessage.BlockedList != null)
                {
                    List <string> blockedNumbers = content.SynchronizeMessage.BlockedList.Numbers;
                    await HandleBlockedNumbers(blockedNumbers);
                }
                else if (content.SynchronizeMessage.Groups != null)
                {
                    Logger.LogInformation("HandleMessage() handling groups sync message from device {0}", envelope.GetSourceDevice());
                    int read;
                    var avatarBuffer = new byte[4096];
                    var groups       = content.SynchronizeMessage.Groups;
                    using (var tmpFile = LibUtils.CreateTmpFile("groups_sync"))
                    {
                        var plaintextStream = await MessageReceiver.RetrieveAttachment(Token, groups.AsPointer(), tmpFile, 10000, null);

                        var         deviceGroupsStream = new DeviceGroupsInputStream(plaintextStream);
                        var         groupsList         = new List <(SignalGroup, IList <string>)>();
                        DeviceGroup g;
                        while ((g = deviceGroupsStream.Read()) != null)
                        {
                            if (g.Avatar != null)
                            {
                                SignalServiceAttachmentStream ssas = g.Avatar.AsStream();
                                while ((read = ssas.InputStream.Read(avatarBuffer, 0, avatarBuffer.Length)) > 0)
                                {
                                }
                            }
                            var group = new SignalGroup()
                            {
                                ThreadDisplayName = g.Name,
                                ThreadId          = Base64.EncodeBytes(g.Id),
                                GroupMemberships  = new List <GroupMembership>(),
                                CanReceive        = true,
                                ExpiresInSeconds  = g.ExpirationTimer != null ? g.ExpirationTimer.Value : 0
                            };
                            groupsList.Add((group, g.Members));
                        }
                        List <SignalConversation> dbGroups = await SignalDBContext.InsertOrUpdateGroups(groupsList);

                        await SignalLibHandle.Instance.DispatchAddOrUpdateConversations(dbGroups);
                    }
                }
                else if (content.SynchronizeMessage.Contacts != null && content.SynchronizeMessage.Contacts.Complete) //TODO incomplete updates
                {
                    Logger.LogInformation("HandleMessage() handling contacts sync message from device {0}", envelope.GetSourceDevice());
                    int             read;
                    var             avatarBuffer = new byte[4096];
                    ContactsMessage contacts     = content.SynchronizeMessage.Contacts;
                    using (var tmpFile = LibUtils.CreateTmpFile("contacts_sync"))
                    {
                        var plaintextStream = await MessageReceiver.RetrieveAttachment(Token, contacts.Contacts.AsPointer(), tmpFile, 10000, null);

                        var deviceContactsStream          = new DeviceContactsInputStream(plaintextStream);
                        List <SignalContact> contactsList = new List <SignalContact>();
                        DeviceContact        c;
                        while ((c = deviceContactsStream.Read()) != null)
                        {
                            if (c.Avatar != null)
                            {
                                SignalServiceAttachmentStream ssas = c.Avatar.AsStream();
                                while ((read = ssas.InputStream.Read(avatarBuffer, 0, avatarBuffer.Length)) > 0)
                                {
                                }
                            }
                            SignalContact contact = new SignalContact()
                            {
                                ThreadDisplayName = c.Name,
                                ThreadId          = c.Number,
                                Color             = c.Color,
                                CanReceive        = true,
                                ExpiresInSeconds  = c.ExpirationTimer != null ? c.ExpirationTimer.Value : 0
                            };
                            contactsList.Add(contact);
                        }
                        var dbContacts = SignalDBContext.InsertOrUpdateContacts(contactsList);
                        await SignalLibHandle.Instance.DispatchAddOrUpdateConversations(dbContacts);
                    }
                }
            }
            else if (content.ReadMessage != null)
            {
                SignalServiceReceiptMessage receiptMessage = content.ReadMessage;
                Logger.LogTrace("HandleMessage() received ReceiptMessage (type={0}, when={1})", receiptMessage.ReceiptType, receiptMessage.When);
            }
            else
            {
                //TODO callmessages
                Logger.LogWarning("HandleMessage() received unrecognized message");
            }
        }