Skip to content

Commit

Permalink
Fix issue #28: SNMPv2c does not work anymore (ErrNoPermission)
Browse files Browse the repository at this point in the history
1. Introduction of SnmpV3Only Configuration:

A new `SecurityConfig` configuration option, `SnmpV3Only`, has been added.

This setting instructs the server to accept SNMP version 3 (SNMPv3) requests
exclusively. This addition is a response to the request made in issue #23,
aiming to provide enhanced security by leveraging SNMPv3's advanced features.

@see #23 (comment)

2. Code Improvements and Bug Fix for Issue #28:

The contributions from @adenis78 and @ConsoleTVs have been refined and
incorporated to resolve the issue where SNMPv2c was not functioning correctly.

3. Defensive Rechecking of Configuration and Community Handling:

Enhanced validation checks have been implemented to ensure robust error
handling and response mechanisms. In scenarios where the specified community
is not found within the subagent configuration, and there's an absence of a
SecurityConfig.NoSecurity setting, the server will now refrain from responding.

4. Utilization of NoSecurity for Compatibility and Testing:

The SecurityConfig.NoSecurity configuration has been introduced
to facilitate bypassing certain security checks.
  • Loading branch information
slayercat committed Mar 27, 2024
1 parent 1441bb5 commit 3fc3b33
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
38 changes: 36 additions & 2 deletions agentcontrol.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ type MasterAgent struct {
type SecurityConfig struct {
NoSecurity bool

// SnmpV3Only is used for mark only snmpv3 is supported
SnmpV3Only bool

// AuthoritativeEngineID is SNMPV3 AuthoritativeEngineID
AuthoritativeEngineID SNMPEngineID
// AuthoritativeEngineBoots is SNMPV3 AuthoritativeEngineBoots
Expand Down Expand Up @@ -130,6 +133,10 @@ func (t *MasterAgent) ResponseForBuffer(i []byte) ([]byte, error) {

switch request.Version {
case gosnmp.Version1, gosnmp.Version2c:
if t.SecurityConfig.SnmpV3Only {
return nil, errors.WithMessagef(ErrUnsupportedProtoVersion, "Server sets snmpV3 Only")
}

return t.marshalPkt(t.ResponseForPkt(request))
//
case gosnmp.Version3:
Expand All @@ -152,6 +159,30 @@ func (t *MasterAgent) ResponseForBuffer(i []byte) ([]byte, error) {
if err != nil {
return nil, err
}

if !t.SecurityConfig.NoSecurity{
// https://pkg.go.dev/github.com/gosnmp/gosnmp#SnmpV3MsgFlags
userAuthMode := gosnmp.NoAuthNoPriv


if usm.AuthenticationProtocol > gosnmp.NoAuth {
userAuthMode = gosnmp.AuthNoPriv
}


if usm.PrivacyProtocol > gosnmp.NoPriv {
userAuthMode = gosnmp.AuthPriv
}

requestAuthMode := request.MsgFlags&gosnmp.AuthPriv /*3*/

if requestAuthMode != gosnmp.SnmpV3MsgFlags(userAuthMode) {
return nil,
errors.WithMessagef(ErrNoPermission,
"user %v required %v, got %v", username, userAuthMode.String(), request.MsgFlags.String())
}
}

if decodeError != nil {
t.Logger.Debugf("v3 decode [will fail with non password] meet %v", err)
vhandle.SecurityParameters = &gosnmp.UsmSecurityParameters{
Expand Down Expand Up @@ -288,8 +319,11 @@ func (t *MasterAgent) findForSubAgent(community string) *SubAgent {
if val, ok := t.priv.communityToSubAgent[community]; ok {
return val
} else {
return t.priv.defaultSubAgent
}
if t.SecurityConfig.NoSecurity {
return t.priv.defaultSubAgent
}
return nil
}
}

func DefaultAuthoritativeEngineID() SNMPEngineID {
Expand Down
1 change: 1 addition & 0 deletions agentcontrol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func (suite *ResponseForBufferTestSuite) SetupTest() {
Logger: suite.Logger,
SecurityConfig: SecurityConfig{
AuthoritativeEngineBoots: 123,
NoSecurity: true,
Users: []gosnmp.UsmSecurityParameters{
{
UserName: "pippo",
Expand Down
5 changes: 5 additions & 0 deletions cmd/gosnmpserver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func makeApp() *cli.App {
&cli.StringFlag{Name: "v3Username", Value: "testuser"},
&cli.StringFlag{Name: "v3AuthenticationPassphrase", Value: "testauth"},
&cli.StringFlag{Name: "v3PrivacyPassphrase", Value: "testpriv"},
&cli.BoolFlag{Name: "v3Only", Value: false},
},
Action: runServer,
},
Expand Down Expand Up @@ -58,6 +59,7 @@ func runServer(c *cli.Context) error {
Logger: logger,
SecurityConfig: GoSNMPServer.SecurityConfig{
AuthoritativeEngineBoots: 1,
SnmpV3Only: c.Bool("v3Only"),
Users: []gosnmp.UsmSecurityParameters{
{
UserName: c.String("v3Username"),
Expand All @@ -75,6 +77,9 @@ func runServer(c *cli.Context) error {
},
},
}



logger.Infof("V3 Users:")
for _, val := range master.SecurityConfig.Users {
logger.Infof(
Expand Down

0 comments on commit 3fc3b33

Please sign in to comment.