Beispiel #1
0
        /// <summary>Copy constructor. Initialize the class with the values of the parameter class values.</summary>
        /// <param name="second">Parameter class.</param>
        public SecureAgentParameters(SecureAgentParameters second)
            : this()
        {
            contextEngineId.Set(second.ContextEngineId);
            contextName.Set(second.ContextName);
            engineBoots.Value = second.EngineBoots.Value;
            engineId.Set(second.EngineId);
            engineTime.Value     = second.EngineTime.Value;
            engineTimeStamp      = second.EngineTimeStamp();
            maxMessageSize.Value = second.MaxMessageSize.Value;
            privacyProtocol      = second.Privacy;
            privacySecret.Set(second.PrivacySecret);
            authenticationProtocol = second.Authentication;
            authenticationSecret.Set(second.AuthenticationSecret);
            reportable = second.Reportable;
            securityName.Set(second.SecurityName);

            if (second.AuthenticationKey != null)
            {
                authenticationKey = (byte[])second.AuthenticationKey.Clone();
            }

            if (second.PrivacyKey != null)
            {
                privacyKey = (byte[])second.PrivacyKey.Clone();
            }
        }
 /// <summary>
 /// Prepare class for authPriv operations.
 /// </summary>
 /// <param name="securityName">User security name</param>
 /// <param name="authDigest">Authentication protocol</param>
 /// <param name="authSecret">Authentication secret (password)</param>
 /// <param name="privProtocol">Privacy protocol</param>
 /// <param name="privSecret">Privacy secret (encryption password)</param>
 public void authPriv(string securityName, AuthenticationDigests authDigest, string authSecret, PrivacyProtocols privProtocol, string privSecret)
 {
     _securityName.Set(securityName);
     _authenticationProtocol = authDigest;
     _authenticationSecret.Set(authSecret);
     _privacyProtocol = privProtocol;
     _privacySecret.Set(privSecret);
 }
 /// <summary>
 /// Prepare class for authNoPriv operations. Set privacy protocol to none
 /// </summary>
 /// <param name="securityName">User security name</param>
 /// <param name="authDigest">Authentication protocol</param>
 /// <param name="authSecret">Authentication secret (password)</param>
 public void authNoPriv(string securityName, AuthenticationDigests authDigest, string authSecret)
 {
     _securityName.Set(securityName);
     _authenticationProtocol = authDigest;
     _authenticationSecret.Set(authSecret);
     _privacyProtocol = PrivacyProtocols.None;
     _privacySecret.Clear();
 }
Beispiel #4
0
 /// <summary>
 /// Copy all relevant values from the SnmpV3Packet class. Do not use this class for
 /// updating the SNMP version 3 discovery process results because secret name, authentication
 /// and privacy values are updated as well which discovery process doesn't use.
 /// </summary>
 /// <param name="packet"><see cref="SnmpV3Packet"/> cast as <see cref="SnmpPacket"/></param>
 /// <exception cref="SnmpInvalidVersionException">Thrown when SNMP packet class other then version 3
 /// is passed as parameter</exception>
 public void UpdateValues(SnmpPacket packet)
 {
     if (packet is SnmpV3Packet)
     {
         SnmpV3Packet pkt = (SnmpV3Packet)packet;
         _authenticationProtocol = pkt.USM.Authentication;
         _privacyProtocol        = pkt.USM.Privacy;
         _authenticationSecret.Set(pkt.USM.AuthenticationSecret);
         _privacySecret.Set(pkt.USM.PrivacySecret);
         _securityName.Set(pkt.USM.SecurityName);
         if (pkt.MaxMessageSize < _maxMessageSize.Value)
         {
             _maxMessageSize.Value = pkt.MaxMessageSize;
         }
         UpdateDiscoveryValues(pkt);
     }
     else
     {
         throw new SnmpInvalidVersionException("Invalid SNMP version.");
     }
 }
Beispiel #5
0
        /// <summary>
        ///     Encode single OID instance value
        /// </summary>
        /// <param name="number">Instance value</param>
        /// <returns>Encoded instance value</returns>
        protected byte[] encodeInstance(uint number)
        {
            var result = new MutableByte();

            if (number <= 127)
            {
                result.Set((byte)number);
            }
            else
            {
                var val = number;
                var tmp = new MutableByte();
                while (val != 0)
                {
                    var b    = BitConverter.GetBytes(val);
                    var bval = b[0];
                    if ((bval & 0x80) != 0)
                    {
                        bval = (byte)(bval & ~HIGH_BIT); // clear high bit
                    }
                    val >>= 7;                           // shift original value by 7 bits
                    tmp.Append(bval);
                }
                // now we need to reverse the bytes for the final encoding
                for (var i = tmp.Length - 1; i >= 0; i--)
                {
                    if (i > 0)
                    {
                        result.Append((byte)(tmp[i] | HIGH_BIT));
                    }
                    else
                    {
                        result.Append(tmp[i]);
                    }
                }
            }
            return(result);
        }
Beispiel #6
0
        /// <summary>Encode SNMP version 3 packet</summary>
        /// <param name="authKey">Authentication key (not password)</param>
        /// <param name="privKey">Privacy key (not password)</param>
        /// <remarks>
        /// Before encoding the packet into a byte array you need to ensure all required information is
        /// set. Examples of required information is request type, Vbs (Oid + values pairs), USM settings including
        /// SecretName, authentication method and secret (if needed), privacy method and secret (if needed), etc.
        /// </remarks>
        /// <returns>Byte array BER encoded SNMP packet.</returns>
        public byte[] Encode(byte[] authKey, byte[] privKey)
        {
            MutableByte buffer = new MutableByte();

            // encode the global message data sequence header information
            MutableByte globalMessageData = new MutableByte();

            // if message id is 0 then generate a new, random message id
            if (messageId.Value == 0)
            {
                Random rand = new Random();
                messageId.Value = rand.Next(1, int.MaxValue);
            }

            // encode message id
            messageId.Encode(globalMessageData);

            // encode max message size
            maxMessageSize.Encode(globalMessageData);

            // message flags
            messageFlags.Encode(globalMessageData);

            // security model code
            securityModel.Value = userSecurityModel.Type;
            securityModel.Encode(globalMessageData);

            // add global message data to the main buffer
            // encode sequence header and add data
            AsnType.BuildHeader(buffer, SnmpConstants.SmiSequence, globalMessageData.Length);
            buffer.Append(globalMessageData);

            MutableByte packetHeader = new MutableByte(buffer);

            // before going down this road, check if this is a discovery packet
            OctetString savedUserName  = new OctetString();
            bool        privacy        = messageFlags.Privacy;
            bool        authentication = messageFlags.Authentication;
            bool        reportable     = messageFlags.Reportable;

            if (userSecurityModel.EngineId.Length <= 0)
            {
                // save USM settings prior to encoding a Discovery packet
                savedUserName.Set(userSecurityModel.SecurityName);
                userSecurityModel.SecurityName.Reset(); // delete security name for discovery packets
                messageFlags.Authentication = false;
                messageFlags.Privacy        = false;
                messageFlags.Reportable     = true;
            }

            userSecurityModel.Encode(buffer);

            if (userSecurityModel.EngineId.Length <= 0)
            {
                // restore saved USM values
                userSecurityModel.SecurityName.Set(savedUserName);
                messageFlags.Authentication = authentication;
                messageFlags.Privacy        = privacy;
                messageFlags.Reportable     = reportable;
            }

            // Check if privacy encryption is required
            MutableByte encodedPdu = new MutableByte();

            if (messageFlags.Privacy && userSecurityModel.EngineId.Length > 0)
            {
                IPrivacyProtocol privacyProtocol = PrivacyProtocol.GetInstance(userSecurityModel.Privacy);
                if (privacyProtocol == null)
                {
                    throw new SnmpException(SnmpException.EErrorCode.UnsupportedPrivacyProtocol, "Specified privacy protocol is not supported.");
                }

                // Get BER encoded ScopedPdu
                MutableByte unencryptedPdu = new MutableByte();
                scopedPdu.Encode(unencryptedPdu);

                // we have to expand the key
                IAuthenticationDigest auth = Authentication.GetInstance(userSecurityModel.Authentication);
                if (auth == null)
                {
                    throw new SnmpException(SnmpException.EErrorCode.UnsupportedNoAuthPriv, "Invalid authentication protocol. noAuthPriv mode not supported.");
                }

                byte[] encryptedBuffer = privacyProtocol.Encrypt(unencryptedPdu, 0, unencryptedPdu.Length, privKey, userSecurityModel.EngineBoots, userSecurityModel.EngineTime, out byte[] privacyParameters, auth);

                userSecurityModel.PrivacyParameters.Set(privacyParameters);

                OctetString encryptedOctetString = new OctetString(encryptedBuffer);
                encryptedOctetString.Encode(encodedPdu);

                // now redo packet encoding
                buffer.Reset();
                buffer.Set(packetHeader);
                userSecurityModel.Encode(buffer);

                int preEncodedLength = encodedPdu.Length;
                buffer.Append(encodedPdu);

                if (maxMessageSize.Value != 0)
                {
                    // verify compliance with maximum message size
                    if ((encodedPdu.Length - preEncodedLength) > maxMessageSize)
                    {
                        throw new SnmpException(SnmpException.EErrorCode.MaximumMessageSizeExceeded, "ScopedPdu exceeds maximum message size.");
                    }
                }
            }
            else
            {
                scopedPdu.Encode(encodedPdu);
                buffer.Append(encodedPdu);
            }

            Encode(buffer);

            if (messageFlags.Authentication && userSecurityModel.EngineId.Length > 0)
            {
                userSecurityModel.Authenticate(authKey, ref buffer);

                // Now re-encode the packet with the authentication information
                userSecurityModel.Encode(packetHeader);
                packetHeader.Append(encodedPdu);

                Encode(packetHeader);
                buffer = packetHeader;
            }

            return(buffer);
        }
        /// <summary>
        /// Encode SNMP version 3 packet
        /// </summary>
        /// <remarks>
        /// Before encoding the packet into a byte array you need to ensure all required information is
        /// set. Examples of required information is request type, Vbs (Oid + values pairs), USM settings including
        /// SecretName, authentication method and secret (if needed), privacy method and secret (if needed), etc.
        /// </remarks>
        /// <returns>Byte array BER encoded SNMP packet.</returns>
        public override byte[] encode()
        {
            MutableByte buffer = new MutableByte();
            // encode the global message data sequence header information

            MutableByte globalMessageData = new MutableByte();

            // if message id is 0 then generate a new, random message id
            if (_messageId.Value == 0)
            {
                Random rand = new Random();
                _messageId.Value = rand.Next(1, Int32.MaxValue);
            }

            // encode message id
            _messageId.encode(globalMessageData);

            // encode max message size
            _maxMessageSize.encode(globalMessageData);

            // message flags
            _msgFlags.encode(globalMessageData);

            // security model code
            _securityModel.Value = _userSecurityModel.Type;
            _securityModel.encode(globalMessageData);

            // add global message data to the main buffer
            // encode sequence header and add data
            AsnType.BuildHeader(buffer, SnmpConstants.SMI_SEQUENCE, globalMessageData.Length);
            buffer.Append(globalMessageData);

            MutableByte packetHeader = new MutableByte(buffer);

            // before going down this road, check if this is a discovery packet
            OctetString savedUserName  = new OctetString();
            bool        privacy        = _msgFlags.Privacy;
            bool        authentication = _msgFlags.Authentication;
            bool        reportable     = _msgFlags.Reportable;

            if (_userSecurityModel.EngineId.Length <= 0)
            {
                // save USM settings prior to encoding a Discovery packet
                savedUserName.Set(_userSecurityModel.SecurityName);
                _userSecurityModel.SecurityName.Reset();                 // delete security name for discovery packets
                _msgFlags.Authentication = false;
                _msgFlags.Privacy        = false;
                _msgFlags.Reportable     = true;
            }

            _userSecurityModel.encode(buffer);

            if (_userSecurityModel.EngineId.Length <= 0)
            {
                // restore saved USM values
                _userSecurityModel.SecurityName.Set(savedUserName);
                _msgFlags.Authentication = authentication;
                _msgFlags.Privacy        = privacy;
                _msgFlags.Reportable     = reportable;
            }

            // Check if privacy encryption is required
            MutableByte encodedPdu = new MutableByte();

            if (_msgFlags.Privacy && _userSecurityModel.EngineId.Length > 0)
            {
                IPrivacyProtocol privacyProtocol = PrivacyProtocol.GetInstance(_userSecurityModel.Privacy);
                if (privacyProtocol == null)
                {
                    throw new SnmpException(SnmpException.UnsupportedPrivacyProtocol, "Specified privacy protocol is not supported.");
                }

                // Get BER encoded ScopedPdu
                MutableByte unencryptedPdu = new MutableByte();
                _scopedPdu.encode(unencryptedPdu);

                byte[] privacyParameters = null;
                // we have to expand the key
                IAuthenticationDigest auth = Authentication.GetInstance(_userSecurityModel.Authentication);
                if (auth == null)
                {
                    throw new SnmpException(SnmpException.UnsupportedNoAuthPriv, "Invalid authentication protocol. noAuthPriv mode not supported.");
                }

                byte[] pkey = privacyProtocol.PasswordToKey(_userSecurityModel.PrivacySecret, _userSecurityModel.EngineId, auth);

                byte[] encryptedBuffer = privacyProtocol.Encrypt(unencryptedPdu, 0, unencryptedPdu.Length, pkey, _userSecurityModel.EngineBoots, _userSecurityModel.EngineTime, out privacyParameters, auth);

                _userSecurityModel.PrivacyParameters.Set(privacyParameters);
                OctetString encryptedOctetString = new OctetString(encryptedBuffer);
                encryptedOctetString.encode(encodedPdu);
                // now redo packet encoding
                buffer.Reset();
                buffer.Set(packetHeader);
                _userSecurityModel.encode(buffer);
                int preEncodedLength = encodedPdu.Length;
                buffer.Append(encodedPdu);
                if (_maxMessageSize.Value != 0)
                {
                    // verify compliance with maximum message size
                    if ((encodedPdu.Length - preEncodedLength) > _maxMessageSize)
                    {
                        throw new SnmpException(SnmpException.MaximumMessageSizeExceeded, "ScopedPdu exceeds maximum message size.");
                    }
                }
            }
            else
            {
                _scopedPdu.encode(encodedPdu);
                buffer.Append(encodedPdu);
            }

            int preVersionLength = buffer.Length;

            base.encode(buffer);

            int versionHeaderLength = buffer.Length - preVersionLength;

            if (_msgFlags.Authentication && _userSecurityModel.EngineId.Length > 0)
            {
                _userSecurityModel.Authenticate(ref buffer);
                // Now re-encode the packet with the authentication information
                _userSecurityModel.encode(packetHeader);
                packetHeader.Append(encodedPdu);
                base.encode(packetHeader);
                buffer = packetHeader;
            }
            return(buffer);
        }