296 lines · 10.8 KB · C#
RawDownload
// Secure SNMP context class.// Copyright (C) 2009-2010 Lex Li// // Permission is hereby granted, free of charge, to any person obtaining a copy of this// software and associated documentation files (the "Software"), to deal in the Software// without restriction, including without limitation the rights to use, copy, modify, merge,// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons// to whom the Software is furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in all copies or// substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER// DEALINGS IN THE SOFTWARE. using System;using System.Collections.Generic;#if NET471using System.Configuration;#endifusing System.Diagnostics.CodeAnalysis;using System.Globalization;using System.Net;using GSF.Net.Snmp.Messaging;using GSF.Net.Snmp.Security; namespace GSF.Net.Snmp.Pipeline{    /// <summary>    /// Secure SNMP context. It is specific to v3.    /// </summary>    internal sealed class SecureSnmpContext : SnmpContextBase    {           /// <summary>        /// Initializes a new instance of the <see cref="SecureSnmpContext"/> class.        /// </summary>        /// <param name="request">The request.</param>        /// <param name="sender">The sender.</param>        /// <param name="users">The users.</param>        /// <param name="group">The engine core group.</param>        /// <param name="binding">The binding.</param>        public SecureSnmpContext(ISnmpMessage request, IPEndPoint sender, UserRegistry users, EngineGroup group, IListenerBinding binding)            : base(request, sender, users, group, binding)        {        }         private void HandleFailure(Variable failure)        {            IPrivacyProvider defaultPair = DefaultPrivacyProvider.DefaultPair;            int[] time = Group.EngineTimeData;            Response = new ReportMessage(                Request.Version,                new Header(                    new Integer32(Request.MessageId()),                    new Integer32(Messenger.MaxMessageSize),                    0), // no need to encrypt.                new SecurityParameters(                    Group.EngineId,                    new Integer32(time[0]),                    new Integer32(time[1]),                    Request.Parameters.UserName,                    defaultPair.AuthenticationProvider.CleanDigest,                    defaultPair.Salt),                new Scope(                    Group.EngineId,                    OctetString.Empty,                    new ReportPdu(                        Request.RequestId(),                        ErrorCode.NoError,                        0,                        new List<Variable>(1) { failure })),                defaultPair,                null);            if (TooBig)            {                GenerateTooBig();            }        }         public override void CopyRequest(ErrorCode status, int index)        {            OctetString userName = Request.Parameters.UserName;            IPrivacyProvider privacy = Users.Find(userName);            int[] time = Group.EngineTimeData;            Response = new ResponseMessage(                    Request.Version,                    new Header(                        new Integer32(Request.MessageId()),                        new Integer32(Messenger.MaxMessageSize),                        privacy.ToSecurityLevel()),                    new SecurityParameters(                        Group.EngineId,                        new Integer32(time[0]),                        new Integer32(time[1]),                        userName,                        privacy.AuthenticationProvider.CleanDigest,                        privacy.Salt),                    new Scope(                        Group.EngineId,                        OctetString.Empty,                        new ResponsePdu(                            Request.RequestId(),                            status,                            index,                            Request.Pdu().Variables)),                    privacy,                    true,                    null);            if (TooBig)            {                GenerateTooBig();            }        }         /// <summary>        /// Generates too big message.        /// </summary>        public override void GenerateTooBig()        {            OctetString userName = Request.Parameters.UserName;            IPrivacyProvider privacy = Users.Find(userName);            int[] time = Group.EngineTimeData;            Response = new ResponseMessage(                Request.Version,                new Header(                    new Integer32(Request.MessageId()),                    new Integer32(Messenger.MaxMessageSize),                    privacy.ToSecurityLevel()),                new SecurityParameters(                    Group.EngineId,                    new Integer32(time[0]),                    new Integer32(time[1]),                    userName,                    privacy.AuthenticationProvider.CleanDigest,                    privacy.Salt),                new Scope(                    Group.EngineId,                    OctetString.Empty,                    new ResponsePdu(                        Request.RequestId(),                        ErrorCode.TooBig,                        0,                        Request.Pdu().Variables)),                privacy,                true,                null);            if (TooBig)            {                Response = null;                                // TODO: snmpSilentDrops++;            }        }         /// <summary>        /// Handles the membership.        /// </summary>        /// <returns></returns>        [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Reviewed. Suppression is OK here.")]        public override bool HandleMembership()        {            ISnmpMessage request = Request;            SecurityParameters parameters = request.Parameters;            SnmpType typeCode = Request.TypeCode();             if (typeCode == SnmpType.Unknown)            {                HandleFailure(Group.DecryptionError);                return false;            }             if (typeCode != SnmpType.TrapV2Pdu && parameters.EngineId != Group.EngineId)            {                HandleDiscovery();                return true;            }             IPrivacyProvider user = Users.Find(parameters.UserName);            if (user == null)             {                HandleFailure(Group.UnknownSecurityName);                return false;            }             if (typeCode == SnmpType.TrapV2Pdu && (user.EngineIds == null || !user.EngineIds.Contains(parameters.EngineId)))            {                HandleFailure(Group.UnknownEngineId);                return false;            }             if (parameters.IsInvalid)            {                HandleFailure(Group.AuthenticationFailure);                return false;            }             if (typeCode == SnmpType.TrapV2Pdu)            {                return true;            }             if ((user.ToSecurityLevel() | Levels.Reportable) != request.Header.SecurityLevel)            {                HandleFailure(Group.UnsupportedSecurityLevel);                return false;            }             bool inTime = EngineGroup.IsInTime(Group.EngineTimeData, parameters.EngineBoots.ToInt32(), parameters.EngineTime.ToInt32());            if (!inTime)            {                HandleFailure(Group.NotInTimeWindow);                return false;            }             return true;        }         private static bool TimeIncluded => true;         private void HandleDiscovery()        {                     // discovery message received.            int[] time = Group.EngineTimeData;            Response = new ReportMessage(                VersionCode.V3,                new Header(                    new Integer32(Request.MessageId()),                    new Integer32(Messenger.MaxMessageSize),                    0), // no need to encrypt for discovery.                new SecurityParameters(                    Group.EngineId,                    TimeIncluded ? new Integer32(time[0]) : Integer32.Zero,                    TimeIncluded ? new Integer32(time[1]) : Integer32.Zero,                    OctetString.Empty,                    OctetString.Empty,                    OctetString.Empty),                new Scope(                    Group.EngineId,                    OctetString.Empty,                    new ReportPdu(                        Request.RequestId(),                        ErrorCode.NoError,                        0,                        new List<Variable>(1) { Group.UnknownEngineId })),                DefaultPrivacyProvider.DefaultPair,                null);            if (TooBig)            {                GenerateTooBig();            }        }         /// <summary>        /// Generates the response.        /// </summary>        /// <param name="variables">The variables.</param>        public override void GenerateResponse(IList<Variable> variables)        {            OctetString userName = Request.Parameters.UserName;            IPrivacyProvider privacy = Users.Find(userName);            int[] time = Group.EngineTimeData;            Response = new ResponseMessage(                Request.Version,                new Header(                    new Integer32(Request.MessageId()),                    new Integer32(Messenger.MaxMessageSize),                    privacy.ToSecurityLevel()),                new SecurityParameters(                    Group.EngineId,                    new Integer32(time[0]),                    new Integer32(time[1]),                    userName,                    privacy.AuthenticationProvider.CleanDigest,                    privacy.Salt),                new Scope(                    Group.EngineId,                    OctetString.Empty,                    new ResponsePdu(                        Request.RequestId(),                        ErrorCode.NoError,                        0,                        variables)),                privacy,                true,                null);            if (TooBig)            {                GenerateTooBig();            }        }    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t