WIP USM
parent
e6b25374f3
commit
3a084820f5
|
@ -15,6 +15,7 @@ using System.Net;
|
|||
using System.Threading;
|
||||
using ln.snmp.asn1;
|
||||
using ln.logging;
|
||||
using ln.snmp.endpoint;
|
||||
|
||||
namespace ln.snmp
|
||||
{
|
||||
|
@ -29,6 +30,8 @@ namespace ln.snmp
|
|||
private bool shutdown = false;
|
||||
private Thread ReceiverThread { get; set; }
|
||||
|
||||
private Dictionary<IPEndPoint, SnmpEndpoint> currentEndpoints = new Dictionary<IPEndPoint, SnmpEndpoint>();
|
||||
|
||||
|
||||
private int nextMessageID = (int)DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
public int NextMessageID => nextMessageID++;
|
||||
|
@ -101,6 +104,17 @@ namespace ln.snmp
|
|||
}
|
||||
}
|
||||
|
||||
public void SendMessage(IPEndPoint remoteEndpoint,SnmpMessage message)
|
||||
{
|
||||
ASN1Value snmpMessage = message;
|
||||
byte[] snmpMessageBytes = snmpMessage.AsByteArray;
|
||||
|
||||
lock (LocalEndpoint)
|
||||
{
|
||||
LocalEndpoint.Send(snmpMessageBytes, snmpMessageBytes.Length, remoteEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
public SnmpMessage SNMPRequest(IPEndPoint remoteEndpoint,SnmpMessage snmpMessage,int timeout)
|
||||
{
|
||||
lock (queuedRequests)
|
||||
|
@ -136,6 +150,23 @@ namespace ln.snmp
|
|||
}
|
||||
}
|
||||
|
||||
public void RegisterEndpoint(SnmpEndpoint intf)
|
||||
{
|
||||
lock (currentEndpoints)
|
||||
{
|
||||
currentEndpoints.Add(intf.RemoteEndpoint,intf);
|
||||
}
|
||||
}
|
||||
public void UnregisterEndpoint(SnmpEndpoint intf)
|
||||
{
|
||||
lock (currentEndpoints)
|
||||
{
|
||||
currentEndpoints.Remove(intf.RemoteEndpoint);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (ReceiverThread != null)
|
||||
|
|
|
@ -3,24 +3,19 @@ using ln.snmp.types;
|
|||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ln.snmp.channel;
|
||||
using ln.snmp.endpoint;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ln.snmp
|
||||
{
|
||||
public enum SnmpVersion : int { V1 = 0, V2c = 1, V3 = 3 }
|
||||
|
||||
public abstract class SNMPInterface
|
||||
public abstract class SnmpInterface : IDisposable
|
||||
{
|
||||
public SNMPEngine SNMPEngine { get; }
|
||||
public IPEndPoint RemoteEndpoint { get; set; }
|
||||
|
||||
public abstract SnmpVersion SnmpVersion { get; }
|
||||
|
||||
public SNMPInterface(SNMPEngine snmpEngine,IPEndPoint remoteEndpoint)
|
||||
public SnmpInterface()
|
||||
{
|
||||
SNMPEngine = snmpEngine;
|
||||
RemoteEndpoint = remoteEndpoint;
|
||||
}
|
||||
|
||||
public abstract PDU snmpRequest(PDU pdu);
|
||||
|
@ -264,6 +259,9 @@ namespace ln.snmp
|
|||
return snmpWalk(new ObjectIdentifier(objectIdentifier));
|
||||
}
|
||||
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
SNMPEngine.UnregisterEndpoint(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,145 +0,0 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using ln.snmp.types;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
using ln.snmp.asn1;
|
||||
using System.Linq;
|
||||
|
||||
namespace ln.snmp.channel
|
||||
{
|
||||
public enum SnmpV3AuthMethod { MD5, SHA }
|
||||
public enum SnmpV3PrivMethod { DES }
|
||||
public enum SnmpAuthLevel : int { noAuthNoPriv = 0, authNoPriv = 0x01, authPriv = 0x03 }
|
||||
|
||||
public class USMEndpoint : SNMPInterface
|
||||
{
|
||||
public OctetString RemoteEngineID { get; set; }
|
||||
|
||||
public string Username { get; set; }
|
||||
public string AuthKey { get; set; }
|
||||
public string PrivKey { get; set; }
|
||||
|
||||
public SnmpV3AuthMethod AuthMethod { get; set; }
|
||||
public SnmpV3PrivMethod PrivMethod { get; set; }
|
||||
|
||||
public override SnmpVersion SnmpVersion => SnmpVersion.V3;
|
||||
|
||||
public USMEndpoint(SNMPEngine snmpEngine,IPEndPoint remoteEndpoint)
|
||||
:base(snmpEngine,remoteEndpoint)
|
||||
{
|
||||
}
|
||||
|
||||
public SnmpAuthLevel AuthLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PrivKey != null)
|
||||
return SnmpAuthLevel.authPriv;
|
||||
if (AuthKey != null)
|
||||
return SnmpAuthLevel.authNoPriv;
|
||||
|
||||
return SnmpAuthLevel.noAuthNoPriv;
|
||||
}
|
||||
}
|
||||
|
||||
public override PDU snmpRequest(PDU pdu)
|
||||
{
|
||||
if ((RemoteEngineID == null)||(RemoteEngineID.Bytes.Length == 0))
|
||||
{
|
||||
QueryEngineID();
|
||||
}
|
||||
|
||||
USMMessage request = new USMMessage();
|
||||
ScopedPDU scopedPDU = new ScopedPDU();
|
||||
|
||||
request.MessageID = SNMPEngine.NextMessageID;
|
||||
request.msgData = scopedPDU;
|
||||
|
||||
scopedPDU.contextEngineID = RemoteEngineID;
|
||||
scopedPDU.PDU = pdu;
|
||||
|
||||
AuthenticateMessage(request);
|
||||
|
||||
|
||||
SnmpMessage reply = SNMPEngine.SNMPRequest(RemoteEndpoint, request, SNMPEngine.Timeout);
|
||||
USMMessage replyUSM = reply as USMMessage;
|
||||
|
||||
PDU responsePDU = (replyUSM.msgData as ScopedPDU).PDU;
|
||||
|
||||
return responsePDU;
|
||||
}
|
||||
|
||||
public void QueryEngineID()
|
||||
{
|
||||
USMMessage queryMessage = new USMMessage();
|
||||
queryMessage.MessageID = SNMPEngine.NextMessageID;
|
||||
|
||||
ScopedPDU scopedPDU = new ScopedPDU();
|
||||
|
||||
queryMessage.msgData = scopedPDU;
|
||||
|
||||
queryMessage.Dump();
|
||||
|
||||
|
||||
SnmpMessage reply = SNMPEngine.SNMPRequest(RemoteEndpoint, queryMessage, SNMPEngine.Timeout);
|
||||
USMMessage usmReply = reply as USMMessage;
|
||||
|
||||
RemoteEngineID = usmReply.SecurityParameters.msgAuthoritativeEngineID;
|
||||
}
|
||||
|
||||
public bool AuthenticateMessage(USMMessage message)
|
||||
{
|
||||
message.msgGlobalData.msgFlags.Bytes = new byte[] { (byte)(int)AuthLevel };
|
||||
message.SecurityParameters.msgUserName.StringValue = Username;
|
||||
message.SecurityParameters.msgAuthoritativeEngineID = RemoteEngineID;
|
||||
message.SecurityParameters.msgAuthenticationParameters.Bytes = new byte[12];
|
||||
|
||||
byte[] wholeMsg = ((ASN1Value)message).AsByteArray;
|
||||
|
||||
byte[] extendedAuthKey = new byte[64];
|
||||
byte[] authKey = Encoding.ASCII.GetBytes(AuthKey);
|
||||
|
||||
//Array.Copy(authKey, extendedAuthKey, 16);
|
||||
|
||||
//byte[] K1 = new byte[64];
|
||||
//for (int n = 0; n < 64; n++)
|
||||
// K1[n] = (byte)(extendedAuthKey[n] ^ IPAD[n]);
|
||||
|
||||
//byte[] K2 = new byte[64];
|
||||
//for (int n = 0; n < 64; n++)
|
||||
//K2[n] = (byte)(extendedAuthKey[n] ^ OPAD[n]);
|
||||
|
||||
HMAC hmac = null;
|
||||
|
||||
switch (AuthMethod)
|
||||
{
|
||||
case SnmpV3AuthMethod.MD5:
|
||||
hmac = HMACMD5.Create();
|
||||
break;
|
||||
case SnmpV3AuthMethod.SHA:
|
||||
hmac = HMACSHA1.Create();
|
||||
break;
|
||||
}
|
||||
|
||||
hmac.Key = authKey;
|
||||
byte[] mac = hmac.ComputeHash(wholeMsg);
|
||||
|
||||
message.SecurityParameters.msgAuthenticationParameters.Bytes = mac.Take(12).ToArray();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static byte[] IPAD = __PAD(0x36);
|
||||
static byte[] OPAD = __PAD(0x5C);
|
||||
|
||||
public static byte[] __PAD(byte pad)
|
||||
{
|
||||
byte[] ipad = new byte[0x40];
|
||||
for (int n = 0; n < ipad.Length; n++)
|
||||
ipad[n] = pad;
|
||||
return ipad;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using ln.snmp.types;
|
||||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ln.snmp.endpoint;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using ln.logging;
|
||||
|
||||
namespace ln.snmp.endpoint
|
||||
{
|
||||
public abstract class SnmpEndpoint : SnmpInterface, IDisposable
|
||||
{
|
||||
public SNMPEngine SNMPEngine { get; }
|
||||
public IPEndPoint RemoteEndpoint { get; set; }
|
||||
|
||||
public SnmpEndpoint(SNMPEngine snmpEngine, IPEndPoint remoteEndpoint)
|
||||
{
|
||||
SNMPEngine = snmpEngine;
|
||||
RemoteEndpoint = remoteEndpoint;
|
||||
SNMPEngine.RegisterEndpoint(this);
|
||||
}
|
||||
|
||||
public virtual void Send(SnmpMessage message)
|
||||
{
|
||||
message = Encrypt(message);
|
||||
message = ApplyAuthentication(message);
|
||||
SNMPEngine.SendMessage(RemoteEndpoint, message);
|
||||
}
|
||||
|
||||
public virtual void Received(SnmpMessage message)
|
||||
{
|
||||
message = CheckAuthentication(message);
|
||||
message = Decrypt(message);
|
||||
|
||||
|
||||
|
||||
lock (queuedRequests)
|
||||
{
|
||||
if (queuedRequests.ContainsKey(message.MessageID))
|
||||
{
|
||||
SnmpMessage queuedMessage = queuedRequests[message.MessageID];
|
||||
lock (queuedMessage)
|
||||
{
|
||||
queuedRequests[message.MessageID] = message;
|
||||
Monitor.PulseAll(queuedMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logging.Log(LogLevel.WARNING, "SNMPEndpoint: Received unqueued message id: {0} (0x{0:x8})", message.MessageID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract SnmpMessage Encrypt(SnmpMessage message);
|
||||
public abstract SnmpMessage ApplyAuthentication(SnmpMessage message);
|
||||
|
||||
public abstract SnmpMessage CheckAuthentication(SnmpMessage message);
|
||||
public abstract SnmpMessage Decrypt(SnmpMessage message);
|
||||
|
||||
/**
|
||||
* Requests
|
||||
**/
|
||||
private Dictionary<int, SnmpMessage> queuedRequests = new Dictionary<int, SnmpMessage>();
|
||||
|
||||
public SnmpMessage EnqueueRequest(SnmpMessage requestMessage)
|
||||
{
|
||||
requestMessage.MessageID = SNMPEngine.NextMessageID;
|
||||
|
||||
lock (queuedRequests)
|
||||
{
|
||||
queuedRequests.Add(requestMessage.MessageID, requestMessage);
|
||||
lock (requestMessage)
|
||||
{
|
||||
Send(requestMessage);
|
||||
|
||||
Monitor.Exit(queuedRequests);
|
||||
Monitor.Wait(requestMessage, SNMPEngine.Timeout);
|
||||
Monitor.Enter(queuedRequests);
|
||||
}
|
||||
|
||||
SnmpMessage responseMessage = queuedRequests[requestMessage.MessageID];
|
||||
if (responseMessage == requestMessage)
|
||||
throw new TimeoutException();
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
SNMPEngine.UnregisterEndpoint(this);
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,9 +3,9 @@ using ln.snmp.types;
|
|||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ln.snmp.channel
|
||||
namespace ln.snmp.endpoint
|
||||
{
|
||||
public class SnmpV1Endpoint : SNMPInterface
|
||||
public class SnmpV1Endpoint : SnmpEndpoint
|
||||
{
|
||||
public OctetString CommunityString { get; set; }
|
||||
|
|
@ -3,9 +3,9 @@ using ln.snmp.types;
|
|||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ln.snmp.channel
|
||||
namespace ln.snmp.endpoint
|
||||
{
|
||||
public class SnmpV2Endpoint : SNMPInterface
|
||||
public class SnmpV2Endpoint : SnmpEndpoint
|
||||
{
|
||||
public OctetString CommunityString { get; set; }
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using ln.snmp.types;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
using ln.snmp.asn1;
|
||||
using System.Linq;
|
||||
using ln.logging;
|
||||
|
||||
namespace ln.snmp.endpoint
|
||||
{
|
||||
public enum SnmpV3AuthMethod { MD5, SHA }
|
||||
public enum SnmpV3PrivMethod { DES }
|
||||
public enum SnmpAuthLevel : int { noAuthNoPriv = 0, authNoPriv = 0x01, authPriv = 0x03 }
|
||||
|
||||
public class USMEndpoint : SnmpEndpoint
|
||||
{
|
||||
public OctetString RemoteEngineID { get; set; }
|
||||
public Integer CacheAuthoritativeEngineBoots { get; set; }
|
||||
public Integer CacheAuthoritativeEngineTime { get; set; }
|
||||
|
||||
public string Username { get; set; }
|
||||
|
||||
public byte[] AuthKey { get; set; }
|
||||
public byte[] PrivKey { get; set; }
|
||||
|
||||
public byte[] LocalAuthKey { get; set; }
|
||||
public byte[] LocalPrivKey { get; set; }
|
||||
|
||||
public SnmpV3AuthMethod AuthMethod { get; set; }
|
||||
public SnmpV3PrivMethod PrivMethod { get; set; }
|
||||
|
||||
public override SnmpVersion SnmpVersion => SnmpVersion.V3;
|
||||
|
||||
public USMEndpoint(SNMPEngine snmpEngine,IPEndPoint remoteEndpoint)
|
||||
:base(snmpEngine,remoteEndpoint)
|
||||
{
|
||||
}
|
||||
|
||||
public SnmpAuthLevel AuthLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PrivKey != null)
|
||||
return SnmpAuthLevel.authPriv;
|
||||
if (AuthKey != null)
|
||||
return SnmpAuthLevel.authNoPriv;
|
||||
|
||||
return SnmpAuthLevel.noAuthNoPriv;
|
||||
}
|
||||
}
|
||||
|
||||
public override PDU snmpRequest(PDU pdu)
|
||||
{
|
||||
if ((RemoteEngineID == null)||(RemoteEngineID.Bytes.Length == 0))
|
||||
{
|
||||
QueryEngineID();
|
||||
}
|
||||
|
||||
USMMessage request = new USMMessage();
|
||||
ScopedPDU scopedPDU = new ScopedPDU();
|
||||
|
||||
request.MessageID = SNMPEngine.NextMessageID;
|
||||
|
||||
request.msgData = scopedPDU;
|
||||
|
||||
scopedPDU.contextEngineID = RemoteEngineID;
|
||||
scopedPDU.PDU = pdu;
|
||||
|
||||
AuthenticateMessage(request);
|
||||
|
||||
USMMessage replyUSM = InternalRequest(request);
|
||||
|
||||
PDU responsePDU = (replyUSM.msgData as ScopedPDU).PDU;
|
||||
|
||||
return responsePDU;
|
||||
}
|
||||
|
||||
private USMMessage InternalRequest(USMMessage request)
|
||||
{
|
||||
SnmpMessage reply = SNMPEngine.SNMPRequest(RemoteEndpoint, request, SNMPEngine.Timeout);
|
||||
USMMessage usmReply = reply as USMMessage;
|
||||
|
||||
CacheAuthoritativeEngineBoots = usmReply.SecurityParameters.msgAuthoritativeEngineBoots;
|
||||
CacheAuthoritativeEngineTime = usmReply.SecurityParameters.msgAuthoritativeEngineTime;
|
||||
|
||||
return usmReply;
|
||||
}
|
||||
|
||||
public void QueryEngineID()
|
||||
{
|
||||
USMMessage queryMessage = new USMMessage();
|
||||
queryMessage.MessageID = SNMPEngine.NextMessageID;
|
||||
|
||||
ScopedPDU scopedPDU = new ScopedPDU();
|
||||
|
||||
queryMessage.msgData = scopedPDU;
|
||||
|
||||
queryMessage.Dump();
|
||||
|
||||
USMMessage usmReply = InternalRequest(queryMessage);
|
||||
|
||||
RemoteEngineID = usmReply.SecurityParameters.msgAuthoritativeEngineID;
|
||||
//RemoteEngineID.Bytes = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 };
|
||||
|
||||
LocalizeKeys();
|
||||
}
|
||||
|
||||
public bool AuthenticateMessage(USMMessage message)
|
||||
{
|
||||
message.msgGlobalData.msgFlags.Bytes = new byte[] { (byte)(int)AuthLevel };
|
||||
message.SecurityParameters.msgUserName.StringValue = Username;
|
||||
message.SecurityParameters.msgAuthoritativeEngineID = RemoteEngineID;
|
||||
message.SecurityParameters.msgAuthenticationParameters.Bytes = new byte[12];
|
||||
message.SecurityParameters.msgAuthoritativeEngineBoots = CacheAuthoritativeEngineBoots != null ? CacheAuthoritativeEngineBoots : new Integer();
|
||||
message.SecurityParameters.msgAuthoritativeEngineTime = CacheAuthoritativeEngineTime != null ? CacheAuthoritativeEngineTime : new Integer();
|
||||
|
||||
|
||||
byte[] wholeMsg = ((ASN1Value)message).AsByteArray;
|
||||
|
||||
byte[] extendedAuthKey = new byte[64];
|
||||
byte[] authKey = LocalAuthKey;
|
||||
|
||||
Array.Copy(authKey, extendedAuthKey, authKey.Length);
|
||||
|
||||
byte[] K1 = new byte[64];
|
||||
for (int n = 0; n < 64; n++)
|
||||
K1[n] = (byte)(extendedAuthKey[n] ^ IPAD[n]);
|
||||
|
||||
byte[] K2 = new byte[64];
|
||||
for (int n = 0; n < 64; n++)
|
||||
K2[n] = (byte)(extendedAuthKey[n] ^ OPAD[n]);
|
||||
|
||||
using (HashAlgorithm hash = CreateAuthHashAlgorithm())
|
||||
{
|
||||
byte[] b1 = new byte[K1.Length + wholeMsg.Length];
|
||||
|
||||
Array.Copy(K1, b1, K1.Length);
|
||||
Array.Copy(wholeMsg, 0, b1, K1.Length, wholeMsg.Length);
|
||||
|
||||
byte[] intermediate = hash.ComputeHash(b1);
|
||||
byte[] inter2 = new byte[K2.Length + intermediate.Length];
|
||||
|
||||
Array.Copy(K2, inter2, K2.Length);
|
||||
Array.Copy(intermediate, 0, inter2, K2.Length, intermediate.Length);
|
||||
|
||||
byte[] mac = hash.ComputeHash(inter2);
|
||||
|
||||
message.SecurityParameters.msgAuthenticationParameters.Bytes = mac.Take(12).ToArray();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private byte[] DeriveKey(string passphrase,HashAlgorithm hash)
|
||||
{
|
||||
using (hash)
|
||||
{
|
||||
byte[] pass = Encoding.ASCII.GetBytes(passphrase);
|
||||
byte[] block = new byte[64];
|
||||
|
||||
for (int n = 0; n < 1048576; n += 64)
|
||||
{
|
||||
for (int p = 0; p < block.Length; p++)
|
||||
{
|
||||
block[p] = pass[(p + n) % pass.Length];
|
||||
}
|
||||
hash.TransformBlock(block, 0, block.Length, block, 0);
|
||||
}
|
||||
|
||||
hash.TransformFinalBlock(new byte[0], 0, 0);
|
||||
|
||||
byte[] result = hash.Hash;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private HashAlgorithm CreateAuthHashAlgorithm()
|
||||
{
|
||||
return AuthMethod == SnmpV3AuthMethod.SHA ? (HashAlgorithm)SHA1.Create() : (HashAlgorithm)MD5.Create();
|
||||
}
|
||||
|
||||
private void LocalizeKeys()
|
||||
{
|
||||
if ((AuthKey != null) && (RemoteEngineID != null))
|
||||
{
|
||||
using (HashAlgorithm hash = CreateAuthHashAlgorithm())
|
||||
{
|
||||
byte[] engineID = (byte[])RemoteEngineID.Bytes.Clone();
|
||||
|
||||
hash.TransformBlock(AuthKey, 0, AuthKey.Length, AuthKey, 0);
|
||||
hash.TransformBlock(engineID, 0, engineID.Length, engineID, 0);
|
||||
hash.TransformBlock(AuthKey, 0, AuthKey.Length, AuthKey, 0);
|
||||
|
||||
hash.TransformFinalBlock(new byte[0], 0, 0);
|
||||
|
||||
LocalAuthKey = hash.Hash;
|
||||
|
||||
Logging.Log(LogLevel.DEBUG, "Derived LocalAuthKey from AuthKey: {0}", BitConverter.ToString(LocalAuthKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string AuthKeyPhrase
|
||||
{
|
||||
get => throw new NotSupportedException();
|
||||
set
|
||||
{
|
||||
AuthKey = DeriveKey(
|
||||
value,
|
||||
CreateAuthHashAlgorithm()
|
||||
);
|
||||
|
||||
Logging.Log(LogLevel.DEBUG, "Derived AuthKey from Phrase: {0}",BitConverter.ToString(AuthKey));
|
||||
|
||||
if (RemoteEngineID != null)
|
||||
LocalizeKeys();
|
||||
}
|
||||
}
|
||||
public string PrivKeyPhrase { get; set; }
|
||||
|
||||
|
||||
|
||||
|
||||
static byte[] IPAD = __PAD(0x36);
|
||||
static byte[] OPAD = __PAD(0x5C);
|
||||
|
||||
public static byte[] __PAD(byte pad)
|
||||
{
|
||||
byte[] ipad = new byte[0x40];
|
||||
for (int n = 0; n < ipad.Length; n++)
|
||||
ipad[n] = pad;
|
||||
return ipad;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -44,11 +44,10 @@
|
|||
<Compile Include="types\ObjectIdentifier.cs" />
|
||||
<Compile Include="types\Unsigned32.cs" />
|
||||
<Compile Include="types\Counter64.cs" />
|
||||
<Compile Include="SNMPInterface.cs" />
|
||||
<Compile Include="SnmpError.cs" />
|
||||
<Compile Include="channel\SnmpV1Endpoint.cs" />
|
||||
<Compile Include="channel\SnmpV2Endpoint.cs" />
|
||||
<Compile Include="channel\USMEndpoint.cs" />
|
||||
<Compile Include="endpoint\SnmpV1Endpoint.cs" />
|
||||
<Compile Include="endpoint\SnmpV2Endpoint.cs" />
|
||||
<Compile Include="endpoint\USMEndpoint.cs" />
|
||||
<Compile Include="types\V3Packet.cs" />
|
||||
<Compile Include="types\ScopedPDU.cs" />
|
||||
<Compile Include="asn1\ASN1Value.cs" />
|
||||
|
@ -57,10 +56,12 @@
|
|||
<Compile Include="types\SnmpV2Message.cs" />
|
||||
<Compile Include="types\USMMessage.cs" />
|
||||
<Compile Include="types\UsmSecurityParameters.cs" />
|
||||
<Compile Include="endpoint\SNMPEndpoint.cs" />
|
||||
<Compile Include="SNMPInterface.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="types\" />
|
||||
<Folder Include="channel\" />
|
||||
<Folder Include="endpoint\" />
|
||||
<Folder Include="asn1\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace ln.snmp.types
|
|||
public SnmpVersion SnmpVersion { get; }
|
||||
|
||||
public abstract int MessageID { get; set; }
|
||||
|
||||
public abstract PDU snmpPDU { get; set; }
|
||||
|
||||
public SnmpMessage(SnmpVersion snmpVersion)
|
||||
: base(new Identifier(IdentifierClass.UNIVERSAL, true, 0x10))
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace ln.snmp.types
|
|||
public class SnmpV1Message : SnmpMessage
|
||||
{
|
||||
public OctetString snmpCommunity { get; set; }
|
||||
public PDU snmpPDU { get; set; }
|
||||
public override PDU snmpPDU { get; set; }
|
||||
|
||||
public SnmpV1Message()
|
||||
:base(SnmpVersion.V1)
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace ln.snmp.types
|
|||
public class SnmpV2Message : SnmpMessage
|
||||
{
|
||||
public OctetString snmpCommunity { get; set; }
|
||||
public PDU snmpPDU { get; set; }
|
||||
public override PDU snmpPDU { get; set; }
|
||||
|
||||
public SnmpV2Message()
|
||||
:base(SnmpVersion.V2c)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
using System;
|
||||
using ln.snmp.asn1;
|
||||
using System.Linq;
|
||||
using ln.snmp.channel;
|
||||
using ln.snmp.endpoint;
|
||||
namespace ln.snmp.types
|
||||
{
|
||||
public class USMMessage : SnmpMessage
|
||||
|
@ -22,8 +22,17 @@ namespace ln.snmp.types
|
|||
public MsgGlobalData msgGlobalData { get; set; }
|
||||
public UsmSecurityParameters SecurityParameters { get; set; }
|
||||
|
||||
public ScopedPDU ScopedPDU { get; set; }
|
||||
public OctetString EncryptedPDU { get; set; }
|
||||
|
||||
public Variable msgData { get; set; }
|
||||
|
||||
public override PDU snmpPDU
|
||||
{
|
||||
get => ScopedPDU?.PDU;
|
||||
set => ScopedPDU.PDU = value;
|
||||
}
|
||||
|
||||
public USMMessage()
|
||||
: base(SnmpVersion.V3)
|
||||
{
|
||||
|
@ -50,6 +59,8 @@ namespace ln.snmp.types
|
|||
{
|
||||
msgGlobalData = new MsgGlobalData(value[1]);
|
||||
SecurityParameters = new UsmSecurityParameters(new ASN1Value(value[2].Bytes));
|
||||
|
||||
// ToDo: Check if value[3] is OctetString (Encrypted) or Sequence (ScopedPDU)
|
||||
msgData = value[3];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue