Example #1
0
        private async Task deliver(TextMessageRecord message)
        {
            try
            {
                SignalServiceAddress     address           = getPushAddress(message.IndividualRecipient.Number);
                SignalServiceDataMessage textSecureMessage = SignalServiceDataMessage.newBuilder()
                                                             .withTimestamp(TimeUtil.GetUnixTimestampMillis(message.DateSent))
                                                             .withBody(message.Body.Body)
                                                             .asEndSessionMessage(message.IsEndSession)
                                                             .build();

                Debug.WriteLine("TextSendTask deliver");
                await messageSender.sendMessage(address, textSecureMessage);
            }
            catch (InvalidNumberException /*| UnregisteredUserException e*/)
            {
                //Log.w(TAG, e);
                //throw new InsecureFallbackApprovalException(e);
            }
            catch (Exception)
            {
                Log.Warn("Delivery of message failed");
                OnCanceled();
            }
        }
Example #2
0
        private void handleMediaMessage(SignalServiceEnvelope envelope, SignalServiceDataMessage message, May <long> smsMessageId) // throws MmsException
        {
            throw new NotImplementedException("handleMediaMessage");

            /*
             * var database = DatabaseFactory.getMediaMessageDatabase(); //getMmsDatabase(context);
             * String localNumber = TextSecurePreferences.getLocalNumber(context);
             * IncomingMediaMessage mediaMessage = new IncomingMediaMessage(masterSecret, envelope.getSource(),
             *                                                   localNumber, message.getTimestamp(),
             *                                                   Optional.fromNullable(envelope.getRelay()),
             *                                                   message.getBody(),
             *                                                   message.getGroupInfo(),
             *                                                   message.getAttachments());
             *
             * Pair<long, long> messageAndThreadId = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
             * List<DatabaseAttachment> attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(messageAndThreadId.first);
             *
             * for (DatabaseAttachment attachment : attachments)
             * {
             *  ApplicationContext.getInstance(context)
             *                    .getJobManager()
             *                    .add(new AttachmentDownloadJob(context, messageAndThreadId.first,
             *                                                   attachment.getAttachmentId()));
             * }
             *
             * if (smsMessageId.isPresent())
             * {
             *  DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
             * }
             *
             * MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second);*/
        }
Example #3
0
        private void handleEndSessionMessage(SignalServiceEnvelope envelope,
                                             SignalServiceDataMessage message,
                                             May <long> smsMessageId)
        {
            var smsDatabase         = DatabaseFactory.getTextMessageDatabase();//getEncryptingSmsDatabase(context);
            var incomingTextMessage = new IncomingTextMessage(envelope.getSource(),
                                                              envelope.getSourceDevice(),
                                                              message.getTimestamp(),
                                                              "", May <SignalServiceGroup> .NoValue);

            long threadId;

            if (!smsMessageId.HasValue)
            {
                IncomingEndSessionMessage incomingEndSessionMessage = new IncomingEndSessionMessage(incomingTextMessage);
                Pair <long, long>         messageAndThreadId        = smsDatabase.InsertMessageInbox(incomingEndSessionMessage);

                threadId = messageAndThreadId.second();
            }
            else
            {
                var messageId = smsMessageId.ForceGetValue();
                smsDatabase.MarkAsEndSession(messageId);
                threadId = smsDatabase.GetThreadIdForMessage(messageId);
            }

            SessionStore sessionStore = new TextSecureAxolotlStore();

            sessionStore.DeleteAllSessions(envelope.getSource());

            //SecurityEvent.broadcastSecurityUpdateEvent(context, threadId);
            //MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), threadId);
        }
 public SentTranscriptMessage(string destination, long timestamp, SignalServiceDataMessage message, long expirationStartTimestamp)
 {
     this.destination = new May <string>(destination);
     this.timestamp   = timestamp;
     this.message     = message;
     this.expirationStartTimestamp = expirationStartTimestamp;
 }
Example #5
0
 public SentTranscriptMessage(long timestamp, SignalServiceDataMessage message)
 {
     Destination = May.NoValue;
     Timestamp   = timestamp;
     Message     = message;
     ExpirationStartTimestamp = 0;
 }
 public SentTranscriptMessage(long timestamp, SignalServiceDataMessage message)
 {
     this.destination = May.NoValue;
     this.timestamp   = timestamp;
     this.message     = message;
     this.expirationStartTimestamp = 0;
 }
        public SentTranscriptMessage(SignalServiceAddress destination, long timestamp, SignalServiceDataMessage message,
                                     long expirationStartTimestamp, Dictionary <SignalServiceAddress, bool> unidentifiedStatus,
                                     bool isRecipientUpdate)
        {
            Destination = destination;
            Timestamp   = timestamp;
            Message     = message;
            ExpirationStartTimestamp = expirationStartTimestamp;
            UnidentifiedStatusByUuid = new Dictionary <string, bool>();
            UnidentifiedStatusByE164 = new Dictionary <string, bool>();
            Recipients        = new HashSet <SignalServiceAddress>(unidentifiedStatus.Keys);
            IsRecipientUpdate = isRecipientUpdate;

            foreach (var entry in unidentifiedStatus)
            {
                if (entry.Key.Uuid.HasValue)
                {
                    UnidentifiedStatusByUuid.Add(entry.Key.Uuid.Value.ToString(), entry.Value);
                }

                if (entry.Key.GetNumber() != null)
                {
                    UnidentifiedStatusByE164.Add(entry.Key.GetNumber() !, entry.Value);
                }
            }
        }
Example #8
0
 public SentTranscriptMessage(long timestamp, SignalServiceDataMessage message)
 {
     Destination = May.NoValue;
     Timestamp   = timestamp;
     Message     = message;
     ExpirationStartTimestamp = 0;
     UnidentifiedStatus       = new Dictionary <string, bool>();
 }
Example #9
0
        private void handleGroupMessage(SignalServiceEnvelope envelope, SignalServiceDataMessage message, May <long> smsMessageId)
        {
            //GroupMessageProcessor.process(envelope, message, false); // TODO: GROUP enable

            if (smsMessageId.HasValue)
            {
                DatabaseFactory.getTextMessageDatabase().DeleteThread(smsMessageId.ForceGetValue()); //getSmsDatabase(context).deleteMessage(smsMessageId.get());
            }
        }
Example #10
0
 public SentTranscriptMessage(string destination, long timestamp, SignalServiceDataMessage message,
                              long expirationStartTimestamp, Dictionary <string, bool> unidentifiedStatus)
 {
     Destination = new May <string>(destination);
     Timestamp   = timestamp;
     Message     = message;
     ExpirationStartTimestamp = expirationStartTimestamp;
     UnidentifiedStatus       = unidentifiedStatus;
 }
 public SentTranscriptMessage(long timestamp, SignalServiceDataMessage message)
 {
     Destination = null;
     Timestamp   = timestamp;
     Message     = message;
     ExpirationStartTimestamp = 0;
     UnidentifiedStatusByUuid = new Dictionary <string, bool>();
     UnidentifiedStatusByE164 = new Dictionary <string, bool>();
     Recipients        = new HashSet <SignalServiceAddress>();
     IsRecipientUpdate = false;
 }
Example #12
0
        private void handleTextMessage(/*@NonNull MasterSecretUnion masterSecret,*/
            SignalServiceEnvelope envelope,
            SignalServiceDataMessage message,
            May <long> smsMessageId)
        {
            var    textMessageDatabase = DatabaseFactory.getTextMessageDatabase();
            String body = message.getBody().HasValue ? message.getBody().ForceGetValue() : "";


            IncomingTextMessage textMessage = new IncomingTextMessage(envelope.getSource(),
                                                                      envelope.getSourceDevice(),
                                                                      message.getTimestamp(), body,
                                                                      message.getGroupInfo());

            textMessage = new IncomingEncryptedMessage(textMessage, body);
            var messageAndThreadId = textMessageDatabase.InsertMessageInbox(textMessage);

            ToastHelper.NotifyNewMessage(messageAndThreadId.second(), DatabaseFactory.getDirectoryDatabase().GetForNumber(envelope.getSource()).Name, body);
        }
Example #13
0
        /// <summary>
        /// Send a message to a group.
        /// </summary>
        /// <param name="recipients">The group members.</param>
        /// <param name="message">The group message.</param>
        public async Task sendMessage(List <SignalServiceAddress> recipients, SignalServiceDataMessage message)
        {
            byte[] content = await createMessageContent(message);

            long timestamp = message.getTimestamp();
            SendMessageResponse response = await sendMessage(recipients, timestamp, content, true);

            try
            {
                if (response != null && response.getNeedsSync())
                {
                    byte[] syncMessage = createMultiDeviceSentTranscriptContent(content, May <SignalServiceAddress> .NoValue, (ulong)timestamp);
                    await sendMessage(localAddress, timestamp, syncMessage, false, false);
                }
            }
            catch (UntrustedIdentityException e)
            {
                throw new EncapsulatedExceptions(e);
            }
        }
Example #14
0
        private byte[] createMessageContent(SignalServiceDataMessage message)// throws IOException
        {
            DataMessage dataMessage            = new DataMessage {
            };
            IList <AttachmentPointer> pointers = createAttachmentPointers(message.Attachments);

            if (pointers.Count != 0)
            {
                dataMessage.Attachments.AddRange(pointers);
            }

            if (message.Body != null)
            {
                dataMessage.Body = message.Body;
            }

            if (message.Group != null)
            {
                dataMessage.Group = createGroupContent(message.Group);
            }

            if (message.EndSession)
            {
                dataMessage.Flags = (uint)DataMessage.Types.Flags.EndSession;
            }

            if (message.ExpirationUpdate)
            {
                dataMessage.Flags = (uint)DataMessage.Types.Flags.ExpirationTimerUpdate;
            }

            if (message.ExpiresInSeconds > 0)
            {
                dataMessage.ExpireTimer = (uint)message.ExpiresInSeconds;
            }

            return(dataMessage.ToByteArray());
        }
Example #15
0
        /// <summary>
        /// Send a message to a single recipient.
        /// </summary>
        /// <param name="recipient">The message's destination.</param>
        /// <param name="message">The message.</param>
        public void sendMessage(SignalServiceAddress recipient, SignalServiceDataMessage message)
        {
            byte[] content   = createMessageContent(message);
            long   timestamp = message.Timestamp;
            bool   silent    = message.Group != null && message.Group.Type == SignalServiceGroup.GroupType.REQUEST_INFO;
            var    resp      = sendMessage(recipient, timestamp, content, true, silent);

            if (resp.needsSync)
            {
                byte[] syncMessage = createMultiDeviceSentTranscriptContent(content, new May <SignalServiceAddress>(recipient), (ulong)timestamp);
                sendMessage(localAddress, timestamp, syncMessage, false, false);
            }

            if (message.EndSession)
            {
                store.DeleteAllSessions(recipient.getNumber());

                if (eventListener != null)
                {
                    eventListener.onSecurityEvent(recipient);
                }
            }
        }
Example #16
0
        private async Task <byte[]> createMessageContent(SignalServiceDataMessage message)// throws IOException
        {
            DataMessage.Builder       builder  = DataMessage.CreateBuilder();
            IList <AttachmentPointer> pointers = await createAttachmentPointers(message.getAttachments());

            if (pointers.Count != 0)
            {
                builder.AddRangeAttachments(pointers);
            }

            if (message.getBody().HasValue)
            {
                builder.SetBody(message.getBody().ForceGetValue());
            }

            if (message.getGroupInfo().HasValue)
            {
                builder.SetGroup(await createGroupContent(message.getGroupInfo().ForceGetValue()));
            }

            if (message.isEndSession())
            {
                builder.SetFlags((uint)DataMessage.Types.Flags.END_SESSION);
            }

            if (message.isExpirationUpdate())
            {
                builder.SetFlags((uint)DataMessage.Types.Flags.EXPIRATION_TIMER_UPDATE);
            }

            if (message.getExpiresInSeconds() > 0)
            {
                builder.SetExpireTimer((uint)message.getExpiresInSeconds());
            }

            return(builder.Build().ToByteArray());
        }
Example #17
0
        /// <summary>
        /// Send a message to a single recipient.
        /// </summary>
        /// <param name="recipient">The message's destination.</param>
        /// <param name="message">The message.</param>
        public async Task sendMessage(SignalServiceAddress recipient, SignalServiceDataMessage message)
        {
            byte[] content = await createMessageContent(message);

            long timestamp = message.getTimestamp();
            bool silent    = message.getGroupInfo().HasValue&& message.getGroupInfo().ForceGetValue().getType() == SignalServiceGroup.Type.REQUEST_INFO;
            SendMessageResponse response = await sendMessage(recipient, timestamp, content, true, silent);

            if (response != null && response.getNeedsSync())
            {
                byte[] syncMessage = createMultiDeviceSentTranscriptContent(content, new May <SignalServiceAddress>(recipient), (ulong)timestamp);
                await sendMessage(localAddress, timestamp, syncMessage, false, false);
            }

            if (message.isEndSession())
            {
                store.DeleteAllSessions(recipient.getNumber());

                if (eventListener.HasValue)
                {
                    eventListener.ForceGetValue().onSecurityEvent(recipient);
                }
            }
        }
Example #18
0
        /// <summary>
        /// Send a message to a group.
        /// </summary>
        /// <param name="recipients">The group members.</param>
        /// <param name="message">The group message.</param>
        public void sendMessage(List <SignalServiceAddress> recipients, SignalServiceDataMessage message)
        {
            byte[] content   = createMessageContent(message);
            long   timestamp = message.Timestamp;
            SendMessageResponseList response = sendMessage(recipients, timestamp, content, true);

            try
            {
                if (response != null && response.NeedsSync)
                {
                    byte[] syncMessage = createMultiDeviceSentTranscriptContent(content, May <SignalServiceAddress> .NoValue, (ulong)timestamp);
                    sendMessage(localAddress, timestamp, syncMessage, false, false);
                }
            }
            catch (UntrustedIdentityException e)
            {
                response.UntrustedIdentities.Add(e);
            }

            if (response.HasExceptions())
            {
                throw new EncapsulatedExceptions(response.UntrustedIdentities, response.UnregisteredUsers, response.NetworkExceptions);
            }
        }
Example #19
0
 public SignalServiceDataMessageSendable(SignalServiceDataMessage dataMessage, SignalServiceAddress recipient)
 {
     DataMessage = dataMessage;
     Recipient   = recipient;
 }
        /// <summary>
        /// Send a message to a group.
        /// </summary>
        /// <param name="token">The cancellation token</param>
        /// <param name="recipients">The group members.</param>
        /// <param name="unidentifiedAccess"></param>
        /// <param name="message">The group message.</param>
        public async Task <List <SendMessageResult> > SendMessage(CancellationToken token, List <SignalServiceAddress> recipients,
                                                                  List <UnidentifiedAccessPair?> unidentifiedAccess, SignalServiceDataMessage message)
        {
            byte[] content = await CreateMessageContent(token, message);

            long timestamp = message.Timestamp;
            List <SendMessageResult> results = await SendMessage(token, recipients, GetTargetUnidentifiedAccess(unidentifiedAccess), timestamp, content);

            bool needsSyncInResults = false;

            foreach (var result in results)
            {
                if (result.Success != null && result.Success.NeedsSync)
                {
                    needsSyncInResults = true;
                    break;
                }
            }
            if (needsSyncInResults || IsMultiDevice)
            {
                byte[] syncMessage = CreateMultiDeviceSentTranscriptContent(content, null, (ulong)timestamp, results);
                await SendMessage(token, LocalAddress, GetSelfUnidentifiedAccess(unidentifiedAccess), timestamp, syncMessage);
            }
            return(results);
        }
        /// <summary>
        /// Send a message to a single recipient.
        /// </summary>
        /// <param name="token">The cancellation token</param>
        /// <param name="recipient">The message's destination.</param>
        /// <param name="unidentifiedAccess"></param>
        /// <param name="message">The message.</param>
        public async Task <SendMessageResult> SendMessage(CancellationToken token, SignalServiceAddress recipient,
                                                          UnidentifiedAccessPair?unidentifiedAccess, SignalServiceDataMessage message)
        {
            byte[] content = await CreateMessageContent(token, message);

            long timestamp           = message.Timestamp;
            SendMessageResult result = await SendMessage(token, recipient, unidentifiedAccess?.TargetUnidentifiedAccess, timestamp, content);

            if ((result.Success != null && result.Success.NeedsSync) || (unidentifiedAccess != null && IsMultiDevice))
            {
                byte[] syncMessage = CreateMultiDeviceSentTranscriptContent(content, recipient, (ulong)timestamp, new List <SendMessageResult>()
                {
                    result
                });
                await SendMessage(token, LocalAddress, unidentifiedAccess?.SelfUnidentifiedAccess, timestamp, syncMessage);
            }

            if (message.EndSession)
            {
                Store.DeleteAllSessions(recipient.E164number);

                if (EventListener != null)
                {
                    EventListener.OnSecurityEvent(recipient);
                }
            }
            return(result);
        }
Example #22
0
        private void HandleMessage(SignalServiceEnvelope envelope)
        {
            var  cipher    = new SignalServiceCipher(new SignalServiceAddress(App.Store.Username), new Store());
            var  content   = cipher.decrypt(envelope);
            long timestamp = Util.CurrentTimeMillis();

            if (content.Message != null)
            {
                SignalServiceDataMessage message = content.Message;
                if (message.EndSession)
                {
                    HandleSessionResetMessage(envelope, content, message, false, timestamp);
                }
                else if (message.IsGroupUpdate())
                {
                    if (message.Group.Type == SignalServiceGroup.GroupType.UPDATE)
                    {
                        HandleGroupUpdateMessage(envelope, content, message, false, timestamp);
                    }
                }
                else if (message.ExpirationUpdate)
                {
                    HandleExpirationUpdateMessage(envelope, content, message, false, timestamp);
                }
                else
                {
                    HandleSignalMessage(envelope, content, message, false, timestamp);
                }
            }
            else if (content.SynchronizeMessage != null)
            {
                if (content.SynchronizeMessage.getSent().HasValue)
                {
                    var syncMessage = content.SynchronizeMessage.getSent().ForceGetValue();
                    var dataMessage = syncMessage.getMessage();

                    if (dataMessage.EndSession)
                    {
                        HandleSessionResetMessage(envelope, content, dataMessage, true, timestamp);
                    }
                    else if (dataMessage.IsGroupUpdate())
                    {
                        if (dataMessage.Group.Type == SignalServiceGroup.GroupType.UPDATE)
                        {
                            HandleGroupUpdateMessage(envelope, content, dataMessage, true, timestamp);
                        }
                    }
                    else if (dataMessage.ExpirationUpdate)
                    {
                        HandleExpirationUpdateMessage(envelope, content, dataMessage, true, timestamp);
                    }
                    else
                    {
                        HandleSignalMessage(envelope, content, dataMessage, true, timestamp);
                    }
                }
                else if (content.SynchronizeMessage.getRead().HasValue)
                {
                    var readMessages = content.SynchronizeMessage.getRead().ForceGetValue();
                    foreach (var readMessage in readMessages)
                    {
                        //TODO
                    }
                }
            } //TODO callmessages
            else
            {
                Debug.WriteLine("HandleMessage got unrecognized message from " + envelope.getSource());
            }
        }
Example #23
0
        private void HandleSignalMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp)
        {
            SignalMessageDirection type;
            SignalContact          author;
            SignalMessageStatus    status;
            string threadId;
            long   composedTimestamp;
            string body = dataMessage.Body != null ? dataMessage.Body : "";

            if (dataMessage.Group != null)
            {
                var rawId = dataMessage.Group.GroupId;
                threadId = Base64.encodeBytes(rawId);
                var g = SignalDBContext.GetOrCreateGroupLocked(threadId, timestamp, this);
                if (!g.CanReceive)
                {
                    SignalServiceGroup group = new SignalServiceGroup()
                    {
                        Type    = SignalServiceGroup.GroupType.REQUEST_INFO,
                        GroupId = rawId
                    };
                    SignalServiceDataMessage requestInfoMessage = new SignalServiceDataMessage()
                    {
                        Group     = group,
                        Timestamp = Util.CurrentTimeMillis()
                    };
                    MessageSender.sendMessage(envelope.getSourceAddress(), requestInfoMessage);
                }
                composedTimestamp = envelope.getTimestamp();
            }
            else
            {
                if (isSync)
                {
                    var sent = content.SynchronizeMessage.getSent().ForceGetValue();
                    threadId          = SignalDBContext.GetOrCreateContactLocked(sent.getDestination().ForceGetValue(), timestamp, this).ThreadId;
                    composedTimestamp = sent.getTimestamp();
                }
                else
                {
                    threadId          = SignalDBContext.GetOrCreateContactLocked(envelope.getSource(), timestamp, this).ThreadId;
                    composedTimestamp = envelope.getTimestamp();
                }
            }

            if (isSync)
            {
                type   = SignalMessageDirection.Synced;
                status = SignalMessageStatus.Confirmed;
                author = null;
            }
            else
            {
                status = 0;
                type   = SignalMessageDirection.Incoming;
                author = SignalDBContext.GetOrCreateContactLocked(envelope.getSource(), timestamp, this);
            }

            List <SignalAttachment> attachments = new List <SignalAttachment>();
            SignalMessage           message     = new SignalMessage()
            {
                Direction = type,
                Status    = status,
                Author    = author,
                Content   = new SignalMessageContent()
                {
                    Content = body
                },
                ThreadId          = threadId,
                DeviceId          = (uint)envelope.getSourceDevice(),
                Receipts          = 0,
                ComposedTimestamp = composedTimestamp,
                ReceivedTimestamp = timestamp,
                AttachmentsCount  = (uint)attachments.Count,
                Attachments       = attachments
            };

            if (dataMessage.Attachments != null)
            {
                var receivedAttachments = dataMessage.Attachments;
                foreach (var receivedAttachment in receivedAttachments)
                {
                    var pointer         = receivedAttachment.asPointer();
                    SignalAttachment sa = new SignalAttachment()
                    {
                        Message      = message,
                        Status       = (uint)SignalAttachmentStatus.Default,
                        SentFileName = pointer.FileName,
                        ContentType  = "",
                        Key          = pointer.Key,
                        Relay        = pointer.Relay,
                        StorageId    = pointer.Id
                    };
                    attachments.Add(sa);
                }
            }
            Debug.WriteLine("received message: " + message.Content);
            if (type == SignalMessageDirection.Incoming)
            {
                if (App.WindowActive)
                {
                    Utils.TryVibrate(true);
                }
                else
                {
                    SendTileNotification(message);
                    SendMessageNotification(message);
                }
            }
            Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() =>
            {
                await UIHandleIncomingMessage(message);
            }).AsTask().Wait();
        }
Example #24
0
        private void HandleGroupUpdateMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp)
        {
            if (dataMessage.Group != null) //TODO check signal droid: group messages have different types!
            {
                SignalServiceGroup group       = dataMessage.Group;
                string             groupid     = Base64.encodeBytes(group.GroupId);
                SignalGroup        g           = new SignalGroup();
                string             displayname = "Unknown group";
                string             avatarfile  = null;
                if (group.Name != null)
                {
                    displayname = group.Name;
                }
                var dbgroup = SignalDBContext.InsertOrUpdateGroupLocked(groupid, displayname, avatarfile, true, timestamp, this);
                if (group.Members != null)
                {
                    foreach (var member in group.Members)
                    {
                        SignalDBContext.InsertOrUpdateGroupMembershipLocked(dbgroup.Id, SignalDBContext.GetOrCreateContactLocked(member, 0, this).Id);
                    }
                }

                /* insert message into conversation */
                SignalMessageDirection type;
                SignalContact          author;
                SignalMessageStatus    status;
                string prefix;
                long   composedTimestamp;

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

                SignalMessage sm = new SignalMessage()
                {
                    Direction = type,
                    Type      = SignalMessageType.GroupUpdate,
                    Status    = status,
                    Author    = author,
                    Content   = new SignalMessageContent()
                    {
                        Content = $"{prefix} updated the group."
                    },
                    ThreadId          = groupid,
                    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();
            }
            else
            {
                Debug.WriteLine("received group update without group info!");
            }
        }
Example #25
0
        private async Task HandleSignalMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp)
        {
            SignalMessageDirection type;
            SignalContact          author;
            SignalMessageStatus    status;
            SignalConversation     conversation;
            long   composedTimestamp;
            string body = dataMessage.Body ?? "";

            if (dataMessage.Group != null)
            {
                var rawId    = dataMessage.Group.GroupId;
                var threadId = Base64.EncodeBytes(rawId);
                conversation = await SignalDBContext.GetOrCreateGroupLocked(threadId, timestamp);

                if (!conversation.CanReceive)
                {
                    SignalServiceGroup group = new SignalServiceGroup()
                    {
                        Type    = SignalServiceGroup.GroupType.REQUEST_INFO,
                        GroupId = rawId
                    };
                    SignalServiceDataMessage requestInfoMessage = new SignalServiceDataMessage()
                    {
                        Group     = group,
                        Timestamp = Util.CurrentTimeMillis()
                    };
                    SignalLibHandle.Instance.OutgoingQueue.Add(new SignalServiceDataMessageSendable(requestInfoMessage, envelope.GetSourceAddress()));
                }
                composedTimestamp = envelope.GetTimestamp();
            }
            else
            {
                if (isSync)
                {
                    var sent = content.SynchronizeMessage.Sent;
                    conversation = await SignalDBContext.GetOrCreateContactLocked(sent.Destination.ForceGetValue(), timestamp);

                    composedTimestamp = sent.Timestamp;
                }
                else
                {
                    conversation = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp);

                    composedTimestamp = envelope.GetTimestamp();
                }
            }

            if (isSync)
            {
                type   = SignalMessageDirection.Synced;
                status = SignalMessageStatus.Confirmed;
                author = null;
            }
            else
            {
                status = 0;
                type   = SignalMessageDirection.Incoming;
                author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp);
            }

            if (author != null && author.Blocked)
            {
                // Don't save blocked messages
                return;
            }

            List <SignalAttachment> attachments = new List <SignalAttachment>();
            SignalMessage           message     = new SignalMessage()
            {
                Direction = type,
                Status    = status,
                Author    = author,
                Content   = new SignalMessageContent()
                {
                    Content = body.Truncate(2000)
                },
                ThreadId          = conversation.ThreadId,
                DeviceId          = (uint)envelope.GetSourceDevice(),
                Receipts          = 0,
                ComposedTimestamp = composedTimestamp,
                ReceivedTimestamp = timestamp,
                AttachmentsCount  = (uint)attachments.Count,
                Attachments       = attachments
            };

            if (dataMessage.Attachments != null)
            {
                var receivedAttachments = dataMessage.Attachments;
                foreach (var receivedAttachment in receivedAttachments)
                {
                    var pointer         = receivedAttachment.AsPointer();
                    SignalAttachment sa = new SignalAttachment()
                    {
                        Message      = message,
                        Status       = (uint)SignalAttachmentStatus.Default,
                        SentFileName = pointer.FileName,
                        ContentType  = receivedAttachment.ContentType,
                        Key          = pointer.Key,
                        Relay        = pointer.Relay,
                        StorageId    = pointer.Id,
                        Size         = (long)pointer.Size,
                        Digest       = pointer.Digest
                    };
                    attachments.Add(sa);
                }

                // Make sure to update attachments count
                message.AttachmentsCount = (uint)attachments.Count;
            }
            await SignalLibHandle.Instance.SaveAndDispatchSignalMessage(message, null, conversation);
        }
Example #26
0
        private async Task HandleGroupUpdateMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp)
        {
            if (dataMessage.Group != null) //TODO check signal droid: group messages have different types!
            {
                SignalServiceGroup group       = dataMessage.Group;
                string             groupid     = Base64.EncodeBytes(group.GroupId);
                SignalGroup        g           = new SignalGroup();
                string             displayname = "Unknown group";
                string             avatarfile  = null;
                if (group.Name != null)
                {
                    displayname = group.Name;
                }
                var dbgroup = SignalDBContext.InsertOrUpdateGroupLocked(groupid, displayname, avatarfile, true, timestamp);
                if (group.Members != null)
                {
                    foreach (var member in group.Members)
                    {
                        SignalDBContext.InsertOrUpdateGroupMembershipLocked(dbgroup.Id, (await SignalDBContext.GetOrCreateContactLocked(member, 0)).Id);
                    }
                }

                /* insert message into conversation */
                SignalMessageDirection type;
                SignalContact          author;
                SignalMessageStatus    status;
                string prefix;
                long   composedTimestamp;

                if (isSync)
                {
                    var sent = content.SynchronizeMessage.Sent;
                    type              = SignalMessageDirection.Synced;
                    status            = SignalMessageStatus.Confirmed;
                    composedTimestamp = sent.Timestamp;
                    author            = null;
                    prefix            = "You have";
                }
                else
                {
                    status = 0;
                    type   = SignalMessageDirection.Incoming;
                    author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp);

                    prefix            = $"{author.ThreadDisplayName} has";
                    composedTimestamp = envelope.GetTimestamp();
                }

                SignalMessage sm = new SignalMessage()
                {
                    Direction = type,
                    Type      = SignalMessageType.GroupUpdate,
                    Status    = status,
                    Author    = author,
                    Content   = new SignalMessageContent()
                    {
                        Content = $"{prefix} updated the group."
                    },
                    ThreadId          = groupid,
                    DeviceId          = (uint)envelope.GetSourceDevice(),
                    Receipts          = 0,
                    ComposedTimestamp = composedTimestamp,
                    ReceivedTimestamp = timestamp,
                };
                SignalDBContext.SaveMessageLocked(sm);
                dbgroup.MessagesCount += 1;
                if (sm.Direction == SignalMessageDirection.Incoming)
                {
                    dbgroup.UnreadCount += 1;
                }
                else
                {
                    dbgroup.UnreadCount          = 0;
                    dbgroup.LastSeenMessageIndex = dbgroup.MessagesCount;
                }
                dbgroup.LastMessage = sm;
                await SignalLibHandle.Instance.DispatchAddOrUpdateConversation(dbgroup, sm);
            }
            else
            {
                Logger.LogError("HandleGroupUpdateMessage() received group update without group info");
            }
        }
Example #27
0
        private async Task HandleGroupLeaveMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp)
        {
            SignalServiceGroup sentGroup = dataMessage.Group;

            if (sentGroup != null)
            {
                string      groupid = Base64.EncodeBytes(sentGroup.GroupId);
                SignalGroup group   = await SignalDBContext.GetOrCreateGroupLocked(groupid, 0);

                if (isSync)
                {
                    SignalContact author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), 0);

                    SignalMessage sm = new SignalMessage()
                    {
                        Direction = SignalMessageDirection.Incoming,
                        Type      = SignalMessageType.GroupLeave,
                        Status    = SignalMessageStatus.Received,
                        Author    = author,
                        Content   = new SignalMessageContent()
                        {
                            Content = $"You have left the group."
                        },
                        ThreadId          = groupid,
                        DeviceId          = (uint)envelope.GetSourceDevice(),
                        Receipts          = 0,
                        ComposedTimestamp = envelope.GetTimestamp(),
                        ReceivedTimestamp = timestamp,
                    };
                    SignalConversation updatedConversation = SignalDBContext.RemoveMemberFromGroup(groupid, author, sm);
                    await SignalLibHandle.Instance.DispatchAddOrUpdateConversation(updatedConversation, sm);
                }
                else
                {
                    SignalContact author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), 0);

                    SignalMessage sm = new SignalMessage()
                    {
                        Direction = SignalMessageDirection.Incoming,
                        Type      = SignalMessageType.GroupLeave,
                        Status    = SignalMessageStatus.Received,
                        Author    = author,
                        Content   = new SignalMessageContent()
                        {
                            Content = $"{author.ThreadDisplayName} has left the group."
                        },
                        ThreadId          = groupid,
                        DeviceId          = (uint)envelope.GetSourceDevice(),
                        Receipts          = 0,
                        ComposedTimestamp = envelope.GetTimestamp(),
                        ReceivedTimestamp = timestamp,
                    };
                    SignalConversation updatedConversation = SignalDBContext.RemoveMemberFromGroup(groupid, author, sm);
                    await SignalLibHandle.Instance.DispatchAddOrUpdateConversation(updatedConversation, sm);
                }
            }
            else
            {
                Logger.LogError("HandleGroupLeaveMessage() received group update without group info");
            }
        }
Example #28
0
        /// <summary>
        /// Send a message to a single recipient.
        /// </summary>
        /// <param name="token">The cancellation token</param>
        /// <param name="recipient">The message's destination.</param>
        /// <param name="message">The message.</param>
        public async Task SendMessage(CancellationToken token, SignalServiceAddress recipient, SignalServiceDataMessage message)
        {
            byte[] content = await CreateMessageContent(token, message);

            long timestamp = message.Timestamp;
            bool silent    = message.Group != null && message.Group.Type == SignalServiceGroup.GroupType.REQUEST_INFO;
            var  resp      = await SendMessage(token, recipient, timestamp, content, silent);

            if (resp.NeedsSync)
            {
                byte[] syncMessage = CreateMultiDeviceSentTranscriptContent(content, new May <SignalServiceAddress>(recipient), (ulong)timestamp);
                await SendMessage(token, localAddress, timestamp, syncMessage, false);
            }

            if (message.EndSession)
            {
                store.DeleteAllSessions(recipient.E164number);

                if (eventListener != null)
                {
                    eventListener.OnSecurityEvent(recipient);
                }
            }
        }
Example #29
0
        private async Task <byte[]> CreateMessageContent(CancellationToken token, SignalServiceDataMessage message)// throws IOException
        {
            Content     content                = new Content();
            DataMessage dataMessage            = new DataMessage {
            };
            IList <AttachmentPointer> pointers = await CreateAttachmentPointers(token, message.Attachments);

            if (pointers.Count != 0)
            {
                dataMessage.Attachments.AddRange(pointers);
            }

            if (message.Body != null)
            {
                dataMessage.Body = message.Body;
            }

            if (message.Group != null)
            {
                dataMessage.Group = await CreateGroupContent(token, message.Group);
            }

            if (message.EndSession)
            {
                dataMessage.Flags = (uint)DataMessage.Types.Flags.EndSession;
            }

            if (message.ExpirationUpdate)
            {
                dataMessage.Flags = (uint)DataMessage.Types.Flags.ExpirationTimerUpdate;
            }

            if (message.ExpiresInSeconds > 0)
            {
                dataMessage.ExpireTimer = (uint)message.ExpiresInSeconds;
            }

            if (message.ProfileKey != null)
            {
                dataMessage.ProfileKey = ByteString.CopyFrom(message.ProfileKey);
            }

            if (message.Quote != null)
            {
                var quote = new DataMessage.Types.Quote()
                {
                    Id     = (ulong)message.Quote.Id,
                    Author = message.Quote.Author.E164number,
                    Text   = message.Quote.Text
                };
                foreach (SignalServiceQuotedAttachment attachment in message.Quote.Attachments)
                {
                    QuotedAttachment protoAttachment = new QuotedAttachment()
                    {
                        ContentType = attachment.ContentType
                    };
                    if (attachment.FileName != null)
                    {
                        protoAttachment.FileName = attachment.FileName;
                    }

                    if (attachment.Thumbnail != null)
                    {
                        protoAttachment.Thumbnail = await CreateAttachmentPointer(token, attachment.Thumbnail.AsStream());
                    }
                    quote.Attachments.Add(protoAttachment);
                }
                dataMessage.Quote = quote;
            }

            dataMessage.Timestamp = (ulong)message.Timestamp;

            content.DataMessage = dataMessage;
            return(content.ToByteArray());
        }
Example #30
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();
        }