コード例 #1
0
        private SignalServiceSyncMessage createSynchronizeMessage(SignalServiceEnvelope envelope, SyncMessage content)
        {
            if (content.SentOneofCase == SyncMessage.SentOneofOneofCase.Sent)
            {
                SyncMessage.Types.Sent sentContent = content.Sent;
                return(SignalServiceSyncMessage.forSentTranscript(new SentTranscriptMessage(sentContent.Destination,
                                                                                            (long)sentContent.Timestamp,
                                                                                            createSignalServiceMessage(envelope, sentContent.Message),
                                                                                            (long)sentContent.ExpirationStartTimestamp)));
            }

            if (content.RequestOneofCase == SyncMessage.RequestOneofOneofCase.Request)
            {
                return(SignalServiceSyncMessage.forRequest(new RequestMessage(content.Request)));
            }

            if (content.Read.Count > 0)
            {
                List <ReadMessage> readMessages = new List <ReadMessage>();

                foreach (SyncMessage.Types.Read read in content.Read)
                {
                    readMessages.Add(new ReadMessage(read.Sender, (long)read.Timestamp));
                }

                return(SignalServiceSyncMessage.forRead(readMessages));
            }

            return(SignalServiceSyncMessage.empty());
        }
コード例 #2
0
        /// <summary>
        /// Marks and dispatches a message as read. Must not be called on a task which holds the handle lock.
        /// </summary>
        /// <param name="message"></param>
        public async Task SetMessageRead(long index, SignalMessage message, SignalConversation conversation)
        {
            Logger.LogTrace("SetMessageRead() locking");
            await SemaphoreSlim.WaitAsync(CancelSource.Token);

            try
            {
                Logger.LogTrace("SetMessageRead() locked");
                conversation = SignalDBContext.UpdateMessageRead(index, conversation);
                OutgoingMessages.SendMessage(SignalServiceSyncMessage.ForRead(new List <ReadMessage>()
                {
                    new ReadMessage(message.Author.ThreadId, message.ComposedTimestamp)
                }));
                await DispatchMessageRead(index + 1, conversation);
            }
            catch (Exception e)
            {
                Logger.LogError("SetMessageRead() failed: {0}\n{1}", e.Message, e.StackTrace);
            }
            finally
            {
                SemaphoreSlim.Release();
            }
            Logger.LogTrace("SetMessageRead() released");
        }
コード例 #3
0
 public void SendMessage(SignalServiceSyncMessage message)
 {
     lock (this)
     {
         MessageSender.SendMessage(Token, message);
     }
 }
コード例 #4
0
        public void sendMessage(SignalServiceSyncMessage message)
        {
            byte[] content;

            if (message.getContacts().HasValue)
            {
                content = createMultiDeviceContactsContent(message.getContacts().ForceGetValue().Contacts.asStream(),
                                                           message.getContacts().ForceGetValue().Complete);
            }
            else if (message.getGroups().HasValue)
            {
                content = createMultiDeviceGroupsContent(message.getGroups().ForceGetValue().asStream());
            }
            else if (message.getRead().HasValue)
            {
                content = createMultiDeviceReadContent(message.getRead().ForceGetValue());
            }
            else if (message.getBlockedList().HasValue)
            {
                content = createMultiDeviceBlockedContent(message.getBlockedList().ForceGetValue());
            }
            else
            {
                throw new Exception("Unsupported sync message!");
            }

            sendMessage(localAddress, Util.CurrentTimeMillis(), content, false, false);
        }
コード例 #5
0
        /// <summary>
        /// Marks and dispatches a message as read. Must not be called on a task which holds the handle lock.
        /// </summary>
        /// <param name="message"></param>
        public async Task SetMessageRead(SignalMessage message)
        {
            Logger.LogTrace("SetMessageRead() locking");
            await SemaphoreSlim.WaitAsync(CancelSource.Token);

            try
            {
                Logger.LogTrace("SetMessageRead() locked");
                var updatedConversation = SignalDBContext.UpdateMessageRead(message.ComposedTimestamp);
                UpdateMessageExpiration(message, updatedConversation.ExpiresInSeconds);
                OutgoingQueue.Add(new SignalServiceSyncMessageSendable(SignalServiceSyncMessage.ForRead(new List <ReadMessage>()
                {
                    new ReadMessage(message.Author.ThreadId, message.ComposedTimestamp)
                })));
                await DispatchMessageRead(updatedConversation);
            }
            catch (Exception e)
            {
                Logger.LogError("SetMessageRead() failed: {0}\n{1}", e.Message, e.StackTrace);
            }
            finally
            {
                SemaphoreSlim.Release();
            }
            Logger.LogTrace("SetMessageRead() released");
        }
コード例 #6
0
        public async Task SendBlockedMessage()
        {
            List <SignalContact> blockedContacts = SignalDBContext.GetAllContactsLocked().Where(c => c.Blocked).ToList();
            List <string>        blockedNumbers  = new List <string>();

            foreach (var contact in blockedContacts)
            {
                blockedNumbers.Add(contact.ThreadId);
            }
            var blockMessage = SignalServiceSyncMessage.ForBlocked(new BlockedListMessage(blockedNumbers));

            OutgoingMessages.SendMessage(blockMessage);
            await DispatchHandleBlockedContacts(blockedContacts);
        }
コード例 #7
0
        private SignalServiceContent(SignalServiceSyncMessage synchronizeMessage, SignalServiceAddress sender, int senderDevice, long timestamp, bool needsReceipt, SignalServiceContentProto serializedState)
        {
            Sender               = sender;
            SenderDevice         = senderDevice;
            Timestamp            = timestamp;
            NeedsReceipt         = needsReceipt;
            this.serializedState = serializedState;

            Message            = null;
            SynchronizeMessage = synchronizeMessage;
            CallingMessage     = null;
            ReadMessage        = null;
            TypingMessage      = null;
        }
コード例 #8
0
 public void RequestSync()
 {
     Task.Run(() =>
     {
         Logger.LogTrace("RequestSync()");
         var contactsRequest = SignalServiceSyncMessage.ForRequest(new RequestMessage(new SyncMessage.Types.Request()
         {
             Type = SyncMessage.Types.Request.Types.Type.Contacts
         }));
         OutgoingMessages.SendMessage(contactsRequest);
         var groupsRequest = SignalServiceSyncMessage.ForRequest(new RequestMessage(new SyncMessage.Types.Request()
         {
             Type = SyncMessage.Types.Request.Types.Type.Groups
         }));
         OutgoingMessages.SendMessage(groupsRequest);
     });
 }
コード例 #9
0
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="token"></param>
        /// <param name="message"></param>
        public async Task SendMessage(CancellationToken token, SignalServiceSyncMessage message)
        {
            byte[] content;

            if (message.Contacts != null)
            {
                content = await CreateMultiDeviceContactsContent(token, message.Contacts.Contacts.AsStream(),
                                                                 message.Contacts.Complete);
            }
            else if (message.Groups != null)
            {
                content = await CreateMultiDeviceGroupsContent(token, message.Groups.AsStream());
            }
            else if (message.Reads != null)
            {
                content = CreateMultiDeviceReadContent(message.Reads);
            }
            else if (message.BlockedList != null)
            {
                content = CreateMultiDeviceBlockedContent(message.BlockedList);
            }
            else if (message.Configuration != null)
            {
                content = CreateMultiDeviceConfigurationContent(message.Configuration);
            }
            else if (message.Verified != null)
            {
                await SendMessage(token, message.Verified);

                return;
            }
            else if (message.Request != null)
            {
                content = CreateRequestContent(message.Request);
            }
            else
            {
                throw new Exception("Unsupported sync message!");
            }

            await SendMessage(token, localAddress, Util.CurrentTimeMillis(), content, false);
        }
コード例 #10
0
 public void RequestSync()
 {
     try
     {
         Logger.LogTrace("RequestSync()");
         var contactsRequest = SignalServiceSyncMessage.ForRequest(new RequestMessage(new SyncMessage.Types.Request()
         {
             Type = SyncMessage.Types.Request.Types.Type.Contacts
         }));
         OutgoingQueue.Add(new SignalServiceSyncMessageSendable(contactsRequest));
         var groupsRequest = SignalServiceSyncMessage.ForRequest(new RequestMessage(new SyncMessage.Types.Request()
         {
             Type = SyncMessage.Types.Request.Types.Type.Groups
         }));
         OutgoingQueue.Add(new SignalServiceSyncMessageSendable(groupsRequest));
     }
     catch (Exception e)
     {
         Logger.LogError("RequestSync() failed: {0}\n{1}", e.Message, e.StackTrace);
     }
 }
コード例 #11
0
 public SignalServiceSyncMessageSendable(SignalServiceSyncMessage message)
 {
     SyncMessage = message;
 }
コード例 #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="metadata"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        /// <exception cref="ProtocolInvalidMessageException"></exception>
        /// <exception cref="ProtocolInvalidKeyException"></exception>
        private static SignalServiceSyncMessage CreateSynchronizeMessage(SignalServiceMetadata metadata, SyncMessage content)
        {
            if (content.Sent != null)
            {
                var unidentifiedStatuses             = new Dictionary <SignalServiceAddress, bool>();
                SyncMessage.Types.Sent   sentContent = content.Sent;
                SignalServiceDataMessage dataMessage = CreateSignalServiceMessage(metadata, sentContent.Message);
                SignalServiceAddress?    address     = SignalServiceAddress.IsValidAddress(sentContent.DestinationUuid, sentContent.Destination) ?
                                                       new SignalServiceAddress(UuidUtil.ParseOrNull(sentContent.DestinationUuid), sentContent.Destination) :
                                                       null;

                if (address == null && dataMessage.Group == null)
                {
                    throw new ProtocolInvalidMessageException(new InvalidMessageException("SyncMessage missing both destination and group ID!"), null, 0);
                }

                foreach (var status in sentContent.UnidentifiedStatus)
                {
                    if (SignalServiceAddress.IsValidAddress(status.DestinationUuid, status.Destination))
                    {
                        SignalServiceAddress recipient = new SignalServiceAddress(UuidUtil.ParseOrNull(status.DestinationUuid), status.Destination);
                        unidentifiedStatuses.Add(recipient, status.Unidentified);
                    }
                    else
                    {
                        logger.LogWarning("Encountered an invalid UnidentifiedDeliveryStatus in a SentTranscript! Ignoring.");
                    }
                }

                return(SignalServiceSyncMessage.ForSentTranscript(new SentTranscriptMessage(address !,
                                                                                            (long)sentContent.Timestamp,
                                                                                            CreateSignalServiceMessage(metadata, sentContent.Message),
                                                                                            (long)sentContent.ExpirationStartTimestamp,
                                                                                            unidentifiedStatuses,
                                                                                            sentContent.IsRecipientUpdate)));
            }

            if (content.Request != null)
            {
                return(SignalServiceSyncMessage.ForRequest(new RequestMessage(content.Request)));
            }

            if (content.Read.Count > 0)
            {
                List <ReadMessage> readMessages = new List <ReadMessage>();

                foreach (SyncMessage.Types.Read read in content.Read)
                {
                    if (SignalServiceAddress.IsValidAddress(read.SenderUuid, read.Sender))
                    {
                        SignalServiceAddress address = new SignalServiceAddress(UuidUtil.ParseOrNull(read.SenderUuid), read.Sender);
                        readMessages.Add(new ReadMessage(address, (long)read.Timestamp));
                    }
                    else
                    {
                        logger.LogWarning("Encountered an invalid ReadMessage! Ignoring.");
                    }
                }

                return(SignalServiceSyncMessage.ForRead(readMessages));
            }

            if (content.ViewOnceOpen != null)
            {
                if (SignalServiceAddress.IsValidAddress(content.ViewOnceOpen.SenderUuid, content.ViewOnceOpen.Sender))
                {
                    SignalServiceAddress address   = new SignalServiceAddress(UuidUtil.ParseOrNull(content.ViewOnceOpen.SenderUuid), content.ViewOnceOpen.Sender);
                    ViewOnceOpenMessage  timerRead = new ViewOnceOpenMessage(address, (long)content.ViewOnceOpen.Timestamp);
                    return(SignalServiceSyncMessage.ForViewOnceOpen(timerRead));
                }
                else
                {
                    throw new ProtocolInvalidMessageException(new InvalidMessageException("ViewOnceOpen message has no sender!"), null, 0);
                }
            }

            if (content.Contacts != null)
            {
                AttachmentPointer pointer = content.Contacts.Blob;
                return(SignalServiceSyncMessage.ForContacts(new ContactsMessage(CreateAttachmentPointer(pointer), content.Contacts.Complete)));
            }

            if (content.Groups != null)
            {
                AttachmentPointer pointer = content.Groups.Blob;
                return(SignalServiceSyncMessage.ForGroups(CreateAttachmentPointer(pointer)));
            }

            if (content.Verified != null)
            {
                if (SignalServiceAddress.IsValidAddress(content.Verified.DestinationUuid, content.Verified.Destination))
                {
                    try
                    {
                        Verified             verified    = content.Verified;
                        SignalServiceAddress destination = new SignalServiceAddress(UuidUtil.ParseOrNull(verified.DestinationUuid), verified.Destination);
                        IdentityKey          identityKey = new IdentityKey(verified.IdentityKey.ToByteArray(), 0);

                        VerifiedMessage.VerifiedState verifiedState;

                        if (verified.State == Verified.Types.State.Default)
                        {
                            verifiedState = VerifiedMessage.VerifiedState.Default;
                        }
                        else if (verified.State == Verified.Types.State.Verified)
                        {
                            verifiedState = VerifiedMessage.VerifiedState.Verified;
                        }
                        else if (verified.State == Verified.Types.State.Unverified)
                        {
                            verifiedState = VerifiedMessage.VerifiedState.Unverified;
                        }
                        else
                        {
                            throw new ProtocolInvalidMessageException(new InvalidMessageException($"Unknown state: {(int)verified.State}"),
                                                                      metadata.Sender.GetIdentifier(), metadata.SenderDevice);
                        }

                        return(SignalServiceSyncMessage.ForVerified(new VerifiedMessage(destination, identityKey, verifiedState, Util.CurrentTimeMillis())));
                    }
                    catch (InvalidKeyException ex)
                    {
                        throw new ProtocolInvalidKeyException(ex, metadata.Sender.GetIdentifier(), metadata.SenderDevice);
                    }
                }
                else
                {
                    throw new ProtocolInvalidMessageException(new InvalidMessageException("Verified message has no sender!"), null, 0);
                }
            }

            if (content.StickerPackOperation.Count > 0)
            {
                List <StickerPackOperationMessage> operations = new List <StickerPackOperationMessage>();

                foreach (var operation in content.StickerPackOperation)
                {
                    byte[]? packId  = operation.HasPackId ? operation.PackId.ToByteArray() : null;
                    byte[]? packKey = operation.HasPackKey ? operation.PackKey.ToByteArray() : null;
                    StickerPackOperationMessage.OperationType?type = null;

                    if (operation.HasType)
                    {
                        switch (operation.Type)
                        {
                        case SyncMessage.Types.StickerPackOperation.Types.Type.Install: type = StickerPackOperationMessage.OperationType.Install; break;

                        case SyncMessage.Types.StickerPackOperation.Types.Type.Remove: type = StickerPackOperationMessage.OperationType.Remove; break;
                        }
                    }
                    operations.Add(new StickerPackOperationMessage(packId, packKey, type));
                }

                return(SignalServiceSyncMessage.ForStickerPackOperations(operations));
            }

            if (content.Blocked != null)
            {
                List <string> numbers = content.Blocked.Numbers.ToList();
                List <string> uuids   = content.Blocked.Uuids.ToList();
                List <SignalServiceAddress> addresses = new List <SignalServiceAddress>(numbers.Count + uuids.Count);
                List <byte[]> groupIds = new List <byte[]>(content.Blocked.GroupIds.Count);

                foreach (string e164 in numbers)
                {
                    SignalServiceAddress?address = SignalServiceAddress.FromRaw(null, e164);
                    if (address != null)
                    {
                        addresses.Add(address);
                    }
                }

                foreach (string uuid in uuids)
                {
                    SignalServiceAddress?address = SignalServiceAddress.FromRaw(uuid, null);
                    if (address != null)
                    {
                        addresses.Add(address);
                    }
                }

                foreach (ByteString groupId in content.Blocked.GroupIds)
                {
                    groupIds.Add(groupId.ToByteArray());
                }

                return(SignalServiceSyncMessage.ForBlocked(new BlockedListMessage(addresses, groupIds)));
            }

            if (content.Configuration != null)
            {
                bool?readReceipts = content.Configuration.HasReadReceipts ? content.Configuration.ReadReceipts : (bool?)null;
                bool?unidentifiedDeliveryIndicators = content.Configuration.HasUnidentifiedDeliveryIndicators ? content.Configuration.UnidentifiedDeliveryIndicators : (bool?)null;
                bool?typingIndicators = content.Configuration.HasTypingIndicators ? content.Configuration.TypingIndicators : (bool?)null;
                bool?linkPreviews     = content.Configuration.HasLinkPreviews ? content.Configuration.LinkPreviews : (bool?)null;

                return(SignalServiceSyncMessage.ForConfiguration(new ConfigurationMessage(readReceipts, unidentifiedDeliveryIndicators, typingIndicators, linkPreviews)));
            }

            return(SignalServiceSyncMessage.Empty());
        }
コード例 #13
0
 public SignalServiceContent(SignalServiceSyncMessage synchronizeMessage)
 {
     message = May.NoValue;
     this.synchronizeMessage = new May <SignalServiceSyncMessage>(synchronizeMessage);
 }
コード例 #14
0
        private SignalServiceSyncMessage CreateSynchronizeMessage(Metadata metadata, SyncMessage content)
        {
            if (content.SentOneofCase == SyncMessage.SentOneofOneofCase.Sent)
            {
                SyncMessage.Types.Sent sentContent = content.Sent;
                var unidentifiedStatuses           = new Dictionary <string, bool>();

                foreach (var status in sentContent.UnidentifiedStatus)
                {
                    unidentifiedStatuses[status.Destination] = status.Unidentified;
                }

                return(SignalServiceSyncMessage.ForSentTranscript(new SentTranscriptMessage(sentContent.Destination,
                                                                                            (long)sentContent.Timestamp,
                                                                                            CreateSignalServiceMessage(metadata, sentContent.Message),
                                                                                            (long)sentContent.ExpirationStartTimestamp,
                                                                                            unidentifiedStatuses)));
            }

            if (content.RequestOneofCase == SyncMessage.RequestOneofOneofCase.Request)
            {
                return(SignalServiceSyncMessage.ForRequest(new RequestMessage(content.Request)));
            }

            if (content.Read.Count > 0)
            {
                List <ReadMessage> readMessages = new List <ReadMessage>();

                foreach (SyncMessage.Types.Read read in content.Read)
                {
                    readMessages.Add(new ReadMessage(read.Sender, (long)read.Timestamp));
                }

                return(SignalServiceSyncMessage.ForRead(readMessages));
            }

            if (content.ContactsOneofCase == SyncMessage.ContactsOneofOneofCase.Contacts)
            {
                AttachmentPointer pointer = content.Contacts.Blob;
                return(SignalServiceSyncMessage.ForContacts(new ContactsMessage(CreateAttachmentPointer(pointer), content.Contacts.Complete)));
            }

            if (content.GroupsOneofCase == SyncMessage.GroupsOneofOneofCase.Groups)
            {
                AttachmentPointer pointer = content.Groups.Blob;
                return(SignalServiceSyncMessage.ForGroups(CreateAttachmentPointer(pointer)));
            }

            if (content.VerifiedOneofCase == SyncMessage.VerifiedOneofOneofCase.Verified)
            {
                try
                {
                    Verified    verified    = content.Verified;
                    string      destination = verified.Destination;
                    IdentityKey identityKey = new IdentityKey(verified.IdentityKey.ToByteArray(), 0);

                    VerifiedMessage.VerifiedState verifiedState;

                    if (verified.State == Verified.Types.State.Default)
                    {
                        verifiedState = VerifiedMessage.VerifiedState.Default;
                    }
                    else if (verified.State == Verified.Types.State.Verified)
                    {
                        verifiedState = VerifiedMessage.VerifiedState.Verified;
                    }
                    else if (verified.State == Verified.Types.State.Unverified)
                    {
                        verifiedState = VerifiedMessage.VerifiedState.Unverified;
                    }
                    else
                    {
                        throw new InvalidMessageException("Unknown state: " + verified.State);
                    }

                    return(SignalServiceSyncMessage.ForVerified(new VerifiedMessage(destination, identityKey, verifiedState, Util.CurrentTimeMillis())));
                }
                catch (InvalidKeyException e)
                {
                    throw new InvalidMessageException(e);
                }
            }

            if (content.BlockedOneofCase == SyncMessage.BlockedOneofOneofCase.Blocked)
            {
                List <string> blockedNumbers = new List <string>(content.Blocked.Numbers.Count);
                foreach (var blocked in content.Blocked.Numbers)
                {
                    blockedNumbers.Add(blocked);
                }
                return(SignalServiceSyncMessage.ForBlocked(new BlockedListMessage(blockedNumbers, content.Blocked.GroupIds.Select(gid => gid.ToByteArray()).ToList())));
            }

            if (content.VerifiedOneofCase == SyncMessage.VerifiedOneofOneofCase.Verified)
            {
                try
                {
                    Verified    verified    = content.Verified;
                    string      destination = verified.Destination;
                    IdentityKey identityKey = new IdentityKey(verified.IdentityKey.ToByteArray(), 0);

                    VerifiedMessage.VerifiedState verifiedState;

                    if (verified.State == Verified.Types.State.Default)
                    {
                        verifiedState = VerifiedMessage.VerifiedState.Default;
                    }
                    else if (verified.State == Verified.Types.State.Verified)
                    {
                        verifiedState = VerifiedMessage.VerifiedState.Verified;
                    }
                    else if (verified.State == Verified.Types.State.Unverified)
                    {
                        verifiedState = VerifiedMessage.VerifiedState.Unverified;
                    }
                    else
                    {
                        throw new ProtocolInvalidMessageException(new InvalidMessageException("Unknown state: " + verified.State),
                                                                  metadata.Sender, metadata.SenderDevice);
                    }
                    return(SignalServiceSyncMessage.ForVerified(new VerifiedMessage(destination, identityKey, verifiedState, Util.CurrentTimeMillis())));
                }
                catch (InvalidKeyException e)
                {
                    throw new ProtocolInvalidKeyException(e, metadata.Sender, metadata.SenderDevice);
                }
            }
            return(SignalServiceSyncMessage.Empty());
        }