/// <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); }
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(); }
void FindGroupChatsDiscoItems(IQEventArgs e, AutoResetEvent reset) { if (e.IQ.Error == null) { lock (this) { ServerDiscoItems = (DiscoItems)e.IQ.Query; } } e.Handled = true; reset.Set(); }
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(); }
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); } }
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); }
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); } }
/// <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); } }
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); } }
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; }
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(); }
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; } }
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); } }
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; } } } }
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; } }