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()); }
/// <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); }