Пример #1
0
 private void ViewXStream(XmppIQ xStream, string title = "")
 {
     Dispatcher.BeginInvoke(new Action(() => {
         string content = UIHelper.XmlIndent(xStream.ToString());
         DialogUtils.ShowIndentedContent(this, content, title);
     }), DispatcherPriority.Normal);
 }
Пример #2
0
        private string ParseStreamError(XmppIQ xStream)
        {
            string tag, message;

            XmppError.Parse(xStream, out tag, out message);
            return(tag + " " + message);
        }
Пример #3
0
        private void Signal(XmppIQ xStream)
        {
            if (IqSignal != null)
            {
                string typeStr = xStream.GetAttribute("type");
                string idStr   = xStream.GetAttribute("id");

                int id = -1;
                if (Int32.TryParse(idStr, out id) && id >= 0)
                {
                    IqSignal(this, new XmppIqSignalEventArgs(id, XmppIq.StrToType(typeStr), xStream));
                }
            }
        }
Пример #4
0
        private string recvStream()
        {
            if (tcpClient == null)
            {
                if (Error != null)
                {
                    Error(this, new XmppErrorEventArgs(XmppErrorType.ClientNotConnected, string.Empty, string.Empty));
                }
                return(string.Empty);
            }

            int           iteration = 0;
            StringBuilder buf       = new StringBuilder();

            while (true)
            {
                string internalBuf = tcpClient.ReadStream();
                if (string.IsNullOrWhiteSpace(internalBuf))
                {
                    break;
                }

                if (internalBuf.Contains("<stream:error"))
                {
                    if (RecvStreamCallback != null)
                    {
                        RecvStreamCallback(this, new XmppEventArgs(buf.Append(internalBuf).ToString()));
                    }
                    if (Error != null)
                    {
                        string tag, message;
                        XmppError.Parse(XmppIQ.Parse(internalBuf), out tag, out message);
                        Error(this, new XmppErrorEventArgs(XmppErrorType.XmppStreamError, tag, message));
                    }
                    Disconnect();
                    break;
                }
                else if (internalBuf.Contains("</stream:stream>"))
                {
                    if (RecvStreamCallback != null)
                    {
                        RecvStreamCallback(this, new XmppEventArgs(buf.Append(internalBuf).ToString()));
                    }
                    if (Error != null)
                    {
                        Error(this, new XmppErrorEventArgs(XmppErrorType.ConnectionClosedByServer, string.Empty, string.Empty));
                    }

                    Disconnect();
                    break;
                }

                buf.Append(internalBuf);
                if (state == XmppEngineState.Open)
                {
                    if (XmppStream.IsValid(buf.ToString()))
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }

                iteration++;
                if (iteration > 100)
                {
                    if (Error != null)
                    {
                        Error(this, new XmppErrorEventArgs(XmppErrorType.RecvTooManyInvalidStream, string.Empty, ""));
                    }

                    Disconnect();
                    return(string.Empty);
                }
            }

            if (RecvStreamCallback != null)
            {
                RecvStreamCallback(this, new XmppEventArgs(buf.ToString()));
            }

            // flush string buffer
            string stringBuffer = buf.ToString();

            buf.EnsureCapacity(0);

            // it's ok, return a valid stream
            return(stringBuffer);
        }
Пример #5
0
        private void doAuthenticate()
        {
            doChangeState(XmppEngineState.Opening);
            if (tcpClient != null)
            {
                tcpClient.Dispose();
                tcpClient = null;
            }

            try {
                tcpClient = new XmppTcpSocket(HostName, HostPort);
            }
            catch (Exception ex) {
                if (Error != null)
                {
                    Error(this, new XmppErrorEventArgs(XmppErrorType.SocketError, string.Empty, ex.GetType().ToString() + ": " + ex.Message));
                }
                if (tcpClient != null)
                {
                    tcpClient.Dispose();
                    tcpClient = null;
                }

                return;
            }

            string stream;
            XmppIQ xStream;

            // ==========================================================================
            // === START TLS LAYER ======================================================
            stream = doRequestFeatures();
            if (stream.Contains("<starttls"))
            {
                sendStream("<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>");
                stream = recvStream();
                if (stream.Contains("<proceed"))
                {
                    bool   sslStarted = false;
                    string message    = string.Empty;
                    try {
                        sslStarted = tcpClient.StartSSL();
                        sslStarted = true;
                    }
                    catch (Exception ex) {
                        sslStarted = false;
                        message    = string.Format("{0}: {1}", ex.GetType(), ex.Message);
                    }

                    if (!sslStarted)
                    {
                        if (Error != null)
                        {
                            Error(this, new XmppErrorEventArgs(XmppErrorType.SocketStartSSLError, string.Empty, message));
                        }

                        return;
                    }

                    stream = doRequestFeatures();
                }
            }

            if (stream.Contains("<mechanism>DIGEST-MD5</mechanism>"))
            {
                // ==========================================================================
                // === SASL DIGEST-MD5 AUTHENTICATION PROCESS ===============================
                DigestMD5MechanismProvider mech = new DigestMD5MechanismProvider(UserName, UserPassword);
                sendStream(mech.GetAuthStream());

                stream  = recvStream();
                xStream = XmppIQ.Parse(stream);
                if (!xStream.Equal("challenge", "urn:ietf:params:xml:ns:xmpp-sasl"))
                {
                    if (Error != null)
                    {
                        string tag, message;
                        XmppError.Parse(XmppIQ.Parse(stream), out tag, out message);
                        Error(this, new XmppErrorEventArgs(XmppErrorType.AuthUserNotAuthorized, tag, message));
                    }

                    return;
                }

                sendStream(mech.GetChallengeResponse(xStream.Text));
                stream  = recvStream();
                xStream = XmppIQ.Parse(stream);
                if (!xStream.Equal("challenge", "urn:ietf:params:xml:ns:xmpp-sasl"))
                {
                    if (Error != null)
                    {
                        string tag, message;
                        XmppError.Parse(XmppIQ.Parse(stream), out tag, out message);
                        Error(this, new XmppErrorEventArgs(XmppErrorType.AuthUserNotAuthorized, tag, message));
                    }

                    return;
                }

                sendStream("<response xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\"/>");
            }
            else if (stream.Contains("<mechanism>PLAIN</mechanism>"))
            {
                // ==========================================================================
                // === SASL PLAIN AUTHENTICATION PROCESS ====================================
                PlainMechanismProvider mech = new PlainMechanismProvider(UserName, UserPassword);
                sendStream(mech.GetAuthStream());
            }
            else if (stream.Contains("<mechanism>X-GOOGLE-TOKEN</mechanism>"))
            {
                // ==========================================================================
                // === SASL X-GOOGLE-TOKEN AUTHENTICATION PROCESS ====================================
                XGoogleTokenMechanismProvider mech = new XGoogleTokenMechanismProvider(UserName, UserPassword, UserResource);
                sendStream(mech.GetAuthStream());
            }
            else if (stream.Contains("<mechanism>X-MESSENGER-OAUTH2</mechanism>"))
            {
                // ==========================================================================
                // === SASL X-MESSENGER-OAUTH2 AUTHENTICATION PROCESS ====================================
                XMessengerOAuth2MechanismProvider mech = new XMessengerOAuth2MechanismProvider(UserName, UserOAuthToken);
                sendStream(mech.GetAuthStream());
            }
            else if (stream.Contains("<mechanism>X-FACEBOOK-PLATFORM</mechanism>"))
            {
                // ==========================================================================
                // === SASL X-FACEBOOK-PLATFORM AUTHENTICATION PROCESS ====================================
                XFacebookPlatformMechanismProvider mech = new XFacebookPlatformMechanismProvider(UserName, UserOAuthToken);
                sendStream(mech.GetAuthStream());

                stream  = recvStream();
                xStream = XmppIQ.Parse(stream);
                if (!xStream.Equal("challenge", "urn:ietf:params:xml:ns:xmpp-sasl"))
                {
                    if (Error != null)
                    {
                        string tag, message;
                        XmppError.Parse(XmppIQ.Parse(stream), out tag, out message);
                        Error(this, new XmppErrorEventArgs(XmppErrorType.AuthUserNotAuthorized, tag, message));
                    }

                    return;
                }

                sendStream(mech.GetChallengeResponse(xStream.Text));
            }
            else
            {
                if (Error != null)
                {
                    Error(this, new XmppErrorEventArgs(XmppErrorType.AuthModeNotSupported));
                }

                return;
            }

            stream = recvStream();
            if (stream.Contains("<failure"))
            {
                if (Error != null)
                {
                    string tag, message;
                    XmppError.Parse(XmppIQ.Parse(stream), out tag, out message);
                    Error(this, new XmppErrorEventArgs(XmppErrorType.AuthUserNotAuthorized, tag, message));
                }

                return;
            }

            // ==========================================================================
            // === BIND RESOURCE ========================================================
            stream = doRequestFeatures();
            SendIq(Jid, null, XmppIqType.Set, "<bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"><resource>" + UserResource + "</resource></bind>");
            stream  = recvStream();
            xStream = new XmppIQ(stream);
            XmppIQ xJid = xStream.FindDescendant("jid", "urn:ietf:params:xml:ns:xmpp-bind");

            if (xJid != null)
            {
                Jid = new XmppJid(xJid.Text);
            }

            // ==========================================================================
            // === START SESSION ========================================================
            SendIq(Jid, null, XmppIqType.Set, "<session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>");
            stream = recvStream();

            // ==========================================================================
            // === OK: AUTHENTICATED IN JABBER NETWORK, You rocks! ======================
            //tcpClient.SetReadTimeout(0);
            doChangeState(XmppEngineState.Open);

            if (UserConnected != null)
            {
                UserConnected(this, new XmppEventArgs(Jid.Value));
            }
        }
Пример #6
0
        private void doParseStream(string stream)
        {
            XmppIQ xStream;

            try {
                xStream = XmppIQ.Parse(stream);
            }       catch (Exception) {
                //MessageBox.Show("Invalid stream :(\n\n" + stream);
                return;
            }

            switch (xStream.Name)
            {
                #region PRESENCE
            case "presence": {
                XmppPresence presence = new XmppPresence();
                string       type     = xStream.GetAttribute("type");
                presence.From = new XmppJid(xStream.GetAttribute("from"));
                presence.To   = new XmppJid(xStream.GetAttribute("to"));

                // # type == ""
                if (string.IsNullOrEmpty(type))
                {
                    XmppIQ xStatus = xStream.FindDescendant("status");
                    if (xStatus != null)
                    {
                        presence.MessageStatus = xStatus.Text;
                    }

                    XmppIQ xShow = xStream.FindDescendant("show");
                    presence.Status = xShow != null?XmppIq.StrToPresence(xShow.Text) : XmppPresenceStatus.Online;

                    XmppIQ xCard = xStream.FindDescendant("x", "vcard-temp:x:update");
                    if (xCard != null)
                    {
                        XmppIQ xPhoto = xCard.FindDescendant("photo", "vcard-temp:x:update");
                        if (xPhoto != null)
                        {
                            presence.PhotoHash = xPhoto.Text;
                        }
                    }

                    if (Presence != null)
                    {
                        Presence(this, new XmppPresenceEventArgs(presence));
                    }
                }
                // # type == "unavailable"
                else if (type == "unavailable")
                {
                    presence.Status = XmppPresenceStatus.Unavailable;
                    if (Presence != null)
                    {
                        Presence(this, new XmppPresenceEventArgs(presence));
                    }
                }
                // # type == "probe"	// probe request from server
                else if (type == "probe")
                {
                    SetPresence(statePresence, string.Empty, null);
                }
                // # type == "subscribe"	// new subscription request
                else if (type == "subscribe")
                {
                    if (SubscribeRequest != null)
                    {
                        SubscribeRequest(this, new XmppSubscribeRequestEventArgs(presence.From));
                    }
                }
                // # type == "error"	// presence stanza error
                else if (type == "error")
                {
                    // @@@
                }
            }
            break;

                #endregion
                #region MESSAGE
            case "message": {
                XmppMessage message = new XmppMessage();
                message.Type = xStream.GetAttribute("type");
                message.From = new XmppJid(xStream.GetAttribute("from"));
                message.To   = new XmppJid(xStream.GetAttribute("to"));
                Int32.TryParse(xStream.GetAttribute("id"), out message.ID);

                if (message.Type != "error")
                {
                    // # user composing new message
                    if (xStream.FindDescendant("composing", "http://jabber.org/protocol/chatstates") != null)
                    {
                        if (ChatNotify != null)
                        {
                            ChatNotify(this, new XmppChatNotifyEventArgs(message.From, string.Empty, XmppChatStatus.NowComposing));
                        }
                    }
                    // # user stop composing
                    else if (xStream.FindDescendant("paused", "http://jabber.org/protocol/chatstates") != null)
                    {
                        if (ChatNotify != null)
                        {
                            ChatNotify(this, new XmppChatNotifyEventArgs(message.From, string.Empty, XmppChatStatus.StopComposing));
                        }
                    }
                    // # user is inactive
                    else if (xStream.FindDescendant("inactive", "http://jabber.org/protocol/chatstates") != null)
                    {
                        if (ChatNotify != null)
                        {
                            ChatNotify(this, new XmppChatNotifyEventArgs(message.From, string.Empty, XmppChatStatus.Inactive));
                        }
                    }
                    // # user has left conversation
                    else if (xStream.FindDescendant("gone", "http://jabber.org/protocol/chatstates") != null)
                    {
                        if (ChatNotify != null)
                        {
                            ChatNotify(this, new XmppChatNotifyEventArgs(message.From, string.Empty, XmppChatStatus.Gone));
                        }
                    }
                    // # user is active ;)
                    else if (xStream.FindDescendant("active", "http://jabber.org/protocol/chatstates") != null)
                    {
                        if (ChatNotify != null)
                        {
                            ChatNotify(this, new XmppChatNotifyEventArgs(message.From, string.Empty, XmppChatStatus.Active));
                        }
                    }

                    // # check for new message
                    XmppIQ xBody = xStream.FindDescendant("body");
                    if (xBody != null)
                    {
                        message.Body = xBody.Text;

                        XmppIQ xThread = xStream.FindDescendant("thread");
                        if (xThread != null)
                        {
                            message.Thread = xThread.Text;
                        }

                        XmppIQ xSubject = xStream.FindDescendant("subject");
                        if (xSubject != null)
                        {
                            message.Subject = xSubject.Text;
                        }

                        if (Message != null)
                        {
                            Message(this, new XmppMessageEventArgs(message));
                        }
                    }
                }
            }
            break;

                #endregion
                #region IQ
            case "iq": {
                XmppIQ xQuery = null;
                string type   = xStream.GetAttribute("type");

                // Roster
                xQuery = xStream.FindDescendant("query", "jabber:iq:roster");
                if (xQuery != null)
                {
                    List <XmppRosterItem> roster = new List <XmppRosterItem>();
                    foreach (XmppIQ xItem in xQuery.Children())
                    {
                        if (xItem.Name != "item")
                        {
                            continue;
                        }

                        string jid   = xItem.GetAttribute("jid");
                        string sub   = xItem.GetAttribute("subscription");
                        string ask   = xItem.GetAttribute("ask");
                        string name  = xItem.GetAttribute("name");
                        string group = xItem.GetAttribute("group");
                        roster.Add(new XmppRosterItem(jid, sub, name, group, ask));
                    }

                    if (Roster != null)
                    {
                        Roster(this, new XmppRosterEventArgs(roster, XmppIq.StrToType(type)));
                    }
                }

                // Disco
                xQuery = xStream.FindDescendant("query", "http://jabber.org/protocol/disco#info");
                if (xQuery != null)
                {
                    if (type == "get")
                    {
                        XmppJid from = new XmppJid(xStream.GetAttribute("from"));
                        string  id   = xStream.GetAttribute("id");
                        sendStream(new XmppIq().ToStream(Jid, from, XmppIqType.Result, id, Disco.ToStreamResult()));                                // @@@@@ ottimizza SendIq(...)
                        //SendIq(from, XmppIqType.Result, Disco.ToStreamResult());// @@@@@ ottimizza SendIq(...)
                    }
                }

                // vCard
                xQuery = xStream.FindDescendant("vCard", "vcard-temp");
                if (xQuery != null)
                {
                    if (type == "result")
                    {
                        XmppJid   from  = new XmppJid(xStream.GetAttribute("from"));
                        XmppVCard vCard = new XmppVCard(from, xQuery);
                        if (VCard != null)
                        {
                            VCard(this, new XmppVCartEventArgs(vCard));
                        }
                    }
                }

                // Ping
                xQuery = xStream.FindDescendant("ping", "urn:xmpp:ping");
                if (xQuery != null)
                {
                    if (type == "get")
                    {
                        XmppJid from = new XmppJid(xStream.GetAttribute("from"));
                        string  id   = xStream.GetAttribute("id");
                        sendStream(new XmppIq().ToStream(Jid, from, XmppIqType.Result, id, string.Empty));                                // @@@@@ ottimizza SendIq(...)
                    }
                }
            }

            break;
                #endregion
            }

            Signal(xStream);
        }