Esempio n. 1
0
        /// <summary>
        /// Create a CapsManager from an existing Disco Node.  Pass in null
        /// to use a placeholder.
        /// </summary>
        /// <param name="node"></param>
        public CapsManager(DiscoNode node)
        {
            this.OnStreamChanged += new Kixeye.Bedrock.ObjectHandler(CapsManager_OnStreamChanged);

            if (node == null)
                m_disco = new DiscoNode(new JID(null, "placeholder", null), null);
            else
                m_disco = node;
        }
Esempio n. 2
0
 private void RequestItems(DiscoNode node)
 {
     lock (node)
     {
         if (!node.PendingItems)
         {
             IQ iq = node.ItemsIQ(m_stream.Document);
             Kixeye.Jabber.Server.JabberService js = m_stream as Kixeye.Jabber.Server.JabberService;
             if (js != null)
                 iq.From = js.ComponentID;
             BeginIQ(iq, new Kixeye.Jabber.Connection.IqCB(GotItems), node);
         }
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Deletes the cache.
 /// </summary>
 public void Clear()
 {
     lock (m_items)
     {
         m_root = null;
         m_items.Clear();
     }
 }
Esempio n. 4
0
 /// <summary>
 /// Creates nodes and ensure that they are cached.
 /// </summary>
 /// <param name="jid">JID associated with DiscoNode.</param>
 /// <param name="node">Node associated with DiscoNode.</param>
 /// <returns>
 /// If DiscoNode exists, returns the found node.
 /// Otherwise it creates the node and return it.
 /// </returns>
 public DiscoNode GetNode(JID jid, string node)
 {
     lock (m_items)
     {
         string key = DiscoNode.GetKey(jid, node);
         DiscoNode n = (DiscoNode)m_items[key];
         if (n == null)
         {
             n = new DiscoNode(jid, node);
             m_items.Add(key, n);
         }
         return n;
     }
 }
Esempio n. 5
0
 public void Call(DiscoNode node)
 {
     if (callback != null)
         callback(manager, node, state);
 }
Esempio n. 6
0
 public void GotRootItems(DiscoManager manager, DiscoNode node, object state)
 {
     m_outstanding = node.Children.Count;
     foreach (DiscoNode n in node.Children)
         manager.BeginGetFeatures(n, new DiscoNodeHandler(GotFeatures), state);
 }
Esempio n. 7
0
            public void GotFeatures(DiscoManager manager, DiscoNode node, object state)
            {

                // yes, yes, this may call the handler more than once in multi-threaded world.  Punt for now.
                if (m_handler != null)
                {
                    if (node.HasFeature(m_URI))
                    {
                        m_handler(manager, node, state);
                        m_handler = null;
                    }
                }

                if (Interlocked.Decrement(ref m_outstanding) == 0)
                {
                    if (m_handler != null)
                        m_handler(manager, null, state);
                }
            }
Esempio n. 8
0
        /// <summary>
        /// Retrieves the child items associated with this node,
        /// and then calls back on the handler.
        /// If the information is in the cache, handler gets
        /// called right now.
        /// </summary>
        /// <param name="node">Disco node to search.</param>
        /// <param name="handler">Callback that gets called with the items.</param>
        /// <param name="state">Context to pass back to caller when complete</param>
        public void BeginGetItems(DiscoNode node, DiscoNodeHandler handler, object state)
        {
            if (node == null)
                node = Root;

            if (node.AddItemsCallback(this, handler, state))
                RequestItems(node);
        }
Esempio n. 9
0
        /// <summary>
        /// Retrieves the features associated with this node and
        /// then calls back on the handler.
        /// If the information is in the cache, handler gets called right now.
        /// </summary>
        /// <param name="node">Node to look for.</param>
        /// <param name="handler">Callback to use afterwards.</param>
        /// <param name="state">Context to pass back to caller when complete</param>
        public void BeginGetFeatures(DiscoNode node, DiscoNodeHandler handler, object state)
        {
            if (node == null)
                node = Root;

            if (node.AddFeatureCallback(this, handler, state))
                RequestInfo(node);
        }
Esempio n. 10
0
        private void GotCaps(DiscoManager m, DiscoNode node, object state)
        {
            // timeout
            if (node == null)
                return;

            string ver = (string)state;
            string calc = CalculateVer(node);
            if (ver != calc)
            {
                Debug.WriteLine("WARNING: invalid caps ver hash: '" + ver + "' != '" + calc + "'");
                if (node.Info != null)
                    Debug.WriteLine(node.Info.OuterXml);
                return;
            }
            m_cache[ver] = node.Info;
        }
Esempio n. 11
0
        private string CalculateVer(DiscoNode n)
        {
            if (m_hash == null)
                return null;

            // 1. Initialize an empty string S.
            StringBuilder S = new StringBuilder();

            // 2. Sort the service discovery identities [16] by category and then by type
            // (if it exists) and then by xml:lang (if it exists), formatted as
            // CATEGORY '/' [TYPE] '/' [LANG] '/' [NAME]. Note that each slash is
            // included even if the TYPE, LANG, or NAME is not included.
            Ident[] ids = n.GetIdentities();
            Array.Sort(ids);

            // 3. For each identity, append the 'category/type/lang/name' to S, followed by
            // the '<' character.
            foreach (Ident id in ids)
            {
                S.Append(id.Key);
                S.Append(SEP);
            }

            // 4. Sort the supported service discovery features.
            string[] features = n.FeatureNames;
            Array.Sort(features);

            // 5. For each feature, append the feature to S, followed by the '<' character.
            foreach (string feature in features)
            {
                S.Append(feature);
                S.Append(SEP);
            }

            // 6. If the service discovery information response includes XEP-0128 data forms, 
            // sort the forms by the FORM_TYPE (i.e., by the XML character 
            // data of the <value/> element).
            Data[] ext = n.Extensions;
            if (ext != null)
            {
                Array.Sort(ext, new FormTypeComparer());
                foreach (Data x in ext)  
                {
                    // For each extended service discovery information form:

                    // 1. Append the XML character data of the FORM_TYPE field's <value/> 
                    // element, followed by the '<' character.
                    S.Append(x.FormType);
                    S.Append(SEP);

                    // 2. Sort the fields by the value of the "var" attribute.
                    Kixeye.Bedrock.Collections.Tree fields = new Kixeye.Bedrock.Collections.Tree();
                    foreach (Field f in x.GetFields())
                        fields[f.Var] = f;

                    // 3. For each field:
                    foreach (System.Collections.DictionaryEntry entry in fields)
                    {
                        Field f = (Field)entry.Value;
                        if (f.Var == "FORM_TYPE")
                            continue;

                        // 1. Append the value of the "var" attribute, followed by the '<' character.
                        S.Append(f.Var);
                        S.Append(SEP);

                        // 2. Sort values by the XML character data of the <value/> element.
                        string[] values = f.Vals;
                        Array.Sort(values);
                        foreach (string v in values)
                        {
                            // 3. For each <value/> element, append the XML character data, followed by the '<' character.
                            S.Append(v);
                            S.Append(SEP);
                        }
                    }
                }
            }

            // Ensure that S is encoded according to the UTF-8 encoding (RFC 3269 [16]).
            byte[] input = Encoding.UTF8.GetBytes(S.ToString());

            // Compute the verification string by hashing S using the algorithm specified
            // in the 'hash' attribute (e.g., SHA-1 as defined in RFC 3174 [17]). The hashed
            // data MUST be generated with binary output and encoded using Base64 as specified
            // in Section 4 of RFC 4648 [18] (note: the Base64 output MUST NOT include
            // whitespace and MUST set padding bits to zero). [19]
            HashAlgorithm hasher = GetHasher(m_hash);
            byte[] hash = hasher.ComputeHash(input, 0, input.Length);
            return Convert.ToBase64String(hash);
        }
Esempio n. 12
0
        public void ComplexGenerationExample()
        {

            XmlDocument doc = new XmlDocument();
            doc.LoadXml("<book xml:lang='en'/>");
            XmlElement book = doc.DocumentElement;
            foreach (XmlAttribute attr in book.Attributes)
            {
                System.Console.WriteLine(attr.Name);
            }

            XmlElement root = doc.DocumentElement;

            DiscoInfo info = new DiscoInfo(doc);
            info.AddFeature("http://kixeye.jabber.org/protocol/muc");
            info.AddFeature("http://kixeye.jabber.org/protocol/disco#info");
            info.AddFeature("http://kixeye.jabber.org/protocol/disco#items");
            info.AddIdentity("client", "pc", "Psi 0.9.1", "en");
            info.AddIdentity("client", "pc", "\u03a8 0.9.1", "el");
            Data x = info.CreateExtension();
            x.FormType = "urn:xmpp:dataforms:softwareinfo";
            x.AddField("ip_version").Vals = new string[] { "ipv4", "ipv6" };
            x.AddField("os").Val = "Mac";
            x.AddField("os_version").Val = "10.5.1";
            x.AddField("software").Val = "Psi";
            x.AddField("software_version").Val = "0.11";

            DiscoNode dn = new DiscoNode(new JID(null, "placeholder", null), null);
            dn.AddInfo(info);

            CapsManager cm = new CapsManager(dn);
            Assert.AreEqual("8lu+88MRxmKM7yO3MEzY7YmTsWs=", cm.Ver);
        }