Skip to content

Commit ef55510

Browse files
committed
Add tests for SNMP V3 authentication and validation scenarios
1 parent c0d2372 commit ef55510

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

Tests/CSharpCore/Unit/Messaging/MessageFactoryTestFixture.cs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Lextm.SharpSnmpLib.Security;
1414
using Xunit;
1515
using System.IO;
16+
using System.Net.Security;
1617

1718
#pragma warning disable 1591, 0618
1819
namespace Lextm.SharpSnmpLib.Unit.Messaging
@@ -280,6 +281,19 @@ public void TestGetRequestV3AuthPrivAES2()
280281
"01 5D 01 F1 F4 EF 70 53 CC", output);
281282
}
282283

284+
[Fact]
285+
public void TestGetRequestV3AuthPriv_MD5_3DES()
286+
{
287+
const string bytes = "30 81 9A 02 01 03 30 11 02 04 16 39 99 3C 02 03 00 FF E3 04 01 07 02 01 03 04 40 30 3E 04 0E 80 00 4F B8 05 63 6C 6F 75 64 4D AB 22 CC 02 01 00 02 03 75 6B 5D 04 0C 75 73 72 2D 6D 64 35 2D 33 64 65 73 04 0C 88 3A 31 F2 4D FA 37 1D 40 43 51 EC 04 08 00 00 00 00 3A 90 A4 49 04 40 77 0E B3 60 5E 97 7B 53 3E 21 FD B1 74 6B 73 CF 8A AF C1 14 0B C5 AA EF 2C A3 4F 5E FF 07 BD 37 AF 14 64 91 1B AB 23 E5 C8 52 8E 64 0F FF 67 A3 CB 6D 68 0B 96 67 C5 79 93 AF 02 B2 02 CD B5 CF";
288+
var auth = new MD5AuthenticationProvider(new OctetString("authkey1"));
289+
var privacy = new TripleDESPrivacyProvider(new OctetString("privkey1"), auth);
290+
291+
var registry = new UserRegistry();
292+
registry.Add(new OctetString("usr-md5-3des"), privacy);
293+
var messages = MessageFactory.ParseMessages(bytes, registry);
294+
Assert.Single(messages);
295+
}
296+
283297
[Fact]
284298
public void TestGetRequestV3Auth()
285299
{
@@ -593,6 +607,117 @@ public void TestBadResponseFromPrinter()
593607
var exception = Assert.Throws<SnmpException>(() => MessageFactory.ParseMessages(bytes, new UserRegistry()));
594608
Assert.Contains($"Byte length cannot be 0.", exception.InnerException.Message);
595609
}
610+
611+
[Fact]
612+
public void TestIsInvalidWithWrongPassword()
613+
{
614+
byte[] bytes = File.ReadAllBytes(Path.Combine("Resources", "trapv3auth"));
615+
616+
// Create registry with a user that has the wrong authentication password
617+
UserRegistry registry = new UserRegistry();
618+
registry.Add(new OctetString("lextm"), new DefaultPrivacyProvider(new MD5AuthenticationProvider(new OctetString("wrongpassword"))));
619+
620+
// Parse the message with the wrong password
621+
IList<ISnmpMessage> messages = MessageFactory.ParseMessages(bytes, registry);
622+
Assert.Single(messages);
623+
ISnmpMessage message = messages[0];
624+
625+
// Verify the message was parsed but the IsInvalid flag was set due to hash verification failure
626+
Assert.Equal("lextm", message.Parameters.UserName.ToString());
627+
Assert.True(message.Parameters.IsInvalid, "IsInvalid flag should be true when authentication fails");
628+
629+
// Verify correct message properties despite invalid authentication
630+
Assert.Equal("80001F8880E9630000D61FF449", message.Parameters.EngineId.ToHexString());
631+
Assert.Equal(0, message.Parameters.EngineBoots.ToInt32());
632+
Assert.Equal(0, message.Parameters.EngineTime.ToInt32());
633+
Assert.Equal("84433969457707152C289A3E", message.Parameters.AuthenticationParameters.ToHexString());
634+
}
635+
636+
[Fact]
637+
public void TestIsInvalidWithCorrectPassword()
638+
{
639+
byte[] bytes = File.ReadAllBytes(Path.Combine("Resources", "trapv3auth"));
640+
641+
// Create registry with a user that has the correct authentication password
642+
UserRegistry registry = new UserRegistry();
643+
registry.Add(new OctetString("lextm"), new DefaultPrivacyProvider(new MD5AuthenticationProvider(new OctetString("authentication"))));
644+
645+
// Parse the message with the correct password
646+
IList<ISnmpMessage> messages = MessageFactory.ParseMessages(bytes, registry);
647+
Assert.Single(messages);
648+
ISnmpMessage message = messages[0];
649+
650+
// The message should be valid when the correct password is used
651+
Assert.Equal("lextm", message.Parameters.UserName.ToString());
652+
Assert.False(message.Parameters.IsInvalid, "IsInvalid flag should be false when authentication succeeds");
653+
654+
// Verify correct message properties with valid authentication
655+
Assert.Equal("80001F8880E9630000D61FF449", message.Parameters.EngineId.ToHexString());
656+
Assert.Equal("84433969457707152C289A3E", message.Parameters.AuthenticationParameters.ToHexString());
657+
}
658+
659+
[Fact]
660+
public void TestIsInvalidWithSHA1Authentication()
661+
{
662+
byte[] bytes = File.ReadAllBytes(Path.Combine("Resources", "v3authNoPriv_BER_Issue"));
663+
664+
// Test with wrong password
665+
UserRegistry registry = new UserRegistry();
666+
SHA1AuthenticationProvider wrongAuth = new SHA1AuthenticationProvider(new OctetString("wrongpassword"));
667+
registry.Add(new OctetString("test"), new DefaultPrivacyProvider(wrongAuth));
668+
669+
IList<ISnmpMessage> messages = MessageFactory.ParseMessages(bytes, registry);
670+
Assert.Single(messages);
671+
ISnmpMessage message = messages[0];
672+
673+
// Verify the IsInvalid flag is set when SHA1 authentication fails
674+
Assert.Equal("test", message.Parameters.UserName.ToString());
675+
Assert.True(message.Parameters.IsInvalid, "IsInvalid flag should be true when SHA1 authentication fails");
676+
677+
// Now test with correct password
678+
registry = new UserRegistry();
679+
SHA1AuthenticationProvider correctAuth = new SHA1AuthenticationProvider(new OctetString("testpass"));
680+
registry.Add(new OctetString("test"), new DefaultPrivacyProvider(correctAuth));
681+
682+
messages = MessageFactory.ParseMessages(bytes, registry);
683+
Assert.Single(messages);
684+
message = messages[0];
685+
686+
// The IsInvalid flag should be false when using correct password
687+
Assert.False(message.Parameters.IsInvalid, "IsInvalid flag should be false when SHA1 authentication succeeds");
688+
}
689+
690+
[Fact]
691+
public void TestIsInvalidCanBeCheckedByApplication()
692+
{
693+
byte[] bytes = File.ReadAllBytes(Path.Combine("Resources", "trapv3auth"));
694+
695+
// Create registry with a user that has the wrong authentication password
696+
UserRegistry registry = new UserRegistry();
697+
registry.Add(new OctetString("lextm"), new DefaultPrivacyProvider(new MD5AuthenticationProvider(new OctetString("wrongpassword"))));
698+
699+
// Parse the message with the wrong password
700+
IList<ISnmpMessage> messages = MessageFactory.ParseMessages(bytes, registry);
701+
Assert.Single(messages);
702+
ISnmpMessage message = messages[0];
703+
704+
// This demonstrates how an application can check the IsInvalid flag to detect auth failures
705+
if (message.Parameters.IsInvalid)
706+
{
707+
// The application can log or handle the authentication failure here,
708+
// but still has access to the message content for inspection
709+
Assert.Equal("lextm", message.Parameters.UserName.ToString());
710+
Assert.Equal("80001F8880E9630000D61FF449", message.Parameters.EngineId.ToHexString());
711+
712+
// In real-world applications, you would typically reject the message or log the authentication failure
713+
// Rather than accepting the potentially tampered contents
714+
}
715+
else
716+
{
717+
// Should not reach here
718+
Assert.True(message.Parameters.IsInvalid, "Authentication should have failed with wrong password");
719+
}
720+
}
596721
}
597722
}
598723
#pragma warning restore 1591, 0618

0 commit comments

Comments
 (0)