예제 #1
0
        public override void StreamParserOnStreamElement(object sender, ElementEventArgs eventArgs)
        {
            base.StreamParserOnStreamElement (sender, eventArgs);
            var e = eventArgs.Element;

            if (e is Handshake)
            {
                m_Authenticated = true;

                if (OnLogin != null)
                    OnLogin(this);

                if (KeepAlive)
                    CreateKeepAliveTimer();
                eventArgs.Handled  = true;
            }
            else if (e is Route)
            {
                if (OnRoute != null)
                    OnRoute(this, e as Route);
                eventArgs.Handled = true;
            }
            else if (e is protocol.Error)
            {
                protocol.Error streamErr = e as protocol.Error;
                switch (streamErr.Condition)
                {
                    // Auth errors are important for the users here, so throw catch auth errors
                    // in a separate event here
                    case agsXMPP.protocol.StreamErrorCondition.NotAuthorized:
                        // Authentication Error
                        if (OnAuthError != null)
                            OnAuthError(this, e as Element);
                        break;
                    default:
                        if (OnStreamError != null)
                            OnStreamError(this, e as Element);
                        break;
                }
                eventArgs.Handled = true;
            }
            else if (e is Message)
            {
                if (OnMessage != null) {
                    OnMessage(this, e as Message);
                    eventArgs.Handled = true;
                }
            }
            else if (e is Presence)
            {
                if (OnPresence != null) {
                    OnPresence(this, e as Presence);
                    eventArgs.Handled = true;
                }
            }
            else if (e is IQ)
            {
                if (OnIq != null) {
                    var iqEventArgs = new protocol.client.IQEventArgs((IQ)e);
                    OnIq(this, iqEventArgs);
                    if (iqEventArgs.Handled) {
                        eventArgs.Handled = true;
                    }
                }
            }
        }
예제 #2
0
        internal void OnStreamElement(object sender, ElementEventArgs eventArgs)
        {
            if (m_XmppClient == null) return;
            if ( m_XmppClient.XmppConnectionState == XmppConnectionState.Securing
                || m_XmppClient.XmppConnectionState == XmppConnectionState.StartCompression)
                return;
            var e = eventArgs.Element;

            if (e is Features)
            {
                Features f = e as Features;
                if (!m_XmppClient.Authenticated)
                {
                    // RECV: <stream:features><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>
                    //			<mechanism>DIGEST-MD5</mechanism><mechanism>PLAIN</mechanism>
                    //			</mechanisms>
                    //			<register xmlns='http://jabber.org/features/iq-register'/>
                    //		</stream:features>
                    // SENT: <auth mechanism="DIGEST-MD5" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
                    // Select a SASL mechanism

                    SaslEventArgs args = new SaslEventArgs(f.Mechanisms);

                    if (OnSaslStart != null)
                        OnSaslStart(this, args);

                    if (args.Auto)
                    {
                        // Library handles the Sasl stuff
                        if (f.Mechanisms!=null)
                        {
                            if (m_XmppClient.UseStartTLS == false && m_XmppClient.UseSSL == false
                                && f.Mechanisms.SupportsMechanism(MechanismType.X_GOOGLE_TOKEN) )
                            {
                                // This is the only way to connect to GTalk on a unsecure Socket for now
                                // Secure authentication is done over https requests to pass the
                                // authentication credentials on a secure connection
                                args.Mechanism = protocol.sasl.Mechanism.GetMechanismName(MechanismType.X_GOOGLE_TOKEN);
                            }
            #if !(CF || CF_2)
                            else if (m_XmppClient.UseSso && f.Mechanisms.SupportsMechanism(MechanismType.GSSAPI))
                            {
                                args.Mechanism = protocol.sasl.Mechanism.GetMechanismName(MechanismType.GSSAPI);

                                string kerbPrinc = f.Mechanisms.GetMechanism(MechanismType.GSSAPI).KerberosPrincipal;
                                if (kerbPrinc != null)
                                m_XmppClient.KerberosPrincipal =
                                    f.Mechanisms.GetMechanism(MechanismType.GSSAPI).KerberosPrincipal;
                            }
            #endif
                            else if (f.Mechanisms.SupportsMechanism(MechanismType.SCRAM_SHA_1))
                            {
                                args.Mechanism = protocol.sasl.Mechanism.GetMechanismName(MechanismType.SCRAM_SHA_1);
                            }
                            else if (f.Mechanisms.SupportsMechanism(MechanismType.DIGEST_MD5))
                            {
                                args.Mechanism = protocol.sasl.Mechanism.GetMechanismName(MechanismType.DIGEST_MD5);
                            }
                            else if (f.Mechanisms.SupportsMechanism(MechanismType.PLAIN))
                            {
                                args.Mechanism = protocol.sasl.Mechanism.GetMechanismName(MechanismType.PLAIN);
                            }
                            else
                            {
                                args.Mechanism = null;
                            }
                        }
                        else
                        {
                            // Hack for Google
                            // TODO: i don't think we need this anymore. This was in an very early version of the gtalk server.
                            args.Mechanism = null;
                            //args.Mechanism = agsXMPP.protocol.sasl.Mechanism.GetMechanismName(agsXMPP.protocol.sasl.MechanismType.PLAIN);
                        }
                    }
                    if (args.Mechanism != null)
                    {
                        m_Mechanism = Factory.SaslFactory.GetMechanism(args.Mechanism);
                        // Set properties for the SASL mechanism
                        m_Mechanism.Username = m_XmppClient.Username;
                        m_Mechanism.Password = m_XmppClient.Password;
                        m_Mechanism.Server = m_XmppClient.Server;

                        m_Mechanism.ExtentedData = args.ExtentedData;
                        // Call Init Method on the mechanism
                        m_Mechanism.Init(m_XmppClient);
                    }
                    else
                    {
                        m_XmppClient.RequestLoginInfo();
                    }
                }
                else if(!m_XmppClient.Binded)
                {
                    if (f.SupportsBind)
                    {
                        m_XmppClient.DoChangeXmppConnectionState(XmppConnectionState.Binding);

                        BindIq bIq = string.IsNullOrEmpty(m_XmppClient.Resource) ? new BindIq(IqType.set) : new BindIq(IqType.set, m_XmppClient.Resource);

                        m_XmppClient.IqGrabber.SendIq(bIq, BindResult);
                    }
                }

            }
            else if (e is Challenge)
            {
                if (m_Mechanism != null && !m_XmppClient.Authenticated)
                {
                    m_Mechanism.Parse(e);
                }
            }
            else if (e is Success)
            {
                // SASL authentication was successfull
                if (OnSaslEnd!=null)
                    OnSaslEnd(this);

                m_XmppClient.DoChangeXmppConnectionState(XmppConnectionState.Authenticated);

                m_Mechanism = null;

                m_XmppClient.Reset();
            }
            else if (e is Failure)
            {
                // Authentication failure
                m_XmppClient.FireOnAuthError(e as Element);
            }
        }
예제 #3
0
        private void OnRegisterResult(IQEventArgs e, Element data)
        {
            /*
            Example 6. Host Informs Entity of Failed Registration (Username Conflict)

            <iq type='error' id='reg2'>
            <query xmlns='jabber:iq:register'>
                <username>bill</username>
                <password>m1cro$oft</password>
                <email>[email protected]</email>
            </query>
            <error code='409' type='cancel'>
                <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
            </error>
            </iq>

            Example 7. Host Informs Entity of Failed Registration (Some Required Information Not Provided)

            <iq type='error' id='reg2'>
            <query xmlns='jabber:iq:register'>
                <username>bill</username>
                <password>Calliope</password>
            </query>
            <error code='406' type='modify'>
                <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
            </error>
            </iq>
            */
            if (e.IQ.Type == IqType.result)
            {
                DoChangeXmppConnectionState(XmppConnectionState.Registered);
                if (OnRegistered != null)
                    OnRegistered(this);

                if (this.StreamVersion != null && this.StreamVersion.StartsWith("1."))
                {
                    // init sasl login
                    InitSaslHandler();
                    var eventArgs = new ElementEventArgs(data);
                    m_SaslHandler.OnStreamElement(this, eventArgs);
                    if (eventArgs.Handled) {
                        e.Handled = true;
                    }
                }
                else
                {
                    // old jabber style login
                    RequestLoginInfo();
                    e.Handled = true;
                }
            }
            else if (e.IQ.Type == IqType.error)
            {
                if (OnRegisterError != null)
                    OnRegisterError(this, e.IQ);
            }
        }
예제 #4
0
        public override void StreamParserOnStreamElement(object sender, ElementEventArgs eventArgs)
        {
            base.StreamParserOnStreamElement(sender, eventArgs);
            bool handled = false;
            var e = eventArgs.Element;

            if (e is IQ)
            {
                IQ iq = e as IQ;

                if (OnIq != null) {
                    var ev = new IQEventArgs(iq);
                    OnIq(this, ev);
                    handled = handled || ev.Handled;
                }

                if ( iq != null && iq.Query != null)
                {
                    // Roster
                    if (iq.Query is Roster) {
                        OnRosterIQ(iq);
                        handled = true;
                    }
                }
            }
            else if (e is Message)
            {
                if (OnMessage != null) {
                    OnMessage(this, e as Message);
                    handled = true;
                }
            }
            else if (e is Presence)
            {
                if (OnPresence != null) {
                    OnPresence(this, e as Presence);
                    handled = true;
                }
            }
            else if (e is protocol.stream.Features)
            {
                // Stream Features
                // StartTLS stuff
                protocol.stream.Features f = e as protocol.stream.Features;
            #if SSL || BCCRYPTO || CF_2
                if (f.SupportsStartTls && m_UseStartTLS)
                {
                    DoChangeXmppConnectionState(XmppConnectionState.Securing);
                    Send(new StartTls());
                }
                // connection is not encrypted, doesn't support starttls but tls is forced
                else if (!ClientSocket.IsEncrypted && !f.SupportsStartTls && ForceStartTls) {
                    FireOnError(this, new StartTlsException("StartTls is not supported on this server"));
                    Close();
                }
                else
            #endif
                if (m_UseCompression &&
                    f.SupportsCompression &&
                    f.Compression.SupportsMethod(CompressionMethod.zlib))
                {
                    // Check for Stream Compression
                    // we support only ZLIB because its a free algorithm without patents
                    // yes ePatents suck
                    DoChangeXmppConnectionState(XmppConnectionState.StartCompression);
                    Send(new Compress(CompressionMethod.zlib));
                }

                else if (m_RegisterAccount)
                {
                    // Do registration after TLS when possible
                    if (f.SupportsRegistration)
                        GetRegistrationFields(e);
                    else
                    {
                        // registration is not enabled on this server
                        FireOnError(this, new RegisterException("Registration is not allowed on this server"));
                        Close();
                        // Close the stream
                    }
                }
                ServerCapabilities = f.Capabilities;
            }
            #if SSL || BCCRYPTO || CF_2
            else if (e is Proceed)
            {
                StreamParser.Reset();
                if (ClientSocket.StartTls())
                {
                    SendStreamHeader(false);
                    DoChangeXmppConnectionState(XmppConnectionState.Authenticating);
                    handled = true;
                }
            }
            #endif
            else if (e is Compressed)
            {
                //DoChangeXmppConnectionState(XmppConnectionState.StartCompression);
                StreamParser.Reset();
                ClientSocket.StartCompression();
                // Start new Stream Header compressed.
                SendStreamHeader(false);

                DoChangeXmppConnectionState(XmppConnectionState.Compressed);
                handled = true;
            }
            else if (e is agsXMPP.protocol.Error)
            {
                if (OnStreamError != null) {
                    OnStreamError(this, e as Element);
                    handled = true;
                }
            }

            if (handled) {
                eventArgs.Handled = true;
            }
        }
예제 #5
0
 /// <summary>
 /// If users didnt use the library correctly and had no local error handles
 /// it always crashed here and disconencted the socket.
 /// Catch this errors here now and foreward them.
 /// </summary>
 /// <param name="el"></param>
 internal void DoRaiseOnStreamElement(Element el)
 {
     try
     {
         if (OnStreamElement != null) {
             var eventArgs = new ElementEventArgs(el);
             OnStreamElement(this, eventArgs);
             if (!eventArgs.Handled) {
                 OnStreamElementNotHandled(el);
             }
         }
     }
     catch (Exception ex)
     {
         if (OnError != null)
             OnError(this, ex);
     }
 }