Beispiel #1
0
        /// <summary>
        /// An IQ Element is received. Now check if its one we are looking for and
        /// raise the event in this case.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void OnIq(object sender, IQEventArgs e)
        {
            // the tracker handles on iq responses, which are either result or error
            if (e.IQ.Type != IqType.error && e.IQ.Type != IqType.result)
                return;

            string id = e.IQ.Id;
            if(id == null)
                return;

            IqHandler td;

            lock (m_grabbing)
            {
                td = (IqHandler) m_grabbing[id];

                if (td == null)
                {
                    return;
                }
                m_grabbing.Remove(id);
            }

            td(this, e);
        }
Beispiel #2
0
 void FindGroupChatsDiscoMucs(IQEventArgs e, AutoResetEvent reset, List<Jid> list)
 {
     if (e.IQ.Error == null) {
         var items = (DiscoItems)e.IQ.Query;
         foreach (var item in items.GetDiscoItems()) {
             // no locking required, these callbacks are sequential
             list.Add(item.Jid);
         }
     }
     e.Handled = true;
     reset.Set();
 }
Beispiel #3
0
 void FindGroupChatsDiscoItems(IQEventArgs e, AutoResetEvent reset)
 {
     if (e.IQ.Error == null) {
         lock (this) {
             ServerDiscoItems = (DiscoItems)e.IQ.Query;
         }
     }
     e.Handled = true;
     reset.Set();
 }
Beispiel #4
0
 void FindGroupChatsChatInfo(IQEventArgs e, AutoResetEvent reset, List<GroupChatModel> list)
 {
     if (e.IQ.Error == null) {
         var items = (DiscoInfo)e.IQ.Query;
         lock (this) {
             CachedMucInfo[e.IQ.From] = items;
         }
         FindGroupChatsChatInfoParse(e.IQ.From, items, list);
     }
     e.Handled = true;
     reset.Set();
 }
Beispiel #5
0
 private void OnIq(object sender, IQEventArgs e)
 {
     // DiscoInfo
     if (m_AutoAnswerDiscoInfoRequests && e.IQ.Query is DiscoInfo && e.IQ.Type == IqType.get) {
         e.Handled = true;
         ProcessDiscoInfo(e.IQ);
     }
 }
Beispiel #6
0
        private void SessionResult(object sender, IQEventArgs e)
        {
            if (e.IQ.Type == IqType.result)
            {
                m_XmppClient.DoChangeXmppConnectionState(XmppConnectionState.SessionStarted);
                m_XmppClient.RaiseOnLogin();
                e.Handled = true;
            }
            else if (e.IQ.Type == IqType.error)
            {

            }
        }
        void OnRegistrationFieldsResult(IQEventArgs e, Element data)
        {
            if (e.IQ.Type != IqType.error)
            {
                if (e.IQ.Query is Register)
                {
                    RegisterEventArgs args = new RegisterEventArgs(e.IQ.Query as Register);
                    if (OnRegisterInformation != null)
                        OnRegisterInformation(this, args);

                    DoChangeXmppConnectionState(XmppConnectionState.Registering);

                    IQ regIq = new IQ(IqType.set);
                    regIq.GenerateId();
                    regIq.To = new Jid(base.Server);

                    //RegisterIq regIq = new RegisterIq(IqType.set, new Jid(base.Server));
                    if (args.Auto)
                    {
                        Register reg = new Register(this.m_Username, this.m_Password);
                        regIq.Query = reg;
                    }
                    else
                    {
                        regIq.Query = args.Register;
                    }
                    IqGrabber.SendIq(regIq,
                        (object sender, IQEventArgs ev) => OnRegisterResult(ev, data)
                    );
                    e.Handled = true;
                }
            }
            else
            {
                if (OnRegisterError != null)
                    OnRegisterError(this, e.IQ);
                e.Handled = true; // not really
            }
        }
        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;
                    }
                }
            }
        }
        private void OnGetAuthInfo(object sender, IQEventArgs e)
        {
            // We get smth like this and should add password (digest) and ressource
            // Recv:<iq type="result" id="MX_7"><query xmlns="jabber:iq:auth"><username>gnauck</username><password/><digest/><resource/></query></iq>
            // Send:<iq type='set' id='mx_login'>
            //			<query xmlns='jabber:iq:auth'><username>gnauck</username><digest>27c05d464e3f908db3b2ca1729674bfddb28daf2</digest><resource>Office</resource></query>
            //		</iq>
            // Recv:<iq id="mx_login" type="result"/>

            e.Handled = true;

            var iq = e.IQ;
            if (iq.Error != null) {
                FireOnAuthError(iq);
                return;
            }

            iq.GenerateId();
            iq.SwitchDirection();
            iq.Type = IqType.set;

            Auth auth = (Auth) iq.Query;

            auth.Resource = this.m_Resource;
            auth.SetAuth(this.m_Username, this.m_Password, this.StreamId);

            IqGrabber.SendIq(iq, OnAuthenticate);
        }
Beispiel #10
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);
            }
        }
Beispiel #11
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="iq"></param>
        /// <param name="data">contains the new password</param>
        private void OnChangePasswordResult(IQEventArgs e, string newPass)
        {
            if (e.IQ.Type == IqType.result)
            {
                if(OnPasswordChanged!=null)
                    OnPasswordChanged(this);

                // Set the new password in the Password property on sucess
                m_Password = newPass;
                e.Handled = true;
            }
            else if (e.IQ.Type == IqType.error)
            {
                /*
                The server or service SHOULD NOT return the original XML sent in
                IQ error stanzas related to password changes.

                Example 12. Host Informs Client of Failed Password Change (Bad Request)

                <iq type='error' from='somehost' to='user@host/resource' id='change1'>
                <error code='400' type='modify'>
                    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
                </error>
                </iq>

                Example 13. Host Informs Client of Failed Password Change (Not Authorized)

                <iq type='error' from='somehost' to='user@host/resource' id='change1'>
                <error code='401' type='cancel'>
                    <not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
                </error>
                </iq>

                Example 14. Server Informs Client of Failed Password Change (Not Allowed)

                <iq type='error' from='somehost' to='user@host/resource' id='change1'>
                <error code='405' type='cancel'>
                    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
                </error>
                </iq>

                */

                if(OnRegisterError!=null)
                    OnRegisterError(this, e.IQ);
            }
        }
Beispiel #12
0
 private void OnAuthenticate(object sender, IQEventArgs e)
 {
     if (e.IQ.Type == IqType.result)
     {
         m_Authenticated = true;
         RaiseOnLogin();
         e.Handled = true;
     }
     else if(e.IQ.Type == IqType.error)
     {
         /*
          * <iq xmlns="jabber:client" id="agsXMPP_2" type="error">
          *		<query xmlns="jabber:iq:auth">
          *			<username>test</username>
          *			<digest sid="842070264">dc7e472abb95b65c2b75129ade607170be478b16</digest>
          *			<resource>MiniClient</resource>
          *		</query>
          *		<error code="401">Unauthorized</error>
          * </iq>
          *
          */
         if (OnAuthError!=null)
             OnAuthError(this, e.IQ);
     }
 }
Beispiel #13
0
        private void OnAgents(object sender, IQEventArgs e)
        {
            e.Handled = true;
            if (OnAgentStart != null)
                OnAgentStart(this);

            Agents agents = e.IQ.Query as Agents;
            if (agents != null)
            {
                foreach (Agent a in agents.GetAgents())
                {
                    if (OnAgentItem != null)
                        OnAgentItem(this, a);
                }
            }

            if (OnAgentEnd != null)
                OnAgentEnd(this);
            e.Handled = true;
        }
Beispiel #14
0
 void FindGroupChatsItemDiscoInfo(IQEventArgs e, AutoResetEvent reset, List<Jid> mucList, Jid jid)
 {
     if (e.IQ.Error == null) {
         var discoInfo = (DiscoInfo)e.IQ.Query;
         if (discoInfo.HasFeature(agsXMPP.Uri.MUC)) {
             // no locking required, these callbacks are sequential
             mucList.Add(jid);
         }
     }
     e.Handled = true;
     reset.Set();
 }
Beispiel #15
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;
            }
        }
Beispiel #16
0
 void OnDiscoInfo(IQEventArgs e, string hash)
 {
     if (e.IQ.Error != null) {
     #if LOG4NET
         _Logger.DebugFormat("An error happened during service discovery: {0}", e.IQ);
     #endif
         // clear item from cache so the request is done again some time
         DiscoCache.Remove(hash);
         e.Handled = true;
         return;
     }
     if (e.IQ.Type != IqType.result) {
     #if LOG4NET
         _Logger.Debug("OnDiscoInfo(): iq is not a result");
     #endif
         return;
     }
     if (!(e.IQ.Query is DiscoInfo)) {
     #if LOG4NET
         _Logger.Debug("OnDiscoInfo(): query is not a DiscoInfo");
     #endif
         return;
     }
     var info = (DiscoInfo)e.IQ.Query;
     DiscoCache[hash] = info;
     e.Handled = true;
     if (String.IsNullOrEmpty(e.IQ.From.User)) {
         // server capabilities
         var builder = CreateMessageBuilder();
         builder.AppendText("The Server supports the following features: ");
         Session.AddMessageToChat(NetworkChat, builder.ToMessage());
         foreach (var feature in info.GetFeatures()) {
             builder = CreateMessageBuilder();
             builder.AppendText(feature.Var);
             Session.AddMessageToChat(NetworkChat, builder.ToMessage());
         }
     } else {
         AddCapabilityToResource(e.IQ.From, info);
     }
 }
Beispiel #17
0
        private void BindResult(object sender, IQEventArgs e)
        {
            var iq = e.IQ;
            // Once the server has generated a resource identifier for the client or accepted the resource
            // identifier provided by the client, it MUST return an IQ stanza of type "result"
            // to the client, which MUST include a <jid/> child element that specifies the full JID for
            // the connected resource as determined by the server:

            // Server informs client of successful resource binding:
            // <iq type='result' id='bind_2'>
            //  <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>
            //    <jid>[email protected]/someresource</jid>
            //  </bind>
            // </iq>
            if (iq.Type == IqType.result)
            {
                // i assume the server could assign another resource here to the client
                // so grep the resource assigned by the server now
                Element bind = iq.SelectSingleElement(typeof(Bind));
                if (bind != null)
                {
                    Jid jid = ((Bind)bind).Jid;
                    m_XmppClient.Resource = jid.Resource;
                    m_XmppClient.Username = jid.User;
                }

                m_XmppClient.DoChangeXmppConnectionState(XmppConnectionState.Binded);
                m_XmppClient.m_Binded = true;

                m_XmppClient.DoRaiseEventBinded();

                // success, so start the session now
                m_XmppClient.DoChangeXmppConnectionState(XmppConnectionState.StartSession);
                SessionIq sIq = new SessionIq(IqType.set, new Jid(m_XmppClient.Server));
                m_XmppClient.IqGrabber.SendIq(sIq, SessionResult);
                e.Handled = true;
            }
            else if (iq.Type == IqType.error)
            {
                // TODO, handle bind errors
                m_XmppClient.DoRaiseEventBindError(iq);
            }
        }
        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;
                    }
                }
            }
        }
Beispiel #19
0
        void OnIq(object sender, IQEventArgs e)
        {
            Trace.Call(sender, e);

            // not as pretty as the previous implementation, but it works
            var elem = e.IQ.SelectSingleElement("own-message");
            if (elem is OwnMessageQuery) {
                OnIQOwnMessage((OwnMessageQuery) elem);
                e.Handled = true;
            }
        }