/// <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 noAuthNoPriv operations. Set authentication and privacy protocols to none. /// </summary> /// <param name="securityName">User security name</param> public void noAuthNoPriv(string securityName) { _securityName.Set(securityName); _authenticationProtocol = AuthenticationDigests.None; _authenticationSecret.Clear(); _privacyProtocol = PrivacyProtocols.None; _privacySecret.Clear(); }
/// <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> /// 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> /// Update class values with SNMP version 3 discovery values from the supplied <see cref="SnmpV3Packet"/> /// class. Values updated are EngineId, EngineTime and EngineBoots. /// </summary> /// <param name="packet"><see cref="SnmpV3Packet"/> class 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 UpdateDiscoveryValues(SnmpPacket packet) { if (packet is SnmpV3Packet) { SnmpV3Packet pkt = (SnmpV3Packet)packet; _engineId.Set(pkt.USM.EngineId); _engineTime.Value = pkt.USM.EngineTime; _engineBoots.Value = pkt.USM.EngineBoots; UpdateTimeStamp(); _contextEngineId.Set(pkt.ScopedPdu.ContextEngineId); _contextName.Set(pkt.ScopedPdu.ContextName); } else { throw new SnmpInvalidVersionException("Invalid SNMP version."); } }
/// <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."); } }
/// <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> /// Standard constructor. /// </summary> /// <param name="snmpCommunity">SNMP community name for the packet</param> public SnmpV2Packet(string snmpCommunity) : this() { _snmpCommunity.Set(snmpCommunity); }
/// <summary> /// Copy constructor. Initialize the class with the values of the parameter class values. /// </summary> /// <param name="second">Parameter class.</param> public AgentParameters(AgentParameters second) { _version.Value = (int)second.Version; _community.Set(second.Community); }
/// <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); }
/// <summary>Copy constructor. Initialize the class with the values of the parameter class values.</summary> /// <param name="second">Parameter class.</param> public AgentParameters(AgentParameters second) { version.Value = (int)second.Version; community.Set(second.Community); disableReplySourceCheck = second.DisableReplySourceCheck; }