Exemple #1
0
        public async Task Processed(QuestionView QuestionView)
        {
            MainWindow.UpdateGui(() =>
            {
                int i = QuestionView.QuestionListView.SelectedIndex;
                int c;

                QuestionView.Details.Children.Clear();
                QuestionView.QuestionListView.Items.Remove(this);

                c = QuestionView.QuestionListView.Items.Count;
                if (c == 0)
                {
                    MainWindow.currentInstance.CloseTab_Executed(this, null);
                }
                else if (i < c)
                {
                    QuestionView.QuestionListView.SelectedIndex = i;
                }
            });

            await Database.Delete(this);

            LinkedList <Question> ToRemove = null;

            foreach (Question Question in QuestionView.QuestionListView.Items)
            {
                if (Question.IsResolvedBy(this))
                {
                    if (ToRemove is null)
                    {
                        ToRemove = new LinkedList <Question>();
                    }

                    ToRemove.AddLast(Question);
                }
            }

            if (ToRemove != null)
            {
                MainWindow.UpdateGui(() =>
                {
                    foreach (Question Question in ToRemove)
                    {
                        QuestionView.QuestionListView.Items.Remove(Question);
                    }

                    if (QuestionView.QuestionListView.Items.Count == 0)
                    {
                        MainWindow.currentInstance.CloseTab_Executed(this, null);
                    }
                });

                foreach (Question Question in ToRemove)
                {
                    await Database.Delete(Question);
                }
            }
        }
        private void UpdateTokenSource(string Token, string From)
        {
            LinkedList <KeyValuePair <DateTime, string> > ToRemove = null;
            Triplet <string, DateTime, X509Certificate2>  Rec;
            DateTime TP      = DateTime.Now;
            DateTime Timeout = TP.AddMinutes(-1);

            lock (this.synchObject)
            {
                if (this.sourceByToken.TryGetValue(Token, out Rec))
                {
                    this.sourceByToken.Remove(Token);
                    this.tokenByLastAccess.Remove(Rec.Value2);
                }

                foreach (KeyValuePair <DateTime, string> P in tokenByLastAccess)
                {
                    if (P.Key <= Timeout)
                    {
                        if (ToRemove == null)
                        {
                            ToRemove = new LinkedList <KeyValuePair <DateTime, string> > ();
                        }

                        ToRemove.AddLast(P);
                    }
                    else
                    {
                        break;
                    }
                }

                if (ToRemove != null)
                {
                    foreach (KeyValuePair <DateTime, string> P in ToRemove)
                    {
                        this.tokenByLastAccess.Remove(P.Key);
                        this.sourceByToken.Remove(P.Value);
                    }
                }

                while (this.tokenByLastAccess.ContainsKey(TP))
                {
                    TP = TP.AddTicks(gen.Next(1, 10));
                }

                this.sourceByToken [Token]  = new Triplet <string, DateTime, X509Certificate2> (From, TP, null);
                this.tokenByLastAccess [TP] = Token;
            }
        }
Exemple #3
0
        private void TimerCallback(object State)
        {
            LinkedList <SensorDataEventArgs> ToRemove = null;
            DateTime Now = DateTime.Now;

            lock (this.synchObj)
            {
                foreach (KeyValuePair <DateTime, SensorDataEventArgs> Pair in this.byTimeout)
                {
                    if (Pair.Key > Now)
                    {
                        break;
                    }

                    if (ToRemove == null)
                    {
                        ToRemove = new LinkedList <SensorDataEventArgs> ();
                    }

                    ToRemove.AddLast(Pair.Value);
                }
            }

            if (ToRemove != null)
            {
                foreach (SensorDataEventArgs e in ToRemove)
                {
                    lock (this.synchObj)
                    {
                        this.byTimeout.Remove(e.Timeout);
                        this.receiving.Remove(e.SeqNr);

                        if (this.byTimeout.Count == 0 && this.timer != null)
                        {
                            this.timer.Dispose();
                            this.timer = null;
                        }
                    }

                    e.Receiving();
                    e.ReadoutState = ReadoutState.Timeout;
                    e.Done         = true;
                    e.DoCallback(this);
                }
            }
        }
Exemple #4
0
        internal bool UnregisterSubscription(IPEndPoint RemoteEndpoint, ulong Token)
        {
            string Prefix = RemoteEndpoint.ToString() + " ";
            string Key    = Prefix + Token.ToString();

            lock (this.registrations)
            {
                this.registeredMessages = null;
                if (this.registrations.Remove(Key))
                {
                    return(true);
                }

                if (Token == 0)
                {
                    LinkedList <string> ToRemove = null;

                    foreach (string Key2 in this.registrations.Keys)
                    {
                        if (Key2.StartsWith(Prefix))
                        {
                            if (ToRemove is null)
                            {
                                ToRemove = new LinkedList <string>();
                            }

                            ToRemove.AddLast(Key2);
                        }
                    }

                    if (ToRemove != null)
                    {
                        foreach (string Key2 in ToRemove)
                        {
                            this.registrations.Remove(Key2);
                        }

                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #5
0
        private void RecalcTimerLocked()
        {
            if (this.timer != null)
            {
                this.timer.Dispose();
                this.timer = null;
            }

            LinkedList <DateTime> ToRemove = null;
            DateTime Now = DateTime.Now;
            TimeSpan TimeLeft;

            foreach (KeyValuePair <DateTime, ScheduledEvent> Event in this.events)
            {
                TimeLeft = Event.Key - Now;
                if (TimeLeft <= TimeSpan.Zero)
                {
                    if (ToRemove == null)
                    {
                        ToRemove = new LinkedList <DateTime>();
                    }

                    ToRemove.AddLast(Event.Key);

                    Task.Run((Action)Event.Value.Execute);
                }
                else
                {
                    this.timer = new Timer(this.TimerElapsed, null, TimeLeft, OnlyOnce);
                    break;
                }
            }

            if (ToRemove != null)
            {
                foreach (DateTime TP in ToRemove)
                {
                    this.events.Remove(TP);
                }
            }
        }
        /// <summary>
        /// Reports a set of newly measured field values. Conditions in existing event subscriptions will be analyzed and any corresponding events sent.
        /// </summary>
        /// <param name="FieldValues">Field values.</param>
        public void MomentaryValuesUpdated(params KeyValuePair <string, double>[] FieldValues)
        {
            Dictionary <Subscription, bool> ToUpdate = null;
            LinkedList <Subscription>       ToRemove = null;
            List <Subscription>             Subscriptions;
            DateTime    Now = DateTime.Now;
            TimeSpan    SinceLast;
            XmppContact Contact;
            bool        MaxIntervalReached;
            bool        Update;

            lock (this.synchObj)
            {
                foreach (KeyValuePair <string, double> Pair in FieldValues)
                {
                    this.currentValues [Pair.Key] = Pair.Value;
                    if (this.subscriptionsByField.TryGetValue(Pair.Key, out Subscriptions))
                    {
                        foreach (Subscription Subscription in Subscriptions)
                        {
                            Contact = this.client.GetLocalContact(Subscription.From);
                            if (Contact == null || (Contact.Subscription != RosterItemSubscription.Both && Contact.Subscription != RosterItemSubscription.To))
                            {
                                if (ToRemove == null)
                                {
                                    ToRemove = new LinkedList <Subscription> ();
                                }

                                ToRemove.AddLast(Subscription);
                                continue;
                            }

                            if (Contact.LastPresence == null || Contact.LastPresence.Status == PresenceStatus.Offline)
                            {
                                continue;
                            }

                            SinceLast = Now - Subscription.LastUpdate;
                            if (SinceLast < Subscription.MinInterval)
                            {
                                continue;
                            }

                            Update = MaxIntervalReached = SinceLast >= Subscription.MaxInterval;

                            foreach (Condition Condition in Subscription.Conditions)
                            {
                                if (Condition.Trigger(Pair.Key, Pair.Value, MaxIntervalReached))
                                {
                                    Update = true;
                                    break;
                                }
                            }

                            if (Update)
                            {
                                if (ToUpdate == null)
                                {
                                    ToUpdate = new Dictionary <Subscription, bool> ();
                                }

                                ToUpdate [Subscription] = true;
                                Subscription.LastUpdate = Now;
                            }
                        }
                    }
                }
            }

            if (ToUpdate != null)
            {
                foreach (Subscription Subscription in ToUpdate.Keys)
                {
                    this.SendFields(Subscription.SeqNr, Subscription.From, Subscription.Request);
                }
            }

            if (ToRemove != null)
            {
                foreach (Subscription Subscription in ToRemove)
                {
                    this.RemoveSubscription(Subscription.Key, Subscription.SeqNr);
                }
            }
        }
Exemple #7
0
        private void OnMessage(XmppClient Client, XmppMessage Message)
        {
            if (Message.MessageType != MessageType.Chat)
            {
                return;
            }

            string s = Message.Body.Trim();

            if (string.IsNullOrEmpty(s))
            {
                return;
            }

            DateTime             Now      = DateTime.Now;
            DateTime             Timeout  = Now.AddMinutes(-15);
            LinkedList <Session> ToRemove = null;
            Session Session;
            string  s2;
            int     i;

            lock (this.sessionByJid)
            {
                foreach (KeyValuePair <DateTime, Session> P in this.sessionByLastAccess)
                {
                    if (P.Key <= Timeout)
                    {
                        if (ToRemove == null)
                        {
                            ToRemove = new LinkedList <Session> ();
                        }

                        ToRemove.AddLast(P.Value);
                    }
                    else
                    {
                        break;
                    }
                }

                if (ToRemove != null)
                {
                    foreach (Session S in ToRemove)
                    {
                        this.sessionByJid.Remove(S.From);
                        this.sessionByLastAccess.Remove(S.LastAccess);
                    }
                }

                if (this.sessionByJid.TryGetValue(Message.From, out Session))
                {
                    this.sessionByLastAccess.Remove(Session.LastAccess);
                }
                else
                {
                    Session      = new Session();
                    Session.From = Message.From;
                    this.sessionByJid [Session.From] = Session;
                }

                while (this.sessionByLastAccess.ContainsKey(Now))
                {
                    Now = Now.AddTicks(gen.Next(1, 10));
                }

                Session.LastAccess             = Now;
                this.sessionByLastAccess [Now] = Session;
            }

            switch (s)
            {
            case "#":
                this.SendMenu(Client, Message.From, true, string.Empty, Session);
                break;

            case "##":
                this.SendMenu(Client, Message.From, false, string.Empty, Session);
                break;

            case "?":
                if (this.provisioning == null)
                {
                    this.SendErrorMessage(Message.From, "No provisioning server has been found, so readout through the chat interface is not allowed.", Session);
                }
                else if (this.sensor == null)
                {
                    this.SendErrorMessage(Message.From, "No sensor interface provided.", Session);
                }
                else
                {
                    ReadoutRequest Request = new ReadoutRequest(ReadoutType.MomentaryValues, DateTime.MinValue, DateTime.MaxValue);
                    this.provisioning.CanRead(Request, Message.From, this.CanReadResponse, new object[] { Message.From, Session });
                }
                break;

            case "??":
                if (this.provisioning == null)
                {
                    this.SendErrorMessage(Message.From, "No provisioning server has been found, so readout through the chat interface is not allowed.", Session);
                }
                else if (this.sensor == null)
                {
                    this.SendErrorMessage(Message.From, "No sensor interface provided.", Session);
                }
                else
                {
                    ReadoutRequest Request = new ReadoutRequest(ReadoutType.All, DateTime.MinValue, DateTime.MaxValue);
                    this.provisioning.CanRead(Request, Message.From, this.CanReadResponse, new object[] { Message.From, Session });
                }
                break;

            case "html+":
                Session.Html = true;
                Client.SendMessage(Message.From, "HTML mode turned on.", MessageType.Chat);
                break;

            case "html-":
                Session.Html = false;
                Client.SendMessage(Message.From, "HTML mode turned off.", MessageType.Chat);
                break;

            case "=?":
            case "!?":
                if (this.provisioning == null)
                {
                    this.SendErrorMessage(Message.From, "No provisioning server has been found, so control  through the chat interface is not allowed.", Session);
                }
                else if (this.control == null)
                {
                    this.SendErrorMessage(Message.From, "No control interface provided.", Session);
                }
                else
                {
                    this.provisioning.CanControl(Message.From, this.CanControlListParametersResponse, new object[] {
                        Message.From,
                        Session
                    }, null, null, null, this.control.Parameters, null);
                }
                break;

            default:
                if (s.EndsWith("??"))
                {
                    if (this.provisioning == null)
                    {
                        this.SendErrorMessage(Message.From, "No provisioning server has been found, so readout through the chat interface is not allowed.", Session);
                    }
                    else if (this.sensor == null)
                    {
                        this.SendErrorMessage(Message.From, "No sensor interface provided.", Session);
                    }
                    else
                    {
                        ReadoutRequest Request = new ReadoutRequest(ReadoutType.All, DateTime.MinValue, DateTime.MaxValue, null, new string[] { s.Substring(0, s.Length - 2) });
                        this.provisioning.CanRead(Request, Message.From, this.CanReadResponse, new object[] { Message.From, Session });
                    }
                }
                else if (s.EndsWith("?"))
                {
                    if (this.provisioning == null)
                    {
                        this.SendErrorMessage(Message.From, "No provisioning server has been found, so readout through the chat interface is not allowed.", Session);
                    }
                    else if (this.sensor == null)
                    {
                        this.SendErrorMessage(Message.From, "No sensor interface provided.", Session);
                    }
                    else
                    {
                        ReadoutRequest Request = new ReadoutRequest(ReadoutType.MomentaryValues, DateTime.MinValue, DateTime.MaxValue, null, new string[] { s.Substring(0, s.Length - 1) });
                        this.provisioning.CanRead(Request, Message.From, this.CanReadResponse, new object[] { Message.From, Session });
                    }
                }
                else if ((i = s.IndexOfAny(controlDelimiters)) > 0)
                {
                    IControlParameter Parameter;

                    if (this.provisioning == null)
                    {
                        this.SendErrorMessage(Message.From, "No provisioning server has been found, so control operations through the chat interface is not allowed.", Session);
                    }
                    else if (this.control == null)
                    {
                        this.SendErrorMessage(Message.From, "No control interface provided.", Session);
                    }
                    else if ((Parameter = this.control [s2 = s.Substring(0, i).Trim()]) == null)
                    {
                        this.SendErrorMessage(Message.From, "No control parameter named '" + s2 + "' found.", Session);
                    }
                    else
                    {
                        this.provisioning.CanControl(Message.From, this.CanControlParameterResponse, new object[] {
                            Message.From,
                            Session,
                            Parameter,
                            s2,
                            s.Substring(i + 1).Trim()
                        }, null, null, null, new string[] { s2 }, null);
                    }
                }
                else
                {
                    this.SendMenu(Client, Message.From, true, "Hello. Following is a list of commands you can use when chatting with me.\r\n\r\n", Session);
                }
                break;
            }
        }
Exemple #8
0
        private async void GetFormHandler(object Sender, IqEventArgs e)
        {
            try
            {
                LinkedList <IThingReference> Nodes = null;
                XmlElement E;
                string     ServiceToken = XML.Attribute(e.Query, "st");
                string     DeviceToken  = XML.Attribute(e.Query, "dt");
                string     UserToken    = XML.Attribute(e.Query, "ut");

                foreach (XmlNode N in e.Query.ChildNodes)
                {
                    E = N as XmlElement;
                    if (E is null)
                    {
                        continue;
                    }

                    if (E.LocalName == "nd")
                    {
                        if (Nodes is null)
                        {
                            Nodes = new LinkedList <IThingReference>();
                        }

                        string NodeId    = XML.Attribute(E, "id");
                        string SourceId  = XML.Attribute(E, "src");
                        string Partition = XML.Attribute(E, "pt");

                        if (this.OnGetNode is null)
                        {
                            Nodes.AddLast(new ThingReference(NodeId, SourceId, Partition));
                        }
                        else
                        {
                            IThingReference Ref = await this.OnGetNode(NodeId, SourceId, Partition);

                            if (Ref is null)
                            {
                                throw new ItemNotFoundException("Node not found.", e.IQ);
                            }

                            Nodes.AddLast(Ref);
                        }
                    }
                }

                ControlParameter[] Parameters;

                if (Nodes is null)
                {
                    Parameters = await this.GetControlParameters(null);

                    if (Parameters is null)
                    {
                        NotFound(e);
                        return;
                    }
                }
                else
                {
                    Dictionary <string, ControlParameter> Parameters1;
                    Dictionary <string, ControlParameter> Parameters2;
                    LinkedList <string> ToRemove = null;

                    Parameters  = null;
                    Parameters1 = null;

                    foreach (IThingReference Node in Nodes)
                    {
                        if (Parameters1 is null)
                        {
                            Parameters = await this.GetControlParameters(Node);

                            if (Parameters is null)
                            {
                                NotFound(e);
                                return;
                            }

                            Parameters1 = new Dictionary <string, ControlParameter>();

                            foreach (ControlParameter P in Parameters)
                            {
                                Parameters1[P.Name] = P;
                            }
                        }
                        else
                        {
                            Parameters2 = await this.GetControlParametersByName(Node);

                            if (Parameters2 is null)
                            {
                                NotFound(e);
                                return;
                            }

                            foreach (KeyValuePair <string, ControlParameter> P in Parameters1)
                            {
                                if (!Parameters2.TryGetValue(P.Key, out ControlParameter P2) || !P.Value.Equals(P2))
                                {
                                    if (ToRemove is null)
                                    {
                                        ToRemove = new LinkedList <string>();
                                    }

                                    ToRemove.AddLast(P.Key);
                                }
                            }

                            if (ToRemove != null)
                            {
                                foreach (string Key in ToRemove)
                                {
                                    Parameters1.Remove(Key);
                                }

                                ToRemove = null;
                            }
                        }
                    }

                    List <ControlParameter> Left = new List <ControlParameter>();

                    foreach (ControlParameter P in Parameters)
                    {
                        if (Parameters1.ContainsKey(P.Name))
                        {
                            Left.Add(P);
                        }
                    }

                    Parameters = Left.ToArray();
                }

                if (this.provisioningClient != null)
                {
                    int      i, c = Parameters.Length;
                    string[] ParameterNames = new string[c];

                    for (i = 0; i < c; i++)
                    {
                        ParameterNames[i] = Parameters[i].Name;
                    }

                    this.provisioningClient.CanControl(e.FromBareJid, Nodes, ParameterNames,
                                                       ServiceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       DeviceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       UserToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       (sender2, e2) =>
                    {
                        if (e2.Ok && e2.CanControl)
                        {
                            if (e2.ParameterNames != null)
                            {
                                List <ControlParameter> Parameters2 = new List <ControlParameter>();

                                foreach (ControlParameter P in Parameters)
                                {
                                    if (Array.IndexOf <string>(e2.ParameterNames, P.Name) >= 0)
                                    {
                                        Parameters2.Add(P);
                                    }
                                }

                                Parameters = Parameters2.ToArray();

                                if (Parameters.Length == 0)
                                {
                                    e.IqError("<error type='cancel'><forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" +
                                              "<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>Access denied.</text></error>");
                                    return;
                                }
                            }

                            this.ReturnForm(e, Parameters, Nodes);
                        }
                        else
                        {
                            e.IqError("<error type='cancel'><forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" +
                                      "<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>Access denied.</text></error>");
                        }
                    }, null);
                }
                else
                {
                    this.ReturnForm(e, Parameters, Nodes);
                }
            }
            catch (Exception ex)
            {
                e.IqError(ex);
            }
        }
Exemple #9
0
        private async void GetFormHandler(object Sender, IqEventArgs e)
        {
            try
            {
                LinkedList <ThingReference> Nodes = null;
                XmlElement E;

                foreach (XmlNode N in e.Query.ChildNodes)
                {
                    E = N as XmlElement;
                    if (E == null)
                    {
                        continue;
                    }

                    if (E.LocalName == "nd")
                    {
                        if (Nodes == null)
                        {
                            Nodes = new LinkedList <ThingReference>();
                        }

                        Nodes.AddLast(new ThingReference(
                                          XML.Attribute(E, "id"),
                                          XML.Attribute(E, "src"),
                                          XML.Attribute(E, "pt")));
                    }
                }

                ControlParameter[] Parameters;

                if (Nodes == null)
                {
                    Parameters = await this.GetControlParameters(null);

                    if (Parameters == null)
                    {
                        NotFound(e);
                        return;
                    }
                }
                else
                {
                    Dictionary <string, ControlParameter> Parameters1;
                    Dictionary <string, ControlParameter> Parameters2;
                    LinkedList <string> ToRemove = null;

                    Parameters  = null;
                    Parameters1 = null;

                    foreach (ThingReference Node in Nodes)
                    {
                        if (Parameters1 == null)
                        {
                            Parameters = await this.GetControlParameters(Node);

                            if (Parameters == null)
                            {
                                NotFound(e);
                                return;
                            }

                            Parameters1 = new Dictionary <string, ControlParameter>();

                            foreach (ControlParameter P in Parameters)
                            {
                                Parameters1[P.Name] = P;
                            }
                        }
                        else
                        {
                            Parameters2 = await this.GetControlParametersByName(Node);

                            if (Parameters2 == null)
                            {
                                NotFound(e);
                                return;
                            }

                            foreach (KeyValuePair <string, ControlParameter> P in Parameters1)
                            {
                                if (!Parameters2.TryGetValue(P.Key, out ControlParameter P2) || !P.Value.Equals(P2))
                                {
                                    if (ToRemove == null)
                                    {
                                        ToRemove = new LinkedList <string>();
                                    }

                                    ToRemove.AddLast(P.Key);
                                }
                            }

                            if (ToRemove != null)
                            {
                                foreach (string Key in ToRemove)
                                {
                                    Parameters1.Remove(Key);
                                }

                                ToRemove = null;
                            }
                        }
                    }

                    List <ControlParameter> Left = new List <ControlParameter>();

                    foreach (ControlParameter P in Parameters)
                    {
                        if (Parameters1.ContainsKey(P.Name))
                        {
                            Left.Add(P);
                        }
                    }

                    Parameters = Left.ToArray();
                }

                StringBuilder  Xml    = new StringBuilder();
                XmlWriter      Output = XmlWriter.Create(Xml, XML.WriterSettings(false, true));
                ThingReference FirstNode;

                Output.WriteStartElement("x", XmppClient.NamespaceData);
                Output.WriteAttributeString("xmlns", "xdv", null, XmppClient.NamespaceDataValidate);
                Output.WriteAttributeString("xmlns", "xdl", null, XmppClient.NamespaceDataLayout);
                Output.WriteAttributeString("xmlns", "xdd", null, XmppClient.NamespaceDynamicForms);

                if (Nodes == null)
                {
                    FirstNode = null;
                    Output.WriteElementString("title", this.client.BareJID);
                }
                else
                {
                    FirstNode = Nodes.First.Value;

                    if (Nodes.First.Next == null)
                    {
                        Output.WriteElementString("title", Nodes.First.Value.NodeId);
                    }
                    else
                    {
                        Output.WriteElementString("title", Nodes.Count.ToString() + " nodes");
                    }
                }

                LinkedList <string> PagesInOrder = new LinkedList <string>();
                Dictionary <string, LinkedList <ControlParameter> > ParametersPerPage = new Dictionary <string, LinkedList <ControlParameter> >();

                foreach (ControlParameter P in Parameters)
                {
                    if (!ParametersPerPage.TryGetValue(P.Page, out LinkedList <ControlParameter> List))
                    {
                        PagesInOrder.AddLast(P.Page);
                        List = new LinkedList <ControlParameter>();
                        ParametersPerPage[P.Page] = List;
                    }

                    List.AddLast(P);
                }

                foreach (string Page in PagesInOrder)
                {
                    Output.WriteStartElement("xdl", "page", null);
                    Output.WriteAttributeString("label", Page);

                    foreach (ControlParameter P in ParametersPerPage[Page])
                    {
                        Output.WriteStartElement("xdl", "fieldref", null);
                        Output.WriteAttributeString("var", P.Name);
                        Output.WriteEndElement();
                    }

                    Output.WriteEndElement();
                }

                foreach (ControlParameter P in Parameters)
                {
                    P.ExportToForm(Output, FirstNode);
                }

                Output.WriteEndElement();
                Output.Flush();

                e.IqResult(Xml.ToString());
            }
            catch (Exception ex)
            {
                e.IqError(ex);
            }
        }
Exemple #10
0
        private void SubscribeHandler(object Sender, IqEventArgs e)
        {
            List <ThingReference> Nodes = null;
            Dictionary <string, FieldSubscriptionRule> Fields = null;
            XmlElement E            = e.Query;
            FieldType  FieldTypes   = (FieldType)0;
            Duration   MaxAge       = null;
            Duration   MinInterval  = null;
            Duration   MaxInterval  = null;
            string     ServiceToken = string.Empty;
            string     DeviceToken  = string.Empty;
            string     UserToken    = string.Empty;
            string     NodeId;
            string     SourceId;
            string     Partition;
            string     Id  = string.Empty;
            bool       Req = false;
            bool       b;

            foreach (XmlAttribute Attr in E.Attributes)
            {
                switch (Attr.Name)
                {
                case "id":
                    Id = Attr.Value;
                    break;

                case "maxAge":
                    if (!Duration.TryParse(Attr.Value, out MaxAge))
                    {
                        MaxAge = null;
                    }
                    break;

                case "minInt":
                    if (!Duration.TryParse(Attr.Value, out MinInterval))
                    {
                        MinInterval = null;
                    }
                    break;

                case "maxInt":
                    if (!Duration.TryParse(Attr.Value, out MaxInterval))
                    {
                        MaxInterval = null;
                    }
                    break;

                case "st":
                    ServiceToken = Attr.Value;
                    break;

                case "dt":
                    DeviceToken = Attr.Value;
                    break;

                case "ut":
                    UserToken = Attr.Value;
                    break;

                case "all":
                    if (CommonTypes.TryParse(Attr.Value, out b) && b)
                    {
                        FieldTypes |= FieldType.All;
                    }
                    break;

                case "h":
                    if (CommonTypes.TryParse(Attr.Value, out b) && b)
                    {
                        FieldTypes |= FieldType.Historical;
                    }
                    break;

                case "m":
                    if (CommonTypes.TryParse(Attr.Value, out b) && b)
                    {
                        FieldTypes |= FieldType.Momentary;
                    }
                    break;

                case "p":
                    if (CommonTypes.TryParse(Attr.Value, out b) && b)
                    {
                        FieldTypes |= FieldType.Peak;
                    }
                    break;

                case "s":
                    if (CommonTypes.TryParse(Attr.Value, out b) && b)
                    {
                        FieldTypes |= FieldType.Status;
                    }
                    break;

                case "c":
                    if (CommonTypes.TryParse(Attr.Value, out b) && b)
                    {
                        FieldTypes |= FieldType.Computed;
                    }
                    break;

                case "i":
                    if (CommonTypes.TryParse(Attr.Value, out b) && b)
                    {
                        FieldTypes |= FieldType.Identity;
                    }
                    break;

                case "req":
                    if (!CommonTypes.TryParse(Attr.Value, out Req))
                    {
                        Req = false;
                    }
                    break;
                }
            }

            foreach (XmlNode N in E.ChildNodes)
            {
                switch (N.LocalName)
                {
                case "nd":
                    if (Nodes == null)
                    {
                        Nodes = new List <ThingReference>();
                    }

                    E         = (XmlElement)N;
                    NodeId    = XML.Attribute(E, "id");
                    SourceId  = XML.Attribute(E, "src");
                    Partition = XML.Attribute(E, "pt");

                    ThingReference Ref = new ThingReference(NodeId, SourceId, Partition);
                    Nodes.Add(Ref);
                    break;

                case "f":
                    if (Fields == null)
                    {
                        Fields = new Dictionary <string, FieldSubscriptionRule>();
                    }

                    string FieldName    = null;
                    double?CurrentValue = null;
                    double?ChangedBy    = null;
                    double?ChangedUp    = null;
                    double?ChangedDown  = null;
                    double d;

                    foreach (XmlAttribute Attr in N.Attributes)
                    {
                        switch (Attr.Name)
                        {
                        case "n":
                            FieldName = Attr.Value;
                            break;

                        case "v":
                            if (CommonTypes.TryParse(Attr.Value, out d))
                            {
                                CurrentValue = d;
                            }
                            break;

                        case "by":
                            if (CommonTypes.TryParse(Attr.Value, out d))
                            {
                                ChangedBy = d;
                            }
                            break;

                        case "up":
                            if (CommonTypes.TryParse(Attr.Value, out d))
                            {
                                ChangedUp = d;
                            }
                            break;

                        case "dn":
                            if (CommonTypes.TryParse(Attr.Value, out d))
                            {
                                ChangedDown = d;
                            }
                            break;
                        }
                    }

                    if (!string.IsNullOrEmpty(FieldName))
                    {
                        Fields[FieldName] = new FieldSubscriptionRule(FieldName, CurrentValue, ChangedBy, ChangedUp, ChangedDown);
                    }

                    break;
                }
            }

            if (this.provisioningClient != null)
            {
                this.provisioningClient.CanRead(e.FromBareJid, FieldTypes, Nodes, Fields.Keys,
                                                ServiceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                DeviceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                UserToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                (sender2, e2) =>
                {
                    if (e2.Ok && e2.CanRead)
                    {
                        if (e2.FieldsNames != null)
                        {
                            Dictionary <string, bool> FieldNames = new Dictionary <string, bool>();

                            foreach (string FieldName in FieldNames.Keys)
                            {
                                FieldNames[FieldName] = true;
                            }

                            LinkedList <string> ToRemove = null;

                            foreach (string FieldName in Fields.Keys)
                            {
                                if (!FieldNames.ContainsKey(FieldName))
                                {
                                    if (ToRemove == null)
                                    {
                                        ToRemove = new LinkedList <string>();
                                    }

                                    ToRemove.AddLast(FieldName);
                                }
                            }

                            if (ToRemove != null)
                            {
                                foreach (string FieldName in ToRemove)
                                {
                                    Fields.Remove(FieldName);
                                }
                            }
                        }

                        this.PerformSubscription(Req, e, Id, Fields, e2.Nodes, e2.FieldTypes,
                                                 ServiceToken, DeviceToken, UserToken, MaxAge, MinInterval, MaxInterval);
                    }
                    else
                    {
                        e.IqError("<error type='cancel'><forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" +
                                  "<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>Access denied.</text></error>");
                    }
                }, null);
            }
            else
            {
                this.PerformSubscription(Req, e, Id, Fields, Nodes?.ToArray(), FieldTypes,
                                         ServiceToken, DeviceToken, UserToken, MaxAge, MinInterval, MaxInterval);
            }
        }
        /// <summary>
        /// Checks if the request is authorized.
        /// </summary>
        /// <param name="Request">Request object.</param>
        /// <returns>User object, if authenticated, or null otherwise.</returns>
        public override async Task <IUser> IsAuthenticated(HttpRequest Request)
        {
            HttpFieldAuthorization Authorization = Request.Header.Authorization;

            if (Authorization != null && Authorization.Value.StartsWith("Digest ", StringComparison.CurrentCultureIgnoreCase))
            {
                string   UserName = null;
                string   Opaque   = null;
                string   Realm    = null;
                string   Nonce    = null;
                string   Cnonce   = null;
                string   Nc       = null;
                string   Uri      = null;
                string   Qop      = null;
                string[] QopItems;
                string   Response = null;
                bool     Auth     = false;
                bool     AuthInt  = false;

                foreach (KeyValuePair <string, string> P in CommonTypes.ParseFieldValues(Authorization.Value.Substring(7)))
                {
                    switch (P.Key.ToLower())
                    {
                    case "username":
                        UserName = P.Value;
                        break;

                    case "opaque":
                        Opaque = P.Value;
                        break;

                    case "realm":
                        Realm = P.Value;
                        break;

                    case "nonce":
                        Nonce = P.Value;
                        break;

                    case "cnonce":
                        Cnonce = P.Value;
                        break;

                    case "nc":
                        Nc = P.Value;
                        break;

                    case "uri":
                        Uri = P.Value;
                        break;

                    case "qop":
                        Qop      = P.Value;
                        QopItems = Qop.Split(',');

                        Auth    = (Array.IndexOf(QopItems, "auth") >= 0);
                        AuthInt = (Array.IndexOf(QopItems, "auth-int") >= 0);
                        break;

                    case "response":
                        Response = P.Value;
                        break;
                    }
                }

                if (this.realm != Realm || Qop is null || Nonce is null || Cnonce is null || Nc is null ||
                    Uri is null || Response is null || UserName is null || (!Auth && !AuthInt))
                {
                    return(null);
                }

                if (this.opaque != Opaque)
                {
                    // We need to ignore the opaque value if it's a POST from a web form, since it can be used from the original GET
                    // (which might have ocurred when another instance of the application ran).

                    if (Request.Header.Method != "POST" || Request.Header.ContentType.Value != "application/x-www-form-urlencoded")
                    {
                        return(null);
                    }
                }

                DateTime TP = DateTime.Now;

                lock (this)
                {
                    LinkedList <DateTime> ToRemove = null;

                    foreach (KeyValuePair <DateTime, string> Pair in this.nonceByExpiration)
                    {
                        if (Pair.Key <= TP)
                        {
                            if (ToRemove is null)
                            {
                                ToRemove = new LinkedList <DateTime>();
                            }

                            ToRemove.AddLast(Pair.Key);
                            this.expirationByNonce.Remove(Pair.Value);
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (ToRemove != null)
                    {
                        foreach (DateTime ExpiryDate in ToRemove)
                        {
                            this.nonceByExpiration.Remove(ExpiryDate);
                        }
                    }

                    if (!this.expirationByNonce.TryGetValue(Nonce, out TP))
                    {
                        // We need to ignore the nonce value if it's a POST from a web form, since it can be used from the original GET
                        // (which might have ocurred when another instance of the application ran).

                        if (Request.Header.Method != "POST" || Request.Header.ContentType.Value != "application/x-www-form-urlencoded")
                        {
                            return(null);
                        }
                    }

                    if (Request.Header.Method != "HEAD")
                    {
                        this.expirationByNonce.Remove(Nonce);
                        this.nonceByExpiration.Remove(TP);
                    }
                }

                string HA1;
                string HA2;
                string Digest;

                IUser User = await this.users.TryGetUser(UserName);

                if (User is null)
                {
                    return(null);
                }

                switch (User.PasswordHashType)
                {
                case "":
                    HA1 = ToHex(H(UserName + ":" + this.realm + ":" + User.PasswordHash));
                    break;

                case "DIGEST-MD5":
                    HA1 = User.PasswordHash;
                    break;

                default:
                    return(null);
                }

                if (AuthInt)
                {
                    HA2 = ToHex(H(Request.Header.Method + ":" + Uri + ":" + ToHex(H(string.Empty))));
                }
                else
                {
                    HA2 = ToHex(H(Request.Header.Method + ":" + Uri));
                }

                Digest = HA1 + ":" + Nonce + ":" + Nc + ":" + Cnonce + ":" + Qop + ":" + HA2;
                Digest = ToHex(H(Digest));

                if (Digest == Response)
                {
                    LoginAuditor.Success("Login successful.", UserName, Request.RemoteEndPoint, "HTTP");
                    return(User);
                }
                else
                {
                    LoginAuditor.Fail("Login attempt failed.", UserName, Request.RemoteEndPoint, "HTTP");
                    return(null);
                }
            }

            return(null);
        }