/// <summary> /// Encode Pdu class to BER byte buffer /// </summary> /// <remarks> /// Encodes the protocol data unit using the passed encoder and stores /// the results in the passed buffer. An exception is thrown if an /// error occurs with the encoding of the information. /// </remarks> /// <param name="buffer">The buffer to write the encoded information.</param> public override void Encode(MutableByte buffer) { MutableByte tmpBuffer = new MutableByte(); // if request id is 0, get a random value if (_requestId.Value == 0) { _requestId.SetRandom(); } _requestId.Encode(tmpBuffer); _errorStatus.Encode(tmpBuffer); _errorIndex.Encode(tmpBuffer); // if V2TRAP PDU type, add sysUpTime and trapObjectID OIDs before encoding VarBind if (Type == PduType.V2Trap || Type == PduType.Inform) { if (_vbs.Count == 0) { // add sysUpTime and trapObjectID to the VbList _vbs.Add(SnmpConstants.SysUpTime, _trapTimeStamp); _vbs.Add(SnmpConstants.TrapObjectId, _trapObjectID); } else { // Make sure user didn't manually add sysUpTime and trapObjectID values // to the pdu // if we have more then one item in the VarBinds array check for sysUpTime if (_vbs.Count > 0) { // if the first Vb in the VarBinds array is not sysUpTime append it in the // encoded byte array if (!_vbs[0].Oid.Equals(SnmpConstants.SysUpTime)) { Vb sysUpTimeVb = new Vb(SnmpConstants.SysUpTime, _trapTimeStamp); _vbs.Insert(0, sysUpTimeVb); } } // if we have 2 or more Vbs in the VarBinds array check for trapObjectID Vb if (_vbs.Count > 1) { // if second Vb in the VarBinds array is not trapObjectId encode the value if (!_vbs[1].Oid.Equals(SnmpConstants.TrapObjectId)) { Vb trapObjectIdVb = new Vb(SnmpConstants.TrapObjectId, _trapObjectID); _vbs.Insert(1, trapObjectIdVb); } } } } // encode variable bindings _vbs.Encode(tmpBuffer); // Now encode the header for the PDU BuildHeader(buffer, (byte)Type, tmpBuffer.Length); buffer.Append(tmpBuffer); }
/// <summary> /// "Look-ahead" decode of SNMP packet header including USM information /// </summary> /// <remarks> /// Decode first component of the SNMP version 3 packet allowing the caller to retrieve USM SecureName needed to retrieve /// client security parameters that will allow authentication and privacy decryption to take place. /// /// This method is used to support Agent like behavior or to handle unsolicited packets like TRAP and INFORMs. In all of /// these cases, sender of packets will forward a packet without a request being sent by you. In turn, you will need /// to parse enough of the packet to retrieve SecureName which you can use to retrieve security parameters associated with /// that user and attempt to authorize and privacy decrypt the received packet. /// /// Only use this method when your application is acting as an Agent or if you need to process TRAP and INFORM packets. /// </remarks> /// <param name="berBuffer">Raw SNMP version 3 packet</param> /// <param name="length">SNMP version 3 packet length</param> /// <returns>UserSecurityModel class parsed from the parameter SNMP version 3 packet</returns> /// <exception cref="SnmpInvalidVersionException">Thrown when attempting to parse an SNMP packet that is not version 3</exception> /// <exception cref="OverflowException">Thrown when header specifies packet length that is longer then the amount of data received.</exception> /// <exception cref="SnmpDecodingException">Thrown when invalid sequence is enountered while decoding global message data sequence</exception> /// <exception cref="SnmpException">Thrown with SnmpException.UnsupportedNoAuthPriv when packet is using privacy without authentication (not allowed)</exception> /// <exception cref="SnmpException">Thrown with SnmpException.UnsupportedSecurityModel when packet is sent with security model other then USM (only USM is defined in SNMPv3 standard)</exception> public UserSecurityModel GetUSM(byte[] berBuffer, int length) { MutableByte buffer = new MutableByte(berBuffer, length); int offset = 0; // let base class parse first sequence and SNMP version number offset = base.Decode(buffer, length); // check for correct SNMP protocol version if (_protocolVersion != (int)SnmpVersion.Ver3) { throw new SnmpInvalidVersionException("Expecting SNMP version 3."); } // now grab the global message data sequence header information byte asnType = AsnType.ParseHeader(buffer, ref offset, out int len); if (asnType != SnmpConstants.SMI_SEQUENCE) { throw new SnmpDecodingException("Invalid sequence type when decoding global message data sequence."); } // check that packet size can accommodate the length specified in the header if (len > (buffer.Length - offset)) { throw new OverflowException("Packet is too small to contain the data described in the header."); } // retrieve message id offset = _messageId.Decode(buffer, offset); // max message size offset = _maxMessageSize.Decode(buffer, offset); // message flags offset = MsgFlags.Decode(buffer, offset); // verify that a valid authentication/privacy configuration is present in the packet if (MsgFlags.Authentication == false && MsgFlags.Privacy == true) { throw new SnmpException(SnmpException.UnsupportedNoAuthPriv, "SNMP version 3 noAuthPriv security combination is not supported."); } // security model code offset = _securityModel.Decode(buffer, offset); // we only support USM. code = 0x03 if (_securityModel.Value != USM.Type) { throw new SnmpException(SnmpException.UnsupportedSecurityModel, "Class only support SNMP Version 3 User Security Model."); } // parse user security model offset = USM.Decode(buffer, offset); return(USM); }
/// <summary>BER encode class value.</summary> /// <param name="buffer">Target buffer. Value is appended to the end of it.</param> public override void encode(MutableByte buffer) { MutableByte tmp = new MutableByte(); byte[] b = BitConverter.GetBytes(_value); for (int i = 3; i >= 0; i--) { if (b[i] != 0 || tmp.Length > 0) { tmp.Append(b[i]); } } // if (tmp.Length > 1 && tmp[0] == 0xff && (tmp[1] & 0x80) != 0) if (tmp.Length > 0 && (tmp[0] & 0x80) != 0) { tmp.Prepend(0); } else if (tmp.Length == 0) { tmp.Append(0); } BuildHeader(buffer, Type, tmp.Length); buffer.Append(tmp); }
/// <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); }
/// <summary> /// Append BER encoded length to the <see cref="MutableByte"/> /// </summary> /// <param name="mb">MutableArray to append BER encoded length to</param> /// <param name="asnLength">Length value to encode.</param> /// <exception cref="ArgumentOutOfRangeException">Thrown when length value to encode is less then 0</exception> internal static void BuildLength(MutableByte mb, int asnLength) { if (asnLength < 0) { throw new ArgumentOutOfRangeException("Length cannot be less then 0."); } byte[] len = BitConverter.GetBytes(asnLength); MutableByte buf = new MutableByte(); for (int i = 3; i >= 0; i--) { if (len[i] != 0 || buf.Length > 0) { buf.Append(len[i]); } } if (buf.Length == 0) { // we are encoding a 0 value. Can't have a 0 byte length encoding buf.Append(0); } // check for short form encoding if (buf.Length == 1 && (buf[0] & HIGH_BIT) == 0) { mb.Append(buf); // done } else { // long form encoding byte encHeader = (byte)buf.Length; encHeader = (byte)(encHeader | HIGH_BIT); mb.Append(encHeader); mb.Append(buf); } }
/// <summary> /// Reset the class. Initialize all member values to class defaults. /// </summary> public void Reset() { _address = new IpAddress(System.Net.IPAddress.Loopback); _port = 161; _version = SnmpVersion.Ver3; _timeout = 2000; _retry = 1; _engineId = new OctetString(); _engineBoots = new Integer32(); _engineTime = new Integer32(); _engineTimeStamp = DateTime.MinValue; _privacyProtocol = PrivacyProtocols.None; _authenticationProtocol = AuthenticationDigests.None; _privacySecret = new MutableByte(); _authenticationSecret = new MutableByte(); _contextEngineId = new OctetString(); _contextName = new OctetString(); _securityName = new OctetString(); // max message size is initialized to 64KB by default. It will be // to the smaller of the two values after discovery process _maxMessageSize = new Integer32(64 * 1024); _reportable = true; }
/// <summary> /// Authenticate SNMP version 3 message. /// /// Before calling this member, entire SNMP version 3 packet needs to be encoded. After authentication /// process is completed, authenticationParameters value in the USM header is updated and SNMPv3 packet /// needs to be re-encoded to include it in the BER encoded stream prior to transmission. /// </summary> /// <param name="authKey">Authentication key (not password)</param> /// <param name="wholePacket">SNMP version 3 BER encoded packet.</param> public void Authenticate(byte[] authKey, ref MutableByte wholePacket) { IAuthenticationDigest authProto = SnmpSharpNet.Authentication.GetInstance(_authentication); byte[] authParam = authProto.authenticate(authKey, wholePacket); _authenticationParameters = new OctetString(authParam); }
/// <summary> /// Reset the class. Initialize all member values to class defaults. /// </summary> public void Reset() { _engineId = new OctetString(); _engineBoots = new Integer32(); _engineTime = new Integer32(); _engineTimeStamp = DateTime.MinValue; _privacyProtocol = PrivacyProtocols.None; _authenticationProtocol = AuthenticationDigests.None; _privacySecret = new MutableByte(); _authenticationSecret = new MutableByte(); _contextEngineId = new OctetString(); _contextName = new OctetString(); _securityName = new OctetString(); // max message size is initialized to 64KB by default. It will be // to the smaller of the two values after discovery process _maxMessageSize = new Integer32(64 * 1024); _reportable = true; _privacyKey = null; _authenticationKey = null; }
/// <summary>Encode SNMP packet for sending.</summary> /// <returns>BER encoded SNMP packet.</returns> public override byte[] Encode() { MutableByte buf = new MutableByte(); if (Pdu.Type != EPduType.Get && Pdu.Type != EPduType.GetNext && Pdu.Type != EPduType.Set && Pdu.Type != EPduType.V2Trap && Pdu.Type != EPduType.Response && Pdu.Type != EPduType.GetBulk && Pdu.Type != EPduType.Inform) { throw new SnmpInvalidPduTypeException("Invalid SNMP PDU type while attempting to encode PDU: " + string.Format("0x{0:x2}", 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.SmiSequence, buf.Length); buf.Prepend(tmpBuf); return(buf); }
/// <summary>Decode received SNMP packet.</summary> /// <param name="buffer">BER encoded packet buffer</param> /// <param name="length">BER encoded packet buffer length</param> /// <exception cref="SnmpException">Thrown when invalid encoding has been found in the packet</exception> /// <exception cref="OverflowException">Thrown when parsed header points to more data then is available in the packet</exception> /// <exception cref="SnmpInvalidVersionException">Thrown when parsed packet is not SNMP version 1</exception> /// <exception cref="SnmpInvalidPduTypeException">Thrown when received PDU is of a type not supported by SNMP version 1</exception> /// <returns>Returns the length of the decoded data</returns> public override int Decode(byte[] buffer, int length) { int offset = 0; offset = base.Decode(buffer, buffer.Length); if (Version != ESnmpVersion.Ver2) { throw new SnmpInvalidVersionException("Invalid protocol version"); } MutableByte buf = new MutableByte(buffer, length); offset = snmpCommunity.Decode(buf, offset); int tmpOffset = offset; byte asnType = AsnType.ParseHeader(buf, ref tmpOffset, out int headerLength); // Check packet length if (headerLength + offset > buf.Length) { throw new OverflowException("Insufficient data in packet"); } if (asnType != (byte)EPduType.Get && asnType != (byte)EPduType.GetNext && asnType != (byte)EPduType.Set && asnType != (byte)EPduType.GetBulk && asnType != (byte)EPduType.Response && asnType != (byte)EPduType.V2Trap && asnType != (byte)EPduType.Inform) { throw new SnmpInvalidPduTypeException("Invalid SNMP operation received: " + string.Format("0x{0:x2}", asnType)); } // Now process the Protocol Data Unit offset = Pdu.Decode(buf, offset); return(length); }
/// <summary> /// Convert user password to acceptable authentication key. /// </summary> /// <param name="userPassword">Authentication password</param> /// <param name="engineID">Authoritative engine id</param> /// <returns>Localized authentication key</returns> /// <exception cref="SnmpAuthenticationException">Thrown when key length is less then 8 bytes</exception> public byte[] PasswordToKey(byte[] userPassword, byte[] engineID) { // key length has to be at least 8 bytes long (RFC3414) if (userPassword == null || userPassword.Length < 8) { throw new SnmpAuthenticationException("Secret key is too short."); } int password_index = 0; int count = 0; MD5 md5 = new MD5CryptoServiceProvider(); byte[] sourceBuffer = new byte[1048576]; byte[] buf = new byte[64]; while (count < 1048576) { for (int i = 0; i < 64; ++i) { buf[i] = userPassword[password_index++ % userPassword.Length]; } Buffer.BlockCopy(buf, 0, sourceBuffer, count, buf.Length); count += 64; } byte[] digest = md5.ComputeHash(sourceBuffer); MutableByte tmpbuf = new MutableByte(); tmpbuf.Append(digest); tmpbuf.Append(engineID); tmpbuf.Append(digest); byte[] key = md5.ComputeHash(tmpbuf); return(key); }
/// <summary> /// Decode received SNMP packet. /// </summary> /// <param name="buffer">BER encoded packet buffer</param> /// <param name="length">BER encoded packet buffer length</param> /// <returns>Buffer position after the decoded packet.</returns> /// <exception cref="SnmpException">Thrown when invalid encoding has been found in the packet</exception> /// <exception cref="OverflowException">Thrown when parsed header points to more data then is available in the packet</exception> /// <exception cref="SnmpInvalidVersionException">Thrown when parsed packet is not SNMP version 1</exception> /// <exception cref="SnmpInvalidPduTypeException">Thrown when received PDU is of a type not supported by SNMP version 1</exception> public override int decode(byte[] buffer, int length) { MutableByte buf = new MutableByte(buffer, length); int headerLength; int offset = 0; offset = base.decode(buffer, buffer.Length); if (_protocolVersion.Value != (int)SnmpVersion.Ver1) { throw new SnmpInvalidVersionException("Invalid protocol version"); } offset = _snmpCommunity.decode(buf, offset); int tmpOffset = offset; byte asnType = AsnType.ParseHeader(buf, ref tmpOffset, out headerLength); // Check packet length if (headerLength + offset > buf.Length) { throw new OverflowException("Insufficient data in packet"); } if (asnType != (byte)PduType.Get && asnType != (byte)PduType.GetNext && asnType != (byte)PduType.Set && asnType != (byte)PduType.Response) { throw new SnmpInvalidPduTypeException("Invalid SNMP operation received: " + string.Format("0x{0:x2}", asnType)); } // Now process the Protocol Data Unit offset = this.Pdu.decode(buf, offset); return(length); }
/// <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); }
/// <summary> /// Authenticate SNMP version 3 message. /// /// Before calling this member, entire SNMP version 3 packet needs to be encoded. After authentication /// process is completed, authenticationParameters value in the USM header is updated and SNMPv3 packet /// needs to be re-encoded to include it in the BER encoded stream prior to transmission. /// </summary> /// <param name="wholePacket">SNMP version 3 BER encoded packet.</param> public void Authenticate(ref MutableByte wholePacket) { if (_authentication != AuthenticationDigests.None) { IAuthenticationDigest authProto = SnmpSharpNet.Authentication.GetInstance(_authentication); byte[] authParam = authProto.authenticate(AuthenticationSecret, EngineId.ToArray(), wholePacket); _authenticationParameters = new OctetString(authParam); } }
/// <summary> /// Authenticate message for sending. /// </summary> /// <param name="userPassword">User password</param> /// <param name="engineId">Authoritative engine id</param> /// <param name="wholeMessage">Un-authenticated message with authenticationParameter field set to 12 byte OctetString /// with all bytes initialized to 0x00.</param> /// <param name="authFieldOffset">Offset of the authentication field in the wholeMessage buffer</param> public void authenticateOutgoingMsg(byte[] userPassword, byte[] engineId, MutableByte wholeMessage, int authFieldOffset) { byte[] authKey = PasswordToKey(userPassword, engineId); HMACMD5 md5 = new HMACMD5(authKey); byte[] hash = md5.ComputeHash(wholeMessage); // copy 12 bytes of the hash into the wholeMessage Buffer.BlockCopy(hash, 0, wholeMessage, authFieldOffset, 12); }
/// <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 VarBind collection sequence /// </summary> /// <param name="buffer">Target buffer. Encoded VarBind collection is appended.</param> public override void Encode(MutableByte buffer) { MutableByte tmp = new MutableByte(); foreach (Vb v in _vbs) { v.Encode(tmp); } BuildHeader(buffer, Type, tmp.Length); buffer.Append(tmp); }
/// <summary> /// Wrap BER encoded SNMP information contained in the parameter <see cref="MutableByte"/> class. /// /// Information in the parameter is prepended by the SNMP version field and wrapped in a sequence header. /// /// Derived classes call this method to finalize SNMP packet encoding. /// </summary> /// <param name="buffer">Buffer containing BER encoded SNMP information</param> public virtual void Encode(MutableByte buffer) { // Encode SNMP protocol version MutableByte temp = new MutableByte(); _protocolVersion.Encode(temp); buffer.Prepend(temp); temp.Reset(); AsnType.BuildHeader(temp, SnmpConstants.SMI_SEQUENCE, buffer.Length); buffer.Prepend(temp); }
/// <summary> /// Authenticate incoming packet /// </summary> /// <param name="authKey">Authentication key (not password)</param> /// <param name="wholePacket">Received BER encoded SNMP version 3 packet</param> /// <returns>True if packet is successfully authenticated, otherwise false.</returns> public bool IsAuthentic(byte[] authKey, MutableByte wholePacket) { if (_authentication != AuthenticationDigests.None) { IAuthenticationDigest authProto = SnmpSharpNet.Authentication.GetInstance(_authentication); if (authProto != null) { return(authProto.authenticateIncomingMsg(authKey, _authenticationParameters, wholePacket)); } } return(false); // Nothing to authenticate }
/// <summary> /// Copy constructor. /// </summary> /// <param name="value">Class to copy values from</param> public UserSecurityModel(UserSecurityModel value) : this() { _engineId.Set(value.EngineId); _engineBoots.Value = value.EngineBoots; _engineTime.Value = value.EngineTime; _securityName.Set(value.SecurityName); _authenticationParameters = new OctetString(); _privacySecret = new MutableByte(); _privacy = PrivacyProtocols.None; _privacyParameters = new OctetString(); }
/// <summary> /// Verify MD5 authentication of a packet. /// </summary> /// <param name="authKey">Authentication key (not password)</param> /// <param name="authenticationParameters">Authentication parameters extracted from the packet being authenticated</param> /// <param name="wholeMessage">Entire packet being authenticated</param> /// <returns>True on authentication success, otherwise false</returns> public bool authenticateIncomingMsg(byte[] authKey, byte[] authenticationParameters, MutableByte wholeMessage) { var md5 = new HMACMD5(authKey); var hash = md5.ComputeHash(wholeMessage, 0, wholeMessage.Length); var myhash = new MutableByte(hash, 12); if (myhash.Equals(authenticationParameters)) { return(true); } return(false); }
/// <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); Pdu.Encode(tmpBuffer); Encode(tmpBuffer); return(tmpBuffer); }
/// <summary>BER encode OctetString variable.</summary> /// <param name="buffer"><see cref="MutableByte"/> encoding destination.</param> public override void encode(MutableByte buffer) { if (_data == null || _data.Length == 0) { BuildHeader(buffer, Type, 0); } else { BuildHeader(buffer, Type, _data.Length); buffer.Append(_data); } }
/// <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); }
/// <summary> /// Verify SHA-1 authentication of a packet. /// </summary> /// <param name="authKey">Authentication key (not password)</param> /// <param name="authenticationParameters">Authentication parameters extracted from the packet being authenticated</param> /// <param name="wholeMessage">Entire packet being authenticated</param> /// <returns>True on authentication success, otherwise false</returns> public bool authenticateIncomingMsg(byte[] authKey, byte[] authenticationParameters, MutableByte wholeMessage) { var sha = new HMACSHA1(authKey); var hash = sha.ComputeHash(wholeMessage); var myhash = new MutableByte(hash, 12); sha.Clear(); // release resources if (myhash.Equals(authenticationParameters)) { return(true); } return(false); }
/// <summary> /// Authenticate message for sending. /// </summary> /// <param name="userPassword">User password</param> /// <param name="engineId">Authoritative engine id</param> /// <param name="wholeMessage">Un-authenticated message with authenticationParameter field set to 12 byte OctetString /// with all bytes initialized to 0x00.</param> /// <param name="authFieldOffset">Offset of the authentication field in the wholeMessage buffer</param> public void authenticateOutgoingMsg(byte[] userPassword, byte[] engineId, MutableByte wholeMessage, int authFieldOffset) { byte[] authKey = PasswordToKey(userPassword, engineId); HMACSHA1 sha = new HMACSHA1(authKey); byte[] hash = sha.ComputeHash(wholeMessage); // copy 12 bytes of the hash into the wholeMessage for (int i = 0; i < 12; i++) { wholeMessage[authFieldOffset + i] = hash[i]; } sha.Clear(); // release resources }
/// <summary> /// Encode VarBind collection sequence /// </summary> /// <param name="buffer">Target buffer. Encoded VarBind collection is appended.</param> public override void encode(MutableByte buffer) { var tmp = new MutableByte(); //foreach (Vb v in _vbs) //{ // v.encode(tmp); //} //Awais this optimization needs review. Parallel.ForEach(_vbs, v => { v.encode(tmp); }); BuildHeader(buffer, Type, tmp.Length); buffer.Append(tmp); }
/// <summary> /// BER encode sequence /// </summary> /// <param name="buffer">Target buffer</param> public override void encode(MutableByte buffer) { int dataLen = 0; if (_data != null && _data.Length > 0) { dataLen = _data.Length; } BuildHeader(buffer, Type, dataLen); if (dataLen > 0) { buffer.Append(_data); } }
/// <summary> /// Verifies correct MD5 authentication of the frame. Prior to calling this method, you have to extract authentication /// parameters from the wholeMessage and reset authenticationParameters field in the USM information block to 12 0x00 /// values. /// </summary> /// <param name="userPassword">User password</param> /// <param name="engineId">Authoritative engine id</param> /// <param name="authenticationParameters">Extracted USM authentication parameters</param> /// <param name="wholeMessage">Whole message with authentication parameters zeroed (0x00) out</param> /// <returns>True if message authentication has passed the check, otherwise false</returns> public bool authenticateIncomingMsg(byte[] userPassword, byte[] engineId, byte[] authenticationParameters, MutableByte wholeMessage) { byte[] authKey = PasswordToKey(userPassword, engineId); HMACMD5 md5 = new HMACMD5(authKey); byte[] hash = md5.ComputeHash(wholeMessage, 0, wholeMessage.Length); MutableByte myhash = new MutableByte(hash, 12); if (myhash.Equals(authenticationParameters)) { return(true); } return(false); }
/// <summary> /// Verifies correct SHA-1 authentication of the frame. Prior to calling this method, you have to extract authentication /// parameters from the wholeMessage and reset authenticationParameters field in the USM information block to 12 0x00 /// values. /// </summary> /// <param name="userPassword">User password</param> /// <param name="engineId">Authoritative engine id</param> /// <param name="authenticationParameters">Extracted USM authentication parameters</param> /// <param name="wholeMessage">Whole message with authentication parameters zeroed (0x00) out</param> /// <returns>True if message authentication has passed the check, otherwise false</returns> public bool authenticateIncomingMsg(byte[] userPassword, byte[] engineId, byte[] authenticationParameters, MutableByte wholeMessage) { byte[] authKey = PasswordToKey(userPassword, engineId); HMACSHA1 sha = new HMACSHA1(authKey); byte[] hash = sha.ComputeHash(wholeMessage); MutableByte myhash = new MutableByte(hash, 12); sha.Clear(); // release resources if (myhash.Equals(authenticationParameters)) { return(true); } return(false); }