private static SignalServiceDataMessage.SignalServiceQuote?CreateQuote(DataMessage content)
        {
            if (content.Quote == null)
            {
                return(null);
            }

            var attachments = new List <SignalServiceDataMessage.SignalServiceQuotedAttachment>();

            foreach (var attachment in content.Quote.Attachments)
            {
                attachments.Add(new SignalServiceDataMessage.SignalServiceQuotedAttachment(attachment.ContentType,
                                                                                           attachment.FileName,
                                                                                           attachment.Thumbnail != null ? CreateAttachmentPointer(attachment.Thumbnail) : null));
            }

            if (SignalServiceAddress.IsValidAddress(content.Quote.AuthorUuid, content.Quote.Author))
            {
                SignalServiceAddress address = new SignalServiceAddress(UuidUtil.ParseOrNull(content.Quote.AuthorUuid), content.Quote.Author);

                return(new SignalServiceDataMessage.SignalServiceQuote((long)content.Quote.Id,
                                                                       address,
                                                                       content.Quote.Text,
                                                                       attachments));
            }
            else
            {
                logger.LogWarning("Quote was missing an author! Returning null.");
                return(null);
            }
        }
 public static SignalServiceAddress?FromRaw(string?rawUuid, string?e164)
 {
     if (IsValidAddress(rawUuid, e164))
     {
         return(new SignalServiceAddress(UuidUtil.ParseOrNull(rawUuid), e164));
     }
     else
     {
         return(null);
     }
 }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        /// <exception cref="IOException"></exception>
        public DeviceGroup?Read()
        {
            int detailsLength = ReadRawVarint32();

            if (detailsLength == -1)
            {
                return(null);
            }
            byte[] detailsSerialized = new byte[detailsLength];
            Util.ReadFully(inputStream, detailsSerialized);

            GroupDetails details = GroupDetails.Parser.ParseFrom(detailsSerialized);

            if (!details.HasId)
            {
                throw new IOException("ID missing on group record!");
            }

            byte[] id   = details.Id.ToByteArray();
            string?name = details.HasName ? details.Name : null;
            List <GroupDetails.Types.Member> members = details.Members.ToList();
            SignalServiceAttachmentStream?   avatar  = null;
            bool   active          = details.Active;
            uint?  expirationTimer = null;
            string?color           = details.HasColor ? details.Color : null;
            bool   blocked         = details.Blocked;

            if (details.Avatar != null)
            {
                long   avatarLength      = details.Avatar.Length;
                Stream avatarStream      = new LimitedInputStream(inputStream, avatarLength);
                string avatarContentType = details.Avatar.ContentType;
                avatar = new SignalServiceAttachmentStream(avatarStream, avatarContentType, avatarLength, null, false, null);
            }

            if (details.HasExpireTimer && details.ExpireTimer > 0)
            {
                expirationTimer = details.ExpireTimer;
            }

            List <SignalServiceAddress> addressMembers = new List <SignalServiceAddress>(members.Count);

            foreach (GroupDetails.Types.Member member in members)
            {
                addressMembers.Add(new SignalServiceAddress(UuidUtil.ParseOrNull(member.Uuid), member.E164));
            }

            return(new DeviceGroup(id, name, addressMembers, avatar, active, expirationTimer, color, blocked));
        }
        public async Task <List <SignalServiceEnvelope> > RetrieveMessagesAsync(IMessagePipeCallback callback, CancellationToken?token = null)
        {
            if (token == null)
            {
                token = CancellationToken.None;
            }

            List <SignalServiceEnvelope>       results  = new List <SignalServiceEnvelope>();
            List <SignalServiceEnvelopeEntity> entities = await socket.GetMessagesAsync(token);

            foreach (SignalServiceEnvelopeEntity entity in entities)
            {
                SignalServiceEnvelope envelope;

                if (entity.HasSource() && entity.SourceDevice > 0)
                {
                    SignalServiceAddress address = new SignalServiceAddress(UuidUtil.ParseOrNull(entity.SourceUuid), entity.SourceE164);
                    envelope = new SignalServiceEnvelope((int)entity.Type, address,
                                                         (int)entity.SourceDevice, (int)entity.Timestamp,
                                                         entity.Message, entity.Content,
                                                         entity.ServerTimestamp, entity.ServerUuid);
                }
                else
                {
                    envelope = new SignalServiceEnvelope((int)entity.Type, (int)entity.Timestamp,
                                                         entity.Message, entity.Content,
                                                         entity.ServerTimestamp, entity.ServerUuid);
                }

                await callback.OnMessageAsync(envelope);

                results.Add(envelope);

                if (envelope.HasUuid())
                {
                    await socket.AcknowledgeMessageAsync(envelope.GetUuid(), token);
                }
                else
                {
                    await socket.AcknowledgeMessageAsync(entity.SourceE164 !, entity.Timestamp, token);
                }
            }
            return(results);
        }
        /// <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());
        }
예제 #6
0
 /// <summary>
 /// The envelope's sender as a SignalServiceAddress.
 /// </summary>
 /// <returns>The envelope's sender as a SignalServiceAddress.</returns>
 public SignalServiceAddress GetSourceAddress()
 {
     return(new SignalServiceAddress(UuidUtil.ParseOrNull(Envelope.SourceUuid), Envelope.SourceE164));
 }
        public DeviceContact?Read()
        {
            int detailsLength = ReadRawVarint32();

            if (detailsLength == -1)
            {
                return(null);
            }
            byte[] detailsSerialized = new byte[(int)detailsLength];
            Util.ReadFully(inputStream, detailsSerialized);

            var details = ContactDetails.Parser.ParseFrom(detailsSerialized);
            SignalServiceAddress address = new SignalServiceAddress(UuidUtil.ParseOrNull(details.Uuid), details.Number);
            string?name = details.Name;
            SignalServiceAttachmentStream?avatar = null;
            string?         color    = details.HasColor ? details.Color : null;
            VerifiedMessage?verified = null;

            byte[]? profileKey = null;
            bool blocked     = false;
            uint?expireTimer = null;

            if (details.Avatar != null)
            {
                long   avatarLength      = details.Avatar.Length;
                Stream avatarStream      = new LimitedInputStream(inputStream, avatarLength);
                string avatarContentType = details.Avatar.ContentType;
                avatar = new SignalServiceAttachmentStream(avatarStream, avatarContentType, avatarLength, null, false, null);
            }

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

                    VerifiedState state;
                    switch (details.Verified.State)
                    {
                    case Verified.Types.State.Verified:
                        state = VerifiedState.Verified;
                        break;

                    case Verified.Types.State.Unverified:
                        state = VerifiedState.Unverified;
                        break;

                    case Verified.Types.State.Default:
                        state = VerifiedState.Default;
                        break;

                    default:
                        throw new InvalidMessageException("Unknown state: " + details.Verified.State);
                    }

                    verified = new VerifiedMessage(destination, identityKey, state, Util.CurrentTimeMillis());
                }
                catch (Exception ex) when(ex is InvalidKeyException || ex is InvalidMessageException)
                {
                    logger.LogWarning(new EventId(), ex, "");
                    verified = null;
                }
            }

            if (details.HasProfileKey)
            {
                profileKey = details.ProfileKey.ToByteArray();
            }

            if (details.HasExpireTimer && details.ExpireTimer > 0)
            {
                expireTimer = details.ExpireTimer;
            }

            return(new DeviceContact(address, name, avatar, color, verified, profileKey, blocked, expireTimer));
        }
        private static SignalServiceGroup?CreateGroupV1Info(DataMessage content)
        {
            if (content.Group == null)
            {
                return(null);
            }

            var type = content.Group.Type switch
            {
                GroupContext.Types.Type.Deliver => SignalServiceGroup.GroupType.DELIVER,
                GroupContext.Types.Type.Update => SignalServiceGroup.GroupType.UPDATE,
                GroupContext.Types.Type.Quit => SignalServiceGroup.GroupType.QUIT,
                GroupContext.Types.Type.RequestInfo => SignalServiceGroup.GroupType.REQUEST_INFO,
                _ => SignalServiceGroup.GroupType.UNKNOWN,
            };

            if (content.Group.Type != GroupContext.Types.Type.Deliver)
            {
                string?name = null;
                List <SignalServiceAddress>?   members = null;
                SignalServiceAttachmentPointer?avatar  = null;

                if (content.Group.HasName)
                {
                    name = content.Group.Name;
                }

                if (content.Group.Members.Count > 0)
                {
                    members = new List <SignalServiceAddress>(content.Group.Members.Count);

                    foreach (GroupContext.Types.Member member in content.Group.Members)
                    {
                        if (SignalServiceAddress.IsValidAddress(member.Uuid, member.E164))
                        {
                            members.Add(new SignalServiceAddress(UuidUtil.ParseOrNull(member.Uuid), member.E164));
                        }
                        else
                        {
                            throw new ProtocolInvalidMessageException(new InvalidMessageException("GroupContext.Member had no address!"), null, 0);
                        }
                    }
                }
                else if (content.Group.MembersE164.Count > 0)
                {
                    members = new List <SignalServiceAddress>(content.Group.MembersE164.Count);

                    foreach (string member in content.Group.MembersE164)
                    {
                        members.Add(new SignalServiceAddress(null, member));
                    }
                }

                if (content.Group.Avatar != null)
                {
                    AttachmentPointer pointer = content.Group.Avatar;

                    avatar = new SignalServiceAttachmentPointer((int)pointer.CdnNumber,
                                                                SignalServiceAttachmentRemoteId.From(pointer) !,
                                                                pointer.ContentType,
                                                                pointer.Key.ToByteArray(),
                                                                pointer.HasSize ? pointer.Size : 0,
                                                                null,
                                                                0, 0,
                                                                pointer.HasDigest ? pointer.Digest.ToByteArray() : null,
                                                                null,
                                                                false,
                                                                null,
                                                                null,
                                                                pointer.HasUploadTimestamp ? (long)pointer.UploadTimestamp : 0);
                }

                return(new SignalServiceGroup(type, content.Group.Id.ToByteArray(), name, members, avatar));
            }

            return(new SignalServiceGroup(content.Group.Id.ToByteArray()));
        }
 public static bool IsValidAddress(string?rawUuid, string?e164)
 {
     return(!string.IsNullOrEmpty(e164) || UuidUtil.ParseOrNull(rawUuid) != null);
 }