Example #1
0
        private void OnNewRoosterMessage(IMessageSender sender, NewValidMessageEventArgs args)
        {
            if (args.MESSAGE is RosterResultMessage msg && sender is XMPPClient xmppClient)
            {
                string type = msg.TYPE;
                if (!string.Equals(type, IQMessage.RESULT) && !string.Equals(type, IQMessage.SET))
                {
                    // No roster result or set => return
                    return;
                }

                SemaLock semaLock             = DataCache.INSTANCE.NewChatSemaLock();
                IEnumerable <ChatModel> chats = DataCache.INSTANCE.GetChats(client.dbAccount.bareJid, semaLock);

                // TYPE == SET is being send by the server when the roster changes from outside:
                if (string.Equals(type, IQMessage.RESULT))
                {
                    foreach (ChatModel chat in chats)
                    {
                        chat.inRoster = false;
                    }
                }

                List <ChatModel> addedChats   = new List <ChatModel>();
                List <ChatModel> updatedChats = new List <ChatModel>();

                foreach (RosterItem item in msg.ITEMS)
                {
                    ChatModel chat = chats.Where(c => string.Equals(c.bareJid, item.JID)).FirstOrDefault();
                    if (!(chat is null))
                    {
                        chat.inRoster = !string.Equals(item.SUBSCRIPTION, "remove");
                        updatedChats.Add(chat);
                    }
Example #2
0
 //--------------------------------------------------------Events:---------------------------------------------------------------------\\
 #region --Events--
 private async void OnNewValidMessage(IMessageSender sender, NewValidMessageEventArgs args)
 {
     if (args.MESSAGE is OmemoDeviceListEventMessage eventMsg)
     {
         await onOmemoDeviceListEventMessageAsync(eventMsg);
     }
 }
Example #3
0
 private async void OnNewValidMessage(IMessageSender sender, NewValidMessageEventArgs args)
 {
     if (args.MESSAGE is MUCErrorMessage)
     {
         await OnMucErrorMessageAsync((XMPPClient)sender, args.MESSAGE as MUCErrorMessage);
     }
 }
Example #4
0
        protected override async Task processMessageAsync(NewValidMessageEventArgs args)
        {
            if (!STREAM_MANAGEMENT_ENABLED)
            {
                return;
            }

            AbstractMessage msg = args.MESSAGE;

            switch (state)
            {
            case SMState.DISABLED:
                if (msg is StreamFeaturesMessage || msg is OpenStreamAnswerMessage)
                {
                    StreamFeaturesMessage features = null;
                    if (msg is OpenStreamAnswerMessage)
                    {
                        features = (msg as OpenStreamAnswerMessage).getStreamFeaturesMessage();
                    }
                    else
                    {
                        features = msg as StreamFeaturesMessage;
                    }

                    if (features is null)
                    {
                        return;
                    }
                    if (features.containsFeature("sm"))
                    {
                        setMessageProcessed(args);
                        SMEnableMessage enableMsg = new SMEnableMessage();
                        await XMPP_CONNECTION.sendAsync(enableMsg, true);

                        serverSMEnabled = true;
                        state           = SMState.REQUESTED;
                    }
                }
                break;

            case SMState.REQUESTED:
                if (msg is SMEnableMessage enableAnswMsg)
                {
                    setMessageProcessed(args);
                    // Update connection information:
                    state           = SMState.ENABLED;
                    clientSMEnabled = true;
                    stopListeningForMessages();
                }
                else if (msg is SMFailedMessage failedMsg)
                {
                    setMessageProcessed(args);

                    // Handle errors:
                    state = SMState.ERROR;
                    stopListeningForMessages();
                }
                break;
            }
        }
Example #5
0
        protected async override Task processMessageAsync(NewValidMessageEventArgs args)
        {
            AbstractMessage msg = args.MESSAGE;

            if (state == RecourceBindingState.BOUND || state == RecourceBindingState.ERROR || msg.isProcessed())
            {
                return;
            }
            switch (state)
            {
            case RecourceBindingState.UNBOUND:
                if (msg is StreamFeaturesMessage || msg is OpenStreamAnswerMessage)
                {
                    StreamFeaturesMessage features;
                    if (msg is OpenStreamAnswerMessage)
                    {
                        features = (msg as OpenStreamAnswerMessage).getStreamFeaturesMessage();
                    }
                    else
                    {
                        features = msg as StreamFeaturesMessage;
                    }

                    if (features is null)
                    {
                        return;
                    }
                    if (features.containsFeature("bind"))
                    {
                        setMessageProcessed(args);
                        BindResourceMessage bindMsg = new BindResourceMessage(XMPP_CONNECTION.account.user.resourcePart);
                        id = bindMsg.ID;
                        await XMPP_CONNECTION.SendAsync(bindMsg, true);

                        state = RecourceBindingState.BINDING;
                    }
                }
                break;

            case RecourceBindingState.BINDING:
                if (msg is IQMessage)
                {
                    IQMessage iQM = msg as IQMessage;
                    if (string.Equals(iQM.ID, id))
                    {
                        stopListeningForMessages();
                        setMessageProcessed(args);
                        XMPP_CONNECTION.SendAsync(new StartSessionMessage(), true).Wait();
                        state = RecourceBindingState.BOUND;
                        ResourceBound?.Invoke(this, new EventArgs());
                    }
                }
                break;
            }
        }
Example #6
0
        private void Connection_ConnectionNewValidMessage(IMessageSender connection, NewValidMessageEventArgs args)
        {
            AbstractMessage msg = args.MESSAGE;

            if (msg is MessageMessage mMsg)
            {
                NewChatMessage?.Invoke(this, new NewChatMessageEventArgs(mMsg));
            }
            else if (msg is ChatStateMessage sMsg)
            {
                NewChatState?.Invoke(this, new NewChatStateEventArgs(sMsg));
            }
            else if (msg is DeliveryReceiptMessage dRMsg)
            {
                NewDeliveryReceipt?.Invoke(this, new NewDeliveryReceiptEventArgs(dRMsg));
            }

            NewValidMessage?.Invoke(this, args);
        }
Example #7
0
        protected async override Task processMessageAsync(NewValidMessageEventArgs args)
        {
            AbstractMessage msg = args.MESSAGE;

            if (msg.isProcessed())
            {
                return;
            }

            switch (state)
            {
            case SASLState.DISCONNECTED:
                if (msg is StreamFeaturesMessage || msg is OpenStreamAnswerMessage)
                {
                    StreamFeaturesMessage features = null;
                    if (msg is OpenStreamAnswerMessage)
                    {
                        features = (msg as OpenStreamAnswerMessage).getStreamFeaturesMessage();
                    }
                    else
                    {
                        features = msg as StreamFeaturesMessage;
                    }

                    if (features is null)
                    {
                        return;
                    }

                    ArrayList mechanisms = getMechanisms(features);
                    if (mechanisms is null)
                    {
                        return;
                    }
                    setMessageProcessed(args);
                    selectMechanism(mechanisms);
                    if (selectedMechanism is null)
                    {
                        state = SASLState.ERROR;
                        await XMPP_CONNECTION.OnMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.SASL_FAILED, "selectedMechanism is null"), true);

                        return;
                    }
                    await XMPP_CONNECTION.SendAsync(selectedMechanism.getSelectSASLMechanismMessage(), true);

                    state = SASLState.REQUESTED;
                }
                break;

            case SASLState.REQUESTED:
            case SASLState.CHALLENGING:
                if (msg is ScramSHAChallengeMessage)
                {
                    state = SASLState.CHALLENGING;
                    setMessageProcessed(args);
                    AbstractMessage response = selectedMechanism.generateResponse(msg);
                    if (!(response is null))
                    {
                        await XMPP_CONNECTION.SendAsync(response, true);
                    }
                }
                else if (msg is SASLSuccessMessage)
                {
                    state = SASLState.CONNECTED;
                    msg.setRestartConnection(AbstractMessage.SOFT_RESTART);
                    setMessageProcessed(args);
                    stopListeningForMessages();
                }
                else if (msg is SASLFailureMessage)
                {
                    stopListeningForMessages();
                    SASLFailureMessage saslFailureMessage = msg as SASLFailureMessage;
                    state = SASLState.ERROR;

                    Logger.Error("Error during SASL authentication: " + saslFailureMessage.ERROR_TYPE + "\n" + saslFailureMessage.ERROR_MESSAGE);
                    if (saslFailureMessage.ERROR_TYPE == SASLErrorType.UNKNOWN_ERROR)
                    {
                        await XMPP_CONNECTION.OnMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.SASL_FAILED, "SASL: " + saslFailureMessage.ERROR_MESSAGE), true);
                    }
                    else
                    {
                        await XMPP_CONNECTION.OnMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.SASL_FAILED, "SASL: " + saslFailureMessage.ERROR_TYPE), true);
                    }
                }
                break;

            case SASLState.CONNECTED:
                break;

            default:
                throw new InvalidOperationException("Unexpected value for state: " + state);
            }
        }
        private void C_NewRoosterMessage(IMessageSender sender, NewValidMessageEventArgs args)
        {
            if (args.MESSAGE is RosterResultMessage msg && sender is XMPPClient client)
            {
                string to   = client.getXMPPAccount().getBareJid();
                string type = msg.TYPE;

                if (string.Equals(type, IQMessage.RESULT))
                {
                    ChatDBManager.INSTANCE.setAllNotInRoster(client.getXMPPAccount().getBareJid());
                }
                else if (!string.Equals(type, IQMessage.SET))
                {
                    // No roster result or set => return
                    return;
                }

                foreach (RosterItem item in msg.ITEMS)
                {
                    string    from = item.JID;
                    string    id   = ChatTable.generateId(from, to);
                    ChatTable chat = ChatDBManager.INSTANCE.getChat(id);
                    if (chat != null)
                    {
                        chat.inRoster = !string.Equals(item.SUBSCRIPTION, "remove");
                    }
                    else if (!string.Equals(item.SUBSCRIPTION, "remove"))
                    {
                        chat = new ChatTable(from, to)
                        {
                            inRoster = true,
                            chatType = ChatType.CHAT
                        };
                    }
                    else
                    {
                        continue;
                    }

                    // Only update the subscription state, if not set to subscribe:
                    if (!string.Equals(chat.subscription, "subscribe"))
                    {
                        chat.subscription = item.SUBSCRIPTION;
                    }
                    chat.subscriptionRequested = string.Equals(item.ASK, "subscribe");

                    switch (chat.subscription)
                    {
                    case "unsubscribe":
                    case "from":
                    case "none":
                    case "pending":
                    case null:
                        chat.presence = Presence.Unavailable;
                        break;

                    default:
                        break;
                    }

                    ChatDBManager.INSTANCE.setChat(chat, false, true);
                }
            }
        }
Example #9
0
        protected async override Task processMessageAsync(NewValidMessageEventArgs args)
        {
            AbstractMessage msg = args.MESSAGE;

            if (msg.isProcessed())
            {
                return;
            }
            if ((state == TLSState.CONNECTING || state == TLSState.REQUESTED) && msg is ErrorMessage)
            {
                setMessageProcessed(args);
                setState(TLSState.ERROR);
                ErrorMessage error = msg as ErrorMessage;
                if (error.getType().Equals(Consts.XML_FAILURE))
                {
                    error.setRestartConnection(AbstractMessage.HARD_RESTART);
                }
                return;
            }
            switch (state)
            {
            case TLSState.DISCONNECTED:
            case TLSState.CONNECTING:
                if (msg is OpenStreamAnswerMessage)
                {
                    StreamFeaturesMessage features = (msg as OpenStreamAnswerMessage).getStreamFeaturesMessage();
                    if (features != null)
                    {
                        await streamFeaturesMessageReceivedAsync(features, args);
                    }
                }
                else if (msg is StreamFeaturesMessage)
                {
                    await streamFeaturesMessageReceivedAsync(msg as StreamFeaturesMessage, args);
                }
                break;

            case TLSState.REQUESTED:
                if (msg is ProceedAnswerMessage)
                {
                    setMessageProcessed(args);

                    XMPPAccount account = XMPP_CONNECTION.account;
                    Logger.Debug("Upgrading " + account.getBareJid() + " connection to TLS...");
                    try
                    {
                        TCP_CONNECTION.upgradeToTLSAsync().Wait();
                    }
                    catch (AggregateException e)
                    {
                        if (e.InnerException is TaskCanceledException)
                        {
                            Logger.Error("Timeout during upgrading " + account.getBareJid() + " to TLS!", e);
                            setState(TLSState.ERROR);
                            await XMPP_CONNECTION.onMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.TLS_CONNECTION_FAILED, "TSL upgrading timeout!"), true);

                            return;
                        }
                        else
                        {
                            Logger.Error("Error during upgrading " + account.getBareJid() + " to TLS!", e.InnerException);
                            setState(TLSState.ERROR);
                            await XMPP_CONNECTION.onMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.TLS_CONNECTION_FAILED, e.InnerException?.Message), true);

                            return;
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error("Error during upgrading " + account.getBareJid() + " to TLS!", e);
                        setState(TLSState.ERROR);
                        await XMPP_CONNECTION.onMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.TLS_CONNECTION_FAILED, e.Message), true);

                        return;
                    }

                    Logger.Debug("Success upgrading " + account.getBareJid() + " to TLS.");

                    setState(TLSState.CONNECTED);
                    stopListeningForMessages();

                    // TLS established ==> resend stream header
                    msg.setRestartConnection(AbstractMessage.SOFT_RESTART);
                }
                break;
            }
        }
Example #10
0
        private void C_NewRoosterMessage(IMessageSender sender, NewValidMessageEventArgs args)
        {
            XMPPClient client = sender as XMPPClient;

            if (args.MESSAGE is RosterMessage)
            {
                RosterMessage msg  = args.MESSAGE as RosterMessage;
                string        to   = client.getXMPPAccount().getIdAndDomain();
                string        type = msg.TYPE;

                if (string.Equals(type, IQMessage.RESULT))
                {
                    ChatDBManager.INSTANCE.setAllNotInRoster(client.getXMPPAccount().getIdAndDomain());
                }
                else if (type == null || !string.Equals(type, IQMessage.SET))
                {
                    // No roster result or set => return
                    return;
                }

                foreach (RosterItem item in msg.ITEMS)
                {
                    string    from = item.JID;
                    string    id   = ChatTable.generateId(from, to);
                    ChatTable chat = ChatDBManager.INSTANCE.getChat(id);
                    if (chat != null)
                    {
                        chat.subscription = item.SUBSCRIPTION;
                        chat.inRoster     = !item.SUBSCRIPTION.Equals("remove");
                        chat.ask          = item.ASK;
                    }
                    else if (!Equals(item.SUBSCRIPTION, "remove"))
                    {
                        chat = new ChatTable()
                        {
                            id            = id,
                            chatJabberId  = from,
                            userAccountId = to,
                            subscription  = item.SUBSCRIPTION,
                            lastActive    = DateTime.Now,
                            muted         = false,
                            inRoster      = true,
                            ask           = item.ASK,
                            chatType      = ChatType.CHAT
                        };
                    }
                    else
                    {
                        continue;
                    }

                    switch (chat.subscription)
                    {
                    case "unsubscribe":
                    case "from":
                    case "none":
                    case "pending":
                    case null:
                        chat.presence = Presence.Unavailable;
                        break;

                    default:
                        break;
                    }

                    ChatDBManager.INSTANCE.setChat(chat, false, true);
                }
            }
        }
 protected abstract Task processMessageAsync(NewValidMessageEventArgs args);
 //--------------------------------------------------------Events:---------------------------------------------------------------------\\
 #region --Events--
 private async void XMPP_CONNECTION_ConnectionNewValidMessage(IMessageSender sender, NewValidMessageEventArgs args)
 {
     await processMessageAsync(args);
 }
 protected void setMessageProcessed(NewValidMessageEventArgs args)
 {
     setMessageProcessed(args, true);
 }
 //--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\
 #region --Set-, Get- Methods--
 protected void setMessageProcessed(NewValidMessageEventArgs args, bool cancelEvent)
 {
     args.MESSAGE.setProcessed();
     args.Cancel = cancelEvent;
 }
Example #15
0
        private async Task streamFeaturesMessageReceivedAsync(StreamFeaturesMessage features, NewValidMessageEventArgs args)
        {
            TLSStreamFeature  tlsFeature     = getTLSStreamFeature(features);
            TLSConnectionMode connectionMode = TCP_CONNECTION.account.connectionConfiguration.tlsMode;

            if (tlsFeature != null)
            {
                if (connectionMode == TLSConnectionMode.PROHIBIT)
                {
                    if (tlsFeature.REQUIRED)
                    {
                        stopListeningForMessages();
                        string errorMsg = "TSL is required for server but TLS connection mode is set to prohibit!";
                        Logger.Error(errorMsg);
                        setState(TLSState.ERROR);
                        await XMPP_CONNECTION.onMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.TLS_CONNECTION_FAILED, errorMsg), true);
                    }
                    else
                    {
                        setState(TLSState.PROHIBITED);
                    }
                    return;
                }

                // Starting the TSL process:
                setMessageProcessed(args);
                setState(TLSState.CONNECTING);
                await XMPP_CONNECTION.sendAsync(new RequesStartTLSMessage(), true);

                setState(TLSState.REQUESTED);
            }
            else
            {
                if (connectionMode == TLSConnectionMode.FORCE)
                {
                    stopListeningForMessages();
                    string errorMsg = "TSL is not available for this server but TLS connection mode is set to force!";
                    Logger.Error(errorMsg);
                    setState(TLSState.ERROR);
                    await XMPP_CONNECTION.onMessageProcessorFailedAsync(new ConnectionError(ConnectionErrorCode.TLS_CONNECTION_FAILED, errorMsg), true);
                }
            }
        }
Example #16
0
 private void Connection_ConnectionNewPresenceMessage(IMessageSender connection, NewValidMessageEventArgs args)
 {
     // XEP-0045 (MUC member presence):
     if (args.MESSAGE is MUCMemberPresenceMessage mucPresence)
     {
         NewMUCMemberPresenceMessage?.Invoke(this, new NewMUCMemberPresenceMessageEventArgs(mucPresence));
     }
     else if (args.MESSAGE is MUCPresenceErrorMessage mucPresenceError)
     {
         NewMUCPresenceErrorMessage?.Invoke(this, new NewMUCPresenceErrorMessageEventArgs(mucPresenceError));
     }
     else
     {
         NewPresence?.Invoke(this, new NewPresenceMessageEventArgs(args.MESSAGE as PresenceMessage));
     }
 }
Example #17
0
 //--------------------------------------------------------Events:---------------------------------------------------------------------\\
 #region --Events--
 private void Connection_ConnectionNewRoosterMessage(IMessageSender sender, NewValidMessageEventArgs args)
 {
     NewRoosterMessage?.Invoke(this, args);
 }