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

            byte[] bStanza = System.Text.UTF8Encoding.UTF8.GetBytes(strSend);
            return(this.Send(bStanza));
        }
コード例 #3
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,
                };

                AuthMethodsSupported = AuthMethod.NotSpecified;
                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) && (XMPPClient.XMPPState < XMPPState.Authenticated))
                {
                    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;
                }

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

                var bind = xmlElem.Descendants("{urn:ietf:params:xml:ns:xmpp-bind}bind");
                if (bind.Count() > 0)
                {
                    XMPPClient.XMPPState = XMPPState.CanBind;
                    return(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)
                ///
                /// Bug or something changed after RFC.  Now 6120 says we must reopen the stream, our response should not have a TLS option in it
                ///
                FeatureTLS = false;
                OpenStreamStanza open = new OpenStreamStanza(this.XMPPClient);
                XMPPClient.SendRawXML(open.XML);

                //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);

                if (strUnbasedChallenge.IndexOf("rspauth") == 0)
                {
                    string ResponseMessage = MD5Response.Replace("##RESPONSE##", "=");
                    XMPPClient.SendRawXML(ResponseMessage);
                    return(false);
                }
                //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;

                OpenStreamStanza open = new OpenStreamStanza(this.XMPPClient);
                XMPPClient.SendRawXML(open.XML);

                //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);
        }
コード例 #4
0
        int NodeStackDepth     = 0; /// Used in case we have a node inside a node...  ex: <iq><elemeent><iq><otherjunk>lksjdfl</otherjunk></iq></elemeent></iq>

        public void ParseStanzas(XMPPConnection connection, XMPPClient XMPPClient)
        {
            try
            {
                XMPPXMLNode objNode = null;

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

                    //for stream management XEP 0198// for request
                    if (objNode.Name == "r")
                    {
                        XMPPClient.FireDelegateStreamManagementHandler(objNode.OuterXML.ToString());
                    }
                    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(string.Format("Got unpaired end fragment: {0}", strXML));

                        XMPPStanza stanza = new XMPPStanza(strXML);
                        connection.FireStanzaReceived(stanza);
                    }
                    else
                    {
                        if (CurrentNodeName == null)
                        {
                            CurrentNodeName = objNode.Name;
                            NodeStackDepth  = 0;
                            //System.Diagnostics.Debug.WriteLine(string.Format("Setting CurrentNodeName to : {0}", CurrentNodeName));
                        }
                        else
                        {
                            if (objNode.Name == CurrentNodeName) /// Found the end tag
                            {
                                if (objNode.NodeType == XmlNodeType.EndElement)
                                {
                                    if (NodeStackDepth == 0)
                                    {
                                        //System.Diagnostics.Debug.WriteLine(string.Format("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);
                                    }
                                    else
                                    {
                                        NodeStackDepth--;
                                    }
                                }
                                else
                                {
                                    //System.Diagnostics.Debug.WriteLine(string.Format("Found nested node with the same name as our CurrentNodeName, incrementing NodeStackDepth: {0}", CurrentNodeName));
                                    NodeStackDepth++;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
            finally
            {
            }
        }
コード例 #5
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);
 }