Esempio n. 1
0
 internal void FireStanzaReceived(XMPPStanza stanza)
 {
     if (OnStanzaReceived != null)
     {
         OnStanzaReceived(stanza, this);
     }
 }
Esempio n. 2
0
        public virtual int SendStanza(XMPPStanza stanza)
        {
            string strSend = stanza.XML;

            byte[] bStanza = System.Text.UTF8Encoding.UTF8.GetBytes(strSend);
            return(this.Send(bStanza));
        }
Esempio n. 3
0
 /// <summary>
 /// A new XML fragment has been received
 /// </summary>
 /// <param name="node"></param>
 /// <returns>returns true if we handled this fragment, false if other wise</returns>
 public virtual bool NewXMLFragment(XMPPStanza stanza)
 {
     return false;
 }
Esempio n. 4
0
        protected virtual void XMPPConnection_OnStanzaReceived(XMPPStanza stanza, object objFrom)
        {
            bool bHandled = false;
            /// See if any of our handlers
            ///
            List <Logic> RemoveList = new List <Logic>();

            lock (LogicLock)
            {
                foreach (Logic log in ActiveServices)
                {
                    bHandled = log.NewXMLFragment(stanza);
                    if (log.IsCompleted == true)
                    {
                        RemoveList.Add(log);
                    }
                    if (bHandled == true)
                    {
                        break;
                    }
                }

                foreach (Logic log in RemoveList)
                {
                    ActiveServices.Remove(log);
                }
            }

            if (bHandled == true)
            {
                return;
            }

            /// Now see if this stanza is a higher level IQ or message
            ///
            try
            {
                XElement        elem = XElement.Parse(stanza.XML);
                XMPPMessageBase msg  = null;
                if (elem.Name == "iq")
                {
                    msg = XMPPMessageFactory.BuildIQ(elem, stanza.XML);
                }
                else if (elem.Name == "message")
                {
                    msg = XMPPMessageFactory.BuildMessage(elem, stanza.XML);
                }
                else if (elem.Name == "presence")
                {
                    msg = XMPPMessageFactory.BuildPresence(elem, stanza.XML);
                    //msg = new PresenceMessage(stanza.XML);
                }
                /// TODO.. log IQ, MESSAGE or PRESENCE event, maybe have an event handler
                ///
                if (msg != null)
                {
                    if (msg is IQ)
                    {
                        bHandled = OnIQ(msg as IQ);
                    }
                    else if (msg is Message)
                    {
                        bHandled = OnMessage(msg as Message);
                    }
                    else if (msg is PresenceMessage)
                    {
                        bHandled = OnPresence(msg as PresenceMessage);
                    }
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }

            if (bHandled == true)
            {
                return;
            }
        }
Esempio n. 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="stanza"></param>
        /// <returns></returns>
        public override bool NewXMLFragment(XMPPStanza stanza)
        {
            /// Looks like the crippled windows phone 7 libraries can't use output from xsd.exe, have to do this the hard way
            ///
            //XDocument doc = XDocument.Load(new StringReader(stanza.XML));
            //XmlReader reader = XmlReader.Create(new StringReader(stanza.XML));


            stanza.XML = stanza.XML.Replace("stream:", "");  // no support for namespaces in windows phone 7, remove them

            XElement xmlElem = XElement.Parse(stanza.XML);

            if (XMPPClient.XMPPState >= XMPPState.Authenticated)
            {
                if (xmlElem.Name == "features")
                {
                    return(true);  /// If we hit this and parse the stream featurs a second time we re-authenticate.  Just return for now
                }
                //if (xmlElem.Name == "stream")
                //{
                //     XMPPClient.XMPPState = XMPPState.CanBind;
                //}
                /// TODO.. see if this new stream supports bind
            }


            if (xmlElem.Name == "features")
            {
                //foreach (XElement node in xmlElem.Descendants())
                //{
                //    System.Diagnostics.Debug.WriteLine(node.Name);
                //}
                var Mechanisms = from mech in xmlElem.Descendants("{urn:ietf:params:xml:ns:xmpp-sasl}mechanism")
                                 select new Mechanism
                {
                    Name = mech.Value,
                };
                foreach (Mechanism mech in Mechanisms)
                {
                    if (mech.Name == "DIGEST-MD5")
                    {
                        AuthMethodsSupported |= AuthMethod.MD5;
                    }
                    else if (mech.Name == "PLAIN")
                    {
                        AuthMethodsSupported |= AuthMethod.Plain;
                    }
                    //  else if (mech.Name == "X-GOOGLE-TOKEN")
                    //    AuthMethodsSupported |= AuthMethod.googletoken;
                }

                if (AuthMethodsSupported == AuthMethod.NotSpecified)
                {
                    throw new Exception("No acceptable authentication method was supplied");
                }

                var tls = xmlElem.Descendants("{urn:ietf:params:xml:ns:xmpp-tls}starttls");
                if (tls.Count() > 0)
                {
                    FeatureTLS = true;
                }

                if ((FeatureTLS == true) && (XMPPClient.UseTLS == true))
                {
                    /// Tell the man we want to negotiate TLS
                    XMPPClient.SendRawXML(StartTLS);
                }
                else
                {
                    StartAuthentication();
                }

                return(true);
            }
            else if (xmlElem.Name == "{urn:ietf:params:xml:ns:xmpp-tls}proceed")
            {
                XMPPClient.XMPPConnection.StartTLS();

                /// After starting TLS, start our normal digest authentication (or plain)
                ///
                StartAuthentication();
            }
            else if (xmlElem.Name == "{urn:ietf:params:xml:ns:xmpp-sasl}challenge")
            {
                /// Build and send response
                ///
                string strChallenge        = xmlElem.Value;
                byte[] bData               = Convert.FromBase64String(strChallenge);
                string strUnbasedChallenge = System.Text.UTF8Encoding.UTF8.GetString(bData, 0, bData.Length);

                //realm="ninethumbs.com",nonce="oFun3YWfVm/6nHCkNI/9a4XpcWIdQ5RH9E0IDVKH",qop="auth",charset=utf-8,algorithm=md5-sess

                //string strExampleResponse = "dXNlcm5hbWU9InRlc3QiLHJlYWxtPSJuaW5ldGh1bWJzLmNvbSIsbm9uY2U9InJaNjgreS9BeGp2SjJ6cjBCVUNxVUhQcG9ocFE4ZFkzR29JclpJcFkiLGNub25jZT0iVkdFRDNqNHUrUHE1M3IxYzNab2NhcGFzaWp1eTh2NjhoYXFzRC9IWjVKTT0iLG5jPTAwMDAwMDAxLGRpZ2VzdC11cmk9InhtcHAvbmluZXRodW1icy5jb20iLHFvcD1hdXRoLHJlc3BvbnNlPTdiM2MzOTVjZjU2MDA2Njg5MDg5MzdlYTk2YjEzZjI2LGNoYXJzZXQ9dXRmLTg=";
                //bData = Convert.FromBase64String(strExampleResponse);
                //string strUnbasedResponse = System.Text.UTF8Encoding.UTF8.GetString(bData, 0, bData.Length);
                //"username=\"test\",realm=\"ninethumbs.com\",nonce=\"rZ68+y/AxjvJ2zr0BUCqUHPpohpQ8dY3GoIrZIpY\",cnonce=\"VGED3j4u+Pq53r1c3Zocapasijuy8v68haqsD/HZ5JM=\",nc=00000001,digest-uri=\"xmpp/ninethumbs.com\",qop=auth,response=7b3c395cf5600668908937ea96b13f26,charset=utf-8";

                if (AuthMethodUsed == AuthMethod.MD5)
                {
                    string strRealm   = XMPPClient.Domain;
                    Match  matchrealm = Regex.Match(strUnbasedChallenge, @"realm=""([^""]+)""", RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
                    if (matchrealm.Success == true)
                    {
                        strRealm = matchrealm.Groups[1].Value;
                    }

                    string strNonce   = "";
                    Match  matchnonce = Regex.Match(strUnbasedChallenge, @"nonce=""([^""]+)""", RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);
                    if (matchnonce.Success == true)
                    {
                        strNonce = matchnonce.Groups[1].Value;
                    }


                    string strQop   = "auth";
                    Match  matchqop = Regex.Match(strUnbasedChallenge, @"qop=""([^""]+)""", RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
                    if (matchqop.Success == true)
                    {
                        strQop = matchqop.Groups[1].Value;
                    }

                    string strAlgo   = "md5-sess";
                    Match  matchalgo = Regex.Match(strUnbasedChallenge, @"algorithm=([^\s,]+)", RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
                    if (matchalgo.Success == true)
                    {
                        strAlgo = matchalgo.Groups[1].Value;
                    }

                    Random rand      = new Random();
                    string strCnonce = rand.Next().ToString("X8").ToLower();
                    // Compute our MD5 response, then base64 it
                    string strResponse = GenerateMD5Response(strAlgo, XMPPClient.UserName, XMPPClient.Domain, XMPPClient.Password, strNonce, strCnonce);

                    string ResponseMessage = MD5Response.Replace("##RESPONSE##", strResponse);
                    XMPPClient.SendRawXML(ResponseMessage);
                }
                else if (AuthMethodUsed == AuthMethod.Plain)
                {
                    /// Send plain text stuff
                    ///
                }
            }
            else if (xmlElem.Name == "{urn:ietf:params:xml:ns:xmpp-sasl}success") /// Success
            {
                XMPPClient.XMPPState = XMPPState.Authenticated;

                if (XMPPClient.UseTLS == true)
                {
                    /// Start a new stream for some strange reason, but don't close the old one.
                    ///
                    OpenStreamStanza open = new OpenStreamStanza(this.XMPPClient);
                    XMPPClient.SendRawXML(open.XML);
                }
                else
                {
                    XMPPClient.XMPPState = XMPPState.CanBind;
                }
            }
            else if (xmlElem.Name == "{urn:ietf:params:xml:ns:xmpp-sasl}failure")  /// Failed to authorize
            {
                XMPPClient.XMPPState = XMPPState.AuthenticationFailed;
            }


            return(false);
        }
Esempio n. 6
0
        /// <summary>
        ///  
        /// </summary>
        /// <param name="stanza"></param>
        /// <returns></returns>
        public override bool NewXMLFragment(XMPPStanza stanza)
        {
            /// Looks like the crippled windows phone 7 libraries can't use output from xsd.exe, have to do this the hard way
            ///
            //XDocument doc = XDocument.Load(new StringReader(stanza.XML));
            //XmlReader reader = XmlReader.Create(new StringReader(stanza.XML));

            stanza.XML = stanza.XML.Replace("stream:", "");  // no support for namespaces in windows phone 7, remove them

            XElement xmlElem = XElement.Parse(stanza.XML);

            if (XMPPClient.XMPPState >= XMPPState.Authenticated)
            {
                if (xmlElem.Name == "features")
                    return true;  /// If we hit this and parse the stream featurs a second time we re-authenticate.  Just return for now

                //if (xmlElem.Name == "stream")
                //{
                //     XMPPClient.XMPPState = XMPPState.CanBind;
                //}
                /// TODO.. see if this new stream supports bind
            }

            if (xmlElem.Name== "features")
            {
                //foreach (XElement node in xmlElem.Descendants())
                //{
                //    System.Diagnostics.Debug.WriteLine(node.Name);
                //}
                var Mechanisms = from mech in xmlElem.Descendants("{urn:ietf:params:xml:ns:xmpp-sasl}mechanism")
                                 select new Mechanism
                                 {
                                     Name = mech.Value,
                                 };
                foreach (Mechanism mech in Mechanisms)
                {
                    if (mech.Name == "DIGEST-MD5")
                        AuthMethodsSupported |= AuthMethod.MD5;
                    else if (mech.Name == "PLAIN")
                        AuthMethodsSupported |= AuthMethod.Plain;
                  //  else if (mech.Name == "X-GOOGLE-TOKEN")
                    //    AuthMethodsSupported |= AuthMethod.googletoken;
                }

                if (AuthMethodsSupported == AuthMethod.NotSpecified)
                    throw new Exception("No acceptable authentication method was supplied");

                var tls = xmlElem.Descendants("{urn:ietf:params:xml:ns:xmpp-tls}starttls");
                if (tls.Count() > 0)
                    FeatureTLS = true;

                if ((FeatureTLS == true) && (XMPPClient.UseTLS == true))
                {
                    /// Tell the man we want to negotiate TLS
                    XMPPClient.SendRawXML(StartTLS);
                }
                else
                {
                    StartAuthentication();
                }

                return true;
            }
            else if (xmlElem.Name == "{urn:ietf:params:xml:ns:xmpp-tls}proceed")
            {
                XMPPClient.XMPPConnection.StartTLS();

                /// After starting TLS, start our normal digest authentication (or plain)
                ///
                StartAuthentication();
            }
            else if (xmlElem.Name == "{urn:ietf:params:xml:ns:xmpp-sasl}challenge")
            {
                /// Build and send response
                ///
                string strChallenge = xmlElem.Value;
                byte[] bData = Convert.FromBase64String(strChallenge);
                string strUnbasedChallenge = System.Text.UTF8Encoding.UTF8.GetString(bData, 0, bData.Length);

                //realm="ninethumbs.com",nonce="oFun3YWfVm/6nHCkNI/9a4XpcWIdQ5RH9E0IDVKH",qop="auth",charset=utf-8,algorithm=md5-sess

                //string strExampleResponse = "dXNlcm5hbWU9InRlc3QiLHJlYWxtPSJuaW5ldGh1bWJzLmNvbSIsbm9uY2U9InJaNjgreS9BeGp2SjJ6cjBCVUNxVUhQcG9ocFE4ZFkzR29JclpJcFkiLGNub25jZT0iVkdFRDNqNHUrUHE1M3IxYzNab2NhcGFzaWp1eTh2NjhoYXFzRC9IWjVKTT0iLG5jPTAwMDAwMDAxLGRpZ2VzdC11cmk9InhtcHAvbmluZXRodW1icy5jb20iLHFvcD1hdXRoLHJlc3BvbnNlPTdiM2MzOTVjZjU2MDA2Njg5MDg5MzdlYTk2YjEzZjI2LGNoYXJzZXQ9dXRmLTg=";
                //bData = Convert.FromBase64String(strExampleResponse);
                //string strUnbasedResponse = System.Text.UTF8Encoding.UTF8.GetString(bData, 0, bData.Length);
                //"username=\"test\",realm=\"ninethumbs.com\",nonce=\"rZ68+y/AxjvJ2zr0BUCqUHPpohpQ8dY3GoIrZIpY\",cnonce=\"VGED3j4u+Pq53r1c3Zocapasijuy8v68haqsD/HZ5JM=\",nc=00000001,digest-uri=\"xmpp/ninethumbs.com\",qop=auth,response=7b3c395cf5600668908937ea96b13f26,charset=utf-8";

                if (AuthMethodUsed == AuthMethod.MD5)
                {
                    string strRealm = XMPPClient.Domain;
                    Match matchrealm = Regex.Match(strUnbasedChallenge, @"realm=""([^""]+)""", RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
                    if (matchrealm.Success == true)
                        strRealm = matchrealm.Groups[1].Value;

                    string strNonce = "";
                    Match matchnonce = Regex.Match(strUnbasedChallenge, @"nonce=""([^""]+)""", RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline);
                    if (matchnonce.Success == true)
                        strNonce = matchnonce.Groups[1].Value;

                    string strQop = "auth";
                    Match matchqop = Regex.Match(strUnbasedChallenge, @"qop=""([^""]+)""", RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
                    if (matchqop.Success == true)
                        strQop = matchqop.Groups[1].Value;

                    string strAlgo = "md5-sess";
                    Match matchalgo = Regex.Match(strUnbasedChallenge, @"algorithm=([^\s,]+)", RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase);
                    if (matchalgo.Success == true)
                        strAlgo = matchalgo.Groups[1].Value;

                    Random rand = new Random();
                    string strCnonce = rand.Next().ToString("X8").ToLower();
                    // Compute our MD5 response, then base64 it
                    string strResponse = GenerateMD5Response(strAlgo, XMPPClient.UserName, XMPPClient.Domain, XMPPClient.Password, strNonce, strCnonce);

                    string ResponseMessage = MD5Response.Replace("##RESPONSE##", strResponse);
                    XMPPClient.SendRawXML(ResponseMessage);
                }
                else if (AuthMethodUsed == AuthMethod.Plain)
                {
                    /// Send plain text stuff
                    ///

                }

            }
            else if (xmlElem.Name == "{urn:ietf:params:xml:ns:xmpp-sasl}success") /// Success
            {
                XMPPClient.XMPPState = XMPPState.Authenticated;

                if (XMPPClient.UseTLS == true)
                {
                    /// Start a new stream for some strange reason, but don't close the old one.
                    ///
                    OpenStreamStanza open = new OpenStreamStanza(this.XMPPClient);
                    XMPPClient.SendRawXML(open.XML);
                }
                else
                {
                    XMPPClient.XMPPState = XMPPState.CanBind;
                }
            }
            else if (xmlElem.Name == "{urn:ietf:params:xml:ns:xmpp-sasl}failure")  /// Failed to authorize
            {
                XMPPClient.XMPPState = XMPPState.AuthenticationFailed;
            }

            return false;
        }
Esempio n. 7
0
        public void ParseStanzas(XMPPConnection connection, XMPPClient XMPPClient)
        {
            try
               {

              string CurrentNodeName = null;
              XMPPXMLNode objNode = null;

              while ( (objNode = ReadNextBlock(false)) != null)
              {
                 //System.Diagnostics.Debug.WriteLine("**ReadNextBlock got: {0}", objNode.Name);
                 if ((objNode.NodeType == XmlNodeType.XmlDeclaration) || (objNode.NodeType == XmlNodeType.Comment) || (objNode.NodeType == XmlNodeType.Whitespace))
                    continue;

                 if ((objNode.NodeType == XmlNodeType.EndElement) && (objNode.Name == "stream:stream"))
                 {
                    Flush();

                     /// We've been closed, tell whoever
                     ///
                    connection.GracefulDisconnect();
                 }
                 else if (objNode.Name == "stream:stream")
                 {
                     System.Diagnostics.Debug.WriteLine("Got stream beggining fragment");
                    FoundStreamBeginning = true;
                    To = objNode.GetAttribute("to");
                    From = objNode.GetAttribute("from");
                    Id = objNode.GetAttribute("id");
                    Version = objNode.GetAttribute("version");
                    Language = objNode.GetAttribute("xml:lang");
                    CurrentNodeName = null;
                    //System.Diagnostics.Debug.WriteLine("Setting CurrentNodeName to null");

                    Flush();

                    if (XMPPClient.XMPPState == XMPPState.Authenticated)
                        XMPPClient.XMPPState = XMPPState.CanBind;

                 }
                 else if ( (objNode.NodeType == XmlNodeType.EndElement) && (CurrentNodeName == null) ) /// Must be a complete element
                 {
                     string strXML = FlushGet();
                     //System.Diagnostics.Debug.WriteLine("Got unpaired end fragment: {0}", strXML);

                     XMPPStanza stanza = new XMPPStanza(strXML);
                     connection.FireStanzaReceived(stanza);
                 }
                 else
                 {
                     if (CurrentNodeName == null)
                     {
                         CurrentNodeName = objNode.Name;
                         //System.Diagnostics.Debug.WriteLine("Setting CurrentNodeName to : {0}", CurrentNodeName);

                     }
                     else
                     {
                         if (objNode.Name == CurrentNodeName) /// Found the end tag
                         {
                             //System.Diagnostics.Debug.WriteLine("Found End tag to CurrentNodeName: {0}, setting to null", CurrentNodeName);
                             // Extract all the text up to this position
                             CurrentNodeName = null;

                             string strXML = FlushGet();

                             XMPPStanza stanza = new XMPPStanza(strXML);
                             connection.FireStanzaReceived(stanza);
                         }
                     }
                 }

              }
               }
               catch (Exception)
               {

               }
               finally
               {
               }
        }
Esempio n. 8
0
        public void ParseStanzas(XMPPConnection connection, XMPPClient XMPPClient)
        {
            try
            {
                string      CurrentNodeName = null;
                XMPPXMLNode objNode         = null;

                while ((objNode = ReadNextBlock(false)) != null)
                {
                    //System.Diagnostics.Debug.WriteLine("**ReadNextBlock got: {0}", objNode.Name);
                    if ((objNode.NodeType == XmlNodeType.XmlDeclaration) || (objNode.NodeType == XmlNodeType.Comment) || (objNode.NodeType == XmlNodeType.Whitespace))
                    {
                        continue;
                    }


                    if ((objNode.NodeType == XmlNodeType.EndElement) && (objNode.Name == "stream:stream"))
                    {
                        Flush();

                        /// We've been closed, tell whoever
                        ///
                        connection.GracefulDisconnect();
                    }
                    else if (objNode.Name == "stream:stream")
                    {
                        System.Diagnostics.Debug.WriteLine("Got stream beggining fragment");
                        FoundStreamBeginning = true;
                        To              = objNode.GetAttribute("to");
                        From            = objNode.GetAttribute("from");
                        Id              = objNode.GetAttribute("id");
                        Version         = objNode.GetAttribute("version");
                        Language        = objNode.GetAttribute("xml:lang");
                        CurrentNodeName = null;
                        //System.Diagnostics.Debug.WriteLine("Setting CurrentNodeName to null");

                        Flush();

                        if (XMPPClient.XMPPState == XMPPState.Authenticated)
                        {
                            XMPPClient.XMPPState = XMPPState.CanBind;
                        }
                    }
                    else if ((objNode.NodeType == XmlNodeType.EndElement) && (CurrentNodeName == null)) /// Must be a complete element
                    {
                        string strXML = FlushGet();
                        //System.Diagnostics.Debug.WriteLine("Got unpaired end fragment: {0}", strXML);

                        XMPPStanza stanza = new XMPPStanza(strXML);
                        connection.FireStanzaReceived(stanza);
                    }
                    else
                    {
                        if (CurrentNodeName == null)
                        {
                            CurrentNodeName = objNode.Name;
                            //System.Diagnostics.Debug.WriteLine("Setting CurrentNodeName to : {0}", CurrentNodeName);
                        }
                        else
                        {
                            if (objNode.Name == CurrentNodeName) /// Found the end tag
                            {
                                //System.Diagnostics.Debug.WriteLine("Found End tag to CurrentNodeName: {0}, setting to null", CurrentNodeName);
                                // Extract all the text up to this position
                                CurrentNodeName = null;

                                string strXML = FlushGet();

                                XMPPStanza stanza = new XMPPStanza(strXML);
                                connection.FireStanzaReceived(stanza);
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
            finally
            {
            }
        }
Esempio n. 9
0
 /// <summary>
 /// A new XML fragment has been received
 /// </summary>
 /// <param name="node"></param>
 /// <returns>returns true if we handled this fragment, false if other wise</returns>
 public virtual bool NewXMLFragment(XMPPStanza stanza)
 {
     return(false);
 }