예제 #1
0
        private string ParseStreamError(XmppIQ xStream)
        {
            string tag, message;

            XmppError.Parse(xStream, out tag, out message);
            return(tag + " " + message);
        }
예제 #2
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);
        }
예제 #3
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));
            }
        }