Example #1
0
        /// <summary>
        /// Encode SNMP packet for sending.
        /// </summary>
        /// <returns>BER encoded SNMP packet.</returns>
        /// <exception cref="SnmpInvalidPduTypeException">Thrown when PDU being encoded is not a valid SNMP version 1 PDU. Acceptable
        /// protocol version 1 operations are GET, GET-NEXT, SET and RESPONSE.</exception>
        public override byte[] encode()
        {
            if (this.Pdu.Type != PduType.Get && this.Pdu.Type != PduType.GetNext &&
                this.Pdu.Type != PduType.Set && this.Pdu.Type != PduType.Response)
            {
                throw new SnmpInvalidVersionException("Invalid SNMP PDU type while attempting to encode PDU: " + string.Format("0x{0:x2}", this.Pdu.Type));
            }
            if (this.Pdu.RequestId == 0)
            {
                System.Random rand = new System.Random((System.Int32)DateTime.Now.Ticks);
                this.Pdu.RequestId = rand.Next();
            }
            MutableByte tmpBuffer = new MutableByte();

            // snmp version
            _protocolVersion.encode(tmpBuffer);

            // community string
            _snmpCommunity.encode(tmpBuffer);

            // pdu
            this.Pdu.encode(tmpBuffer);

            MutableByte buf = new MutableByte();

            // wrap the packet into a sequence
            AsnType.BuildHeader(buf, SnmpConstants.SMI_SEQUENCE, tmpBuffer.Length);

            buf.Append(tmpBuffer);
            return(buf);
        }
Example #2
0
        /// <summary>
        /// Encode SNMP packet for sending.
        /// </summary>
        /// <returns>BER encoded SNMP packet.</returns>
        public override byte[] encode()
        {
            MutableByte buf = new MutableByte();

            if (this.Pdu.Type != PduType.Get && this.Pdu.Type != PduType.GetNext &&
                this.Pdu.Type != PduType.Set && this.Pdu.Type != PduType.V2Trap &&
                this.Pdu.Type != PduType.Response && this.Pdu.Type != PduType.GetBulk &&
                this.Pdu.Type != PduType.Inform)
            {
                throw new SnmpInvalidPduTypeException("Invalid SNMP PDU type while attempting to encode PDU: " + string.Format("0x{0:x2}", this.Pdu.Type));
            }

            // snmp version
            _protocolVersion.encode(buf);

            // community string
            _snmpCommunity.encode(buf);

            // pdu
            _pdu.encode(buf);

            // wrap the packet into a sequence
            MutableByte tmpBuf = new MutableByte();

            AsnType.BuildHeader(tmpBuf, SnmpConstants.SMI_SEQUENCE, buf.Length);

            buf.Prepend(tmpBuf);
            return(buf);
        }
        /// <summary>BER encode security model field.</summary>
        /// <remarks>
        /// USM security model is a SEQUENCE encoded inside a OCTETSTRING. To encode it, first encode the sequence
        /// of class values then "wrap" it inside a OCTETSTRING field
        /// </remarks>
        /// <param name="buffer">Buffer to store encoded USM security model header</param>
        public override void encode(MutableByte buffer)
        {
            MutableByte tmp = new MutableByte();

            // First encode all the values that will form the sequence
            _engineId.encode(tmp);
            // Encode engine boots
            _engineBoots.encode(tmp);
            // encode engine time
            _engineTime.encode(tmp);
            _securityName.encode(tmp);
            if (_authentication != AuthenticationDigests.None)
            {
                if (_authenticationParameters.Length <= 0)
                {
                    // If authentication is used, set authentication parameters field to 12 bytes set to 0x00
                    _authenticationParameters.Set(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
                }
            }
            else
            {
                _authenticationParameters.Reset();
            }
            _authenticationParameters.encode(tmp);
            if (_privacy != PrivacyProtocols.None)
            {
                if (_privacyParameters.Length <= 0)
                {
                    IPrivacyProtocol privProto = PrivacyProtocol.GetInstance(_privacy);
                    if (privProto != null)
                    {
                        byte[] parameter = new byte[privProto.PrivacyParametersLength];
                        for (int i = 0; i < privProto.PrivacyParametersLength; i++)
                        {
                            parameter[i] = 0x00; // This is not necessary since all array members are, by default, initialized to 0
                        }
                        _privacyParameters.Set(parameter);
                    }
                    else
                    {
                        throw new SnmpException(SnmpException.UnsupportedPrivacyProtocol, "Unrecognized privacy protocol specified.");
                    }
                }
            }
            else
            {
                _privacyParameters.Reset();
            }
            _privacyParameters.encode(tmp);
            MutableByte tmp1 = new MutableByte();

            BuildHeader(tmp1, SnmpConstants.SMI_SEQUENCE, tmp.Length);
            tmp1.Append(tmp);

            BuildHeader(buffer, OCTETSTRING, tmp1.Length);

            buffer.Append(tmp1);
        }
Example #4
0
 /// <summary>
 ///     Convert <see cref="ScopedPdu" /> into a BER encoded byte array. Resulting byte array is appended
 ///     to the argument specified <see cref="MutableByte" /> class.
 ///     Privacy operations are not performed by this method. Value encoded and returned by this method is
 ///     suitable for sending in NoAuthNoPriv or AuthNoPriv security configurations. If privacy is required,
 ///     caller will have to perform encryption and decryption operations after BER encoding is performed.
 ///     In privacy protected SNMP version 3 packets, ScopedPdu is 1) encrypted using configured encryption
 ///     method, 2) added to a <see cref="OctetString" /> field, and 3) appended to the data buffer.
 ///     Because privacy operation is intrusive, it is recommended that BER encoding of the ScopedPdu packet
 ///     is stored in a temporary <see cref="MutableByte" /> class, where it can be privacy protected and
 ///     added to the <see cref="OctetString" /> class for final encoding into the target SNMP v3 packet.
 /// </summary>
 /// <param name="buffer">
 ///     <see cref="MutableByte" /> class passed by reference that encoded ScopedPdu
 ///     value is appended to.
 /// </param>
 public override void encode(MutableByte buffer)
 {
     var tmp = new MutableByte();
     _contextEngineId.encode(tmp);
     _contextName.encode(tmp);
     // Encode base
     base.encode(tmp);
     BuildHeader(buffer, SnmpConstants.SMI_SEQUENCE, tmp.Length);
     buffer.Append(tmp);
 }
        /// <summary>
        /// Encode SNMP packet for sending.
        /// </summary>
        /// <returns>BER encoded SNMP packet.</returns>
        public override byte[] encode()
        {
            MutableByte tmpBuffer = new MutableByte();

            //
            // encode the community strings
            _snmpCommunity.encode(tmpBuffer);
            this.Pdu.encode(tmpBuffer);

            base.encode(tmpBuffer);

            return((byte[])tmpBuffer);
        }
Example #6
0
        /// <summary>
        /// Encode SNMP v3 message flag field
        /// </summary>
        /// <param name="buffer">Buffer to append encoded value to</param>
        public override void encode(MutableByte buffer)
        {
            byte flag = 0x00;

            if (_authenticationFlag)
            {
                flag |= FLAG_AUTH;
            }
            if (_privacyFlag)
            {
                flag |= FLAG_PRIV;
            }
            if (_reportableFlag)
            {
                flag |= FLAG_REPORTABLE;
            }
            OctetString flagObject = new OctetString(flag);

            flagObject.encode(buffer);
        }
Example #7
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, 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[] encryptedBuffer = privacyProtocol.Encrypt(unencryptedPdu, 0, unencryptedPdu.Length, privKey, _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);
            }

            base.encode(buffer);

            if (_msgFlags.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);
                base.encode(packetHeader);
                buffer = packetHeader;
            }
            return(buffer);
        }