exhuma / puresnmp

Pure Python SNMPv2 Library
MIT License
81 stars 23 forks source link

bulkwalk incorrectly handles EndOfMibView #54

Closed hartib closed 5 years ago

hartib commented 6 years ago

I'm retrieving a small table near the end of the MIB (followed by 5 scalars). The response contains the table, the 5 scalars and EndOfMibView. This leads to bulkwalk raising an exception.

Actually it should return the retrieved values and the EndOfMibView indication so that the application can read values near the end of the MIB and also figure out that it has hit the end of the MIB.

I tried to figure out where exactly the problem happens but I got lost...

This is the end of the response message:

_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00_00
.1.3.6.1.6.3.1.1.6.1.0=128024585
.1.3.6.1.6.3.10.2.1.1.0=80_00_08_be_80_33_37_34_30_37_37_33_33_35_35
.1.3.6.1.6.3.10.2.1.2.0=1
.1.3.6.1.6.3.10.2.1.3.0=1656
.1.3.6.1.6.3.10.2.1.4.0=1500
.1.3.6.1.6.3.10.2.1.4.0=[endOfMibView] } }
exhuma commented 6 years ago

Thank you for reporting this issue. I have not yet run across this is my tests but it is hard to reproduce.

If possible, can you run the problematic poll with debug-logging and post the output? This will show me the raw packets which will give me a base for testing:

import logging
logging.defaultConfig(level=logging.DEBUG)

... your code ...

Be aware however that this may include data which you may consider sensitive especially if the device is connected to a pulbic network like the Internet (ip-address, community). If that's a problem, maybe you can just set a temporary community string while you extract the logs. Once posted here, you can remove that community again.

If this is not a problem, that log output would really help in reproducing and fixing this issue!

hartib commented 6 years ago

Seems like it is actually 'logging.basicConfig()'. Here is the offending bulkwalk. The last line comes from a print I inserted to print the exception. The problematic part of the reponse is the 0x82 near the end which is the context-specific tag of the EndOfMibView. This seems to cause the code to enter the GetResponse decoder again (which has the same tag AFAIK, but in another context).

bug1.txt

exhuma commented 6 years ago

I've looked into this over the past two days and it seems to be a bit more difficult to fix than I anticipated. You are correct with the note that GetResponse has the same tag. I need to investigate how I can fix this. Unfortunately this might take me some time.

hartib commented 6 years ago

No problem. When working on this, you should probably also take care to return EndOfMibView explicitly as a value.

exhuma commented 6 years ago

Thanks for the dump. It let's me indeed reproduce the error.

Just to give a status update: I'm currently re-reading the RFCs, so this make a little while.

exhuma commented 5 years ago

Another progress update...

This issue is way harder to fix than I originally expected. I have a fundamental architecture problem in that I consider the types defined in the SNMP spec as subtypes of the X690 spec. At first glance, this seems like the right thing to do. But it should be separate class hierarchies. It's the same sneaky error that can happen when subclassing a Square from a Rectangle. At first sight this seems to be correct but it introduces problems down the road.

In the case of SNMP PDUs and X690 types, this manifests in the way the types are decoded. It causes difficulties between VarBinds, endOfMibView and GetResponse.

An initial attempt was to raise an EndOfMibView exception from within the x690.pop_tlv function. But EndOfMibView is independent from x690 so this is wrong. And indeed, this causes the problem that I can no longer distinguish between two important contexts.

The value needs to be transparently returned by the x690 layer. The "business logic" of this special value belongs into the SNMP layer.

Unfortunately, doing so - in combination with the fact that SNMP PDUs are subclasses from the x690 Type - will cause the x690 layer to try to instantiate a GetResponse instance with empty data. This will correctly raise a "noSuchOID" error but we don't want that in this case.

A solution should be to split the class trees for x690 and SNMP. This way, x690 will see the 0x82 type as "unknown" and let it bubble up to SNMP. We can then attach the appropriate logic to that value when needed.

This should also solve another problem in which x690 Sequence values which should fill in SNMP VarBind values will show up with a correct 2-tuple with the second value being the Unknown type with type tax 0x82 (instead of being a Sequence with only one item).

This does mean that this seemingly mundane problem causes a fairly large change in the code-base.

It should however be doable of fixing this without changing the external API.

exhuma commented 5 years ago

I've released it as 1.4.2rc1 on pypi

My tests were all successful. Can you give it a test if it is OK for you?

hartib commented 5 years ago

Hi,

I test it, but it will take a couple of days. I’ll report back.

harti

From: Michel Albert [mailto:notifications@github.com] Sent: Thursday, December 13, 2018 6:29 AM To: exhuma/puresnmp Cc: Brandt, Hartmut; Author Subject: Re: [exhuma/puresnmp] bulkwalk incorrectly handles EndOfMibView (#54)

I've released it as 1.4.2rc1 on pypi

My tests were all successful. Can you give it a test if it is OK for you?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/exhuma/puresnmp/issues/54#issuecomment-446847215, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AX_V9vYBn-mxl1FYbhjDGqbP06TXhPsJks5u4eWAgaJpZM4Xx9Cd.