summaryrefslogtreecommitdiff
path: root/pysnmp/proto/acmod/rfc3415.py
blob: 277553455b1761ac2aa730fe9df0794a2500581a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# View-based Access Control Model
from pysnmp.smi.error import NoSuchInstanceError
from pysnmp.proto import error

accessModelID = 3

__powOfTwoSeq = [128, 64, 32, 16, 8, 4, 2, 1]

# 3.2
def isAccessAllowed(
    snmpEngine,
    securityModel,
    securityName,
    securityLevel,
    viewType,
    contextName,
    variableName):
    mibInstrumController = snmpEngine.msgAndPduDsp.mibInstrumController 
    # 3.2.1
    vacmContextEntry, = mibInstrumController.mibBuilder.importSymbols('SNMP-VIEW-BASED-ACM-MIB', 'vacmContextEntry')
    tblIdx = vacmContextEntry.getInstIdFromIndices(contextName)
    try:
        vacmContextName = vacmContextEntry.getNode(
            vacmContextEntry.name + (1,) + tblIdx
            ).syntax
    except NoSuchInstanceError:
        raise error.StatusInformation(errorIndication='noSuchContext')    

    # 3.2.2
    vacmSecurityToGroupEntry, = mibInstrumController.mibBuilder.importSymbols(
        'SNMP-VIEW-BASED-ACM-MIB', 'vacmSecurityToGroupEntry'
        )
    tblIdx = vacmSecurityToGroupEntry.getInstIdFromIndices(
        securityModel, securityName
        )
    try:
        vacmGroupName = vacmSecurityToGroupEntry.getNode(
            vacmSecurityToGroupEntry.name + (3,) + tblIdx
            ).syntax
    except NoSuchInstanceError:
        raise error.StatusInformation(errorIndication='noGroupName')

    # 3.2.3
    vacmAccessEntry, = mibInstrumController.mibBuilder.importSymbols(
        'SNMP-VIEW-BASED-ACM-MIB', 'vacmAccessEntry'
        )
    # XXX partial context name match
    tblIdx = vacmAccessEntry.getInstIdFromIndices(
        vacmGroupName, contextName, securityModel, securityLevel
        )

    # 3.2.4
    if viewType == 'read':
        entryIdx = vacmAccessEntry.name + (5,) + tblIdx
    elif viewType == 'write':
        entryIdx = vacmAccessEntry.name + (6,) + tblIdx
    elif viewType == 'notify':
        entryIdx = vacmAccessEntry.name + (7,) + tblIdx
    else:
        raise error.ProtocolError('Unknown view type %s' % viewType)

    try:
        viewName = vacmAccessEntry.getNode(entryIdx).syntax
    except NoSuchInstanceError:
        raise error.StatusInformation(errorIndication='noAccessEntry')
    if not len(viewName):
        raise error.StatusInformation(errorIndication='noSuchView')

    # XXX split onto object & instance ?
    
    # 3.2.5a
    vacmViewTreeFamilyEntry, = mibInstrumController.mibBuilder.importSymbols('SNMP-VIEW-BASED-ACM-MIB', 'vacmViewTreeFamilyEntry')
    tblIdx = vacmViewTreeFamilyEntry.getInstIdFromIndices(viewName)

    # Walk over entries
    initialTreeName = treeName = vacmViewTreeFamilyEntry.name + (2,) + tblIdx
    maskName = vacmViewTreeFamilyEntry.name + (3,) + tblIdx
    while 1:
        vacmViewTreeFamilySubtree = vacmViewTreeFamilyEntry.getNextNode(
            treeName
            )
        vacmViewTreeFamilyMask = vacmViewTreeFamilyEntry.getNextNode(
            maskName
            )
        treeName = vacmViewTreeFamilySubtree.name
        maskName = vacmViewTreeFamilyMask.name
        if initialTreeName != treeName[:len(initialTreeName)]:
            # 3.2.5b
            raise error.StatusInformation(errorIndication='notInView')            
        l = len(vacmViewTreeFamilySubtree.syntax)
        if l > len(variableName):
            continue
        if vacmViewTreeFamilyMask.syntax:
            mask = []
            for c in map(None, str(vacmViewTreeFamilyMask.syntax)):
                mask = mask + map(lambda b,c=ord(c): b&c, __powOfTwoSeq)
            m = len(mask)-1
            idx = l-1
            while idx:
                if idx > m or mask[idx] and \
                   vacmViewTreeFamilySubtree.syntax[idx] != variableName[idx]:
                    break
                idx = idx - 1
            if idx: continue # no match
        else: # no mask
            if vacmViewTreeFamilySubtree.syntax != variableName[:l]:
                continue # no match
        # 3.2.5c
        return error.StatusInformation(errorIndication='accessAllowed')

# XXX
# develop a non-intrum-based management objects access methods