summaryrefslogtreecommitdiff
path: root/pysnmp/proto
diff options
context:
space:
mode:
authorelie <elie>2013-05-05 11:11:51 +0000
committerelie <elie>2013-05-05 11:11:51 +0000
commita6bb3d327278d4a981b685aa01e02e053eb56115 (patch)
treeb58a163a6ceb237640da98f219128e81484442ca /pysnmp/proto
parentb1031a19082078b845f21fa382cc52ee67806c12 (diff)
downloadpysnmp-a6bb3d327278d4a981b685aa01e02e053eb56115.tar.gz
Fix and significant logic rework of snmpCommunityTable to make it working
in both Generator and Responder modes and better follow RFC2576 requirements on sequential entries lookup and selection. As a side effect, untagged snmpCommunityTable entries will *not* match tagged snmpTargetAddrTable entries and vice versa.
Diffstat (limited to 'pysnmp/proto')
-rw-r--r--pysnmp/proto/secmod/rfc2576.py45
1 files changed, 23 insertions, 22 deletions
diff --git a/pysnmp/proto/secmod/rfc2576.py b/pysnmp/proto/secmod/rfc2576.py
index 1c05511..c03b00a 100644
--- a/pysnmp/proto/secmod/rfc2576.py
+++ b/pysnmp/proto/secmod/rfc2576.py
@@ -83,10 +83,6 @@ class SnmpV1SecurityModel(base.AbstractSecurityModel):
snmpCommunitySecurityName.name + instId
).syntax
- if _securityName not in self.__nameToModelMap or \
- self.securityModelID not in self.__nameToModelMap[_securityName]:
- continue
-
_contextEngineId = snmpCommunityContextEngineId.getNode(
snmpCommunityContextEngineId.name + instId
).syntax
@@ -239,12 +235,6 @@ class SnmpV1SecurityModel(base.AbstractSecurityModel):
snmpCommunitySecurityName.name + instId
).syntax
- # Filter community table by security model
- # *if* there are conflicting security names
- if securityName in self.__nameToModelMap and \
- self.securityModelID not in self.__nameToModelMap[securityName]:
- continue
-
contextEngineId = snmpCommunityContextEngineId.getNode(
snmpCommunityContextEngineId.name + instId
).syntax
@@ -257,7 +247,14 @@ class SnmpV1SecurityModel(base.AbstractSecurityModel):
snmpCommunityTransportTag.name + instId
).syntax
- self.__tagAndCommunityToSecurityMap[(transportTag, nextMibNode.syntax)] = (securityName, contextEngineId, contextName)
+ _tagAndCommunity = transportTag, nextMibNode.syntax
+
+ if _tagAndCommunity not in self.__tagAndCommunityToSecurityMap:
+ self.__tagAndCommunityToSecurityMap[_tagAndCommunity] = set()
+
+ self.__tagAndCommunityToSecurityMap[_tagAndCommunity].add(
+ (securityName, contextEngineId, contextName)
+ )
if nextMibNode.syntax not in self.__communityToTagMap:
self.__communityToTagMap[nextMibNode.syntax] = set()
@@ -272,24 +269,28 @@ class SnmpV1SecurityModel(base.AbstractSecurityModel):
if communityName in self.__communityToTagMap:
if transportInformation in self.__transportToTagMap:
tags = self.__transportToTagMap[transportInformation].intersection(self.__communityToTagMap[communityName])
- candidateSecurityNames = [
- self.__tagAndCommunityToSecurityMap[(t, communityName)] for t in tags
- ]
+ elif self.__emptyTag in self.__communityToTagMap[communityName]:
+ tags = [ self.__emptyTag ]
else:
- candidateSecurityNames = []
-
- if self.__emptyTag in self.__communityToTagMap[communityName]:
- candidateSecurityNames.append(
- self.__tagAndCommunityToSecurityMap[(self.__emptyTag, communityName)]
+ raise error.StatusInformation(
+ errorIndication = errind.unknownCommunityName
)
-
+
+ candidateSecurityNames = []
+
+ for x in [ self.__tagAndCommunityToSecurityMap[(t, communityName)] for t in tags ]:
+ candidateSecurityNames.extend(list(x))
+
# 5.2.1 (row selection in snmpCommunityTable)
+ # Picks first match but favors entries already in targets table
if candidateSecurityNames:
- chosenSecurityName = min(candidateSecurityNames, key=lambda x:str(x[0]))
+ chosenSecurityName = min(candidateSecurityNames, key=lambda x,m=self.__nameToModelMap,v=self.securityModelID: (not int(x[0] in m and v in m[x[0]]), str(x[0])))
debug.logger & debug.flagSM and debug.logger('_com2sec: securityName candidates for communityName \'%s\' are %s; choosing securityName \'%s\'' % (communityName, candidateSecurityNames, chosenSecurityName[0]))
return chosenSecurityName
- raise error.StatusInformation()
+ raise error.StatusInformation(
+ errorIndication = errind.unknownCommunityName
+ )
def generateRequestMsg(
self,