1#
2# This file is part of pysnmp software.
3#
4# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
5# License: http://snmplabs.com/pysnmp/license.html
6#
7from pyasn1.compat.octets import null
8from pysnmp.carrier.asyncore.dgram import udp, udp6, unix
9from pysnmp.proto.secmod.rfc3414.auth import hmacmd5, hmacsha, noauth
10from pysnmp.proto.secmod.rfc3414.priv import des, nopriv
11from pysnmp.proto.secmod.rfc3826.priv import aes
12from pysnmp.proto.secmod.rfc7860.auth import hmacsha2
13from pysnmp.proto.secmod.eso.priv import des3, aes192, aes256
14from pysnmp.proto import rfc1905
15from pysnmp import error
16
17# A shortcut to popular constants
18
19# Transports
20snmpUDPDomain = udp.snmpUDPDomain
21snmpUDP6Domain = udp6.snmpUDP6Domain
22snmpLocalDomain = unix.snmpLocalDomain
23
24# Auth protocol
25usmHMACMD5AuthProtocol = hmacmd5.HmacMd5.serviceID
26usmHMACSHAAuthProtocol = hmacsha.HmacSha.serviceID
27usmHMAC128SHA224AuthProtocol = hmacsha2.HmacSha2.sha224ServiceID
28usmHMAC192SHA256AuthProtocol = hmacsha2.HmacSha2.sha256ServiceID
29usmHMAC256SHA384AuthProtocol = hmacsha2.HmacSha2.sha384ServiceID
30usmHMAC384SHA512AuthProtocol = hmacsha2.HmacSha2.sha512ServiceID
31
32usmNoAuthProtocol = noauth.NoAuth.serviceID
33"""No authentication service"""
34
35# Privacy protocol
36usmDESPrivProtocol = des.Des.serviceID
37usm3DESEDEPrivProtocol = des3.Des3.serviceID
38usmAesCfb128Protocol = aes.Aes.serviceID
39usmAesBlumenthalCfb192Protocol = aes192.AesBlumenthal192.serviceID  # semi-standard but not widely used
40usmAesBlumenthalCfb256Protocol = aes256.AesBlumenthal256.serviceID  # semi-standard but not widely used
41usmAesCfb192Protocol = aes192.Aes192.serviceID  # non-standard but used by many vendors
42usmAesCfb256Protocol = aes256.Aes256.serviceID  # non-standard but used by many vendors
43usmNoPrivProtocol = nopriv.NoPriv.serviceID
44
45# Auth services
46authServices = {hmacmd5.HmacMd5.serviceID: hmacmd5.HmacMd5(),
47                hmacsha.HmacSha.serviceID: hmacsha.HmacSha(),
48                hmacsha2.HmacSha2.sha224ServiceID: hmacsha2.HmacSha2(hmacsha2.HmacSha2.sha224ServiceID),
49                hmacsha2.HmacSha2.sha256ServiceID: hmacsha2.HmacSha2(hmacsha2.HmacSha2.sha256ServiceID),
50                hmacsha2.HmacSha2.sha384ServiceID: hmacsha2.HmacSha2(hmacsha2.HmacSha2.sha384ServiceID),
51                hmacsha2.HmacSha2.sha512ServiceID: hmacsha2.HmacSha2(hmacsha2.HmacSha2.sha512ServiceID),
52                noauth.NoAuth.serviceID: noauth.NoAuth()}
53
54# Privacy services
55privServices = {des.Des.serviceID: des.Des(),
56                des3.Des3.serviceID: des3.Des3(),
57                aes.Aes.serviceID: aes.Aes(),
58                aes192.AesBlumenthal192.serviceID: aes192.AesBlumenthal192(),
59                aes256.AesBlumenthal256.serviceID: aes256.AesBlumenthal256(),
60                aes192.Aes192.serviceID: aes192.Aes192(),  # non-standard
61                aes256.Aes256.serviceID: aes256.Aes256(),  # non-standard
62                nopriv.NoPriv.serviceID: nopriv.NoPriv()}
63
64
65def __cookV1SystemInfo(snmpEngine, communityIndex):
66    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
67
68    snmpEngineID, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
69    snmpCommunityEntry, = mibBuilder.importSymbols('SNMP-COMMUNITY-MIB', 'snmpCommunityEntry')
70    tblIdx = snmpCommunityEntry.getInstIdFromIndices(communityIndex)
71    return snmpCommunityEntry, tblIdx, snmpEngineID
72
73
74def addV1System(snmpEngine, communityIndex, communityName,
75                contextEngineId=None, contextName=None,
76                transportTag=None, securityName=None):
77    (snmpCommunityEntry, tblIdx,
78     snmpEngineID) = __cookV1SystemInfo(snmpEngine, communityIndex)
79
80    if contextEngineId is None:
81        contextEngineId = snmpEngineID.syntax
82    else:
83        contextEngineId = snmpEngineID.syntax.clone(contextEngineId)
84
85    if contextName is None:
86        contextName = null
87
88    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
89        ((snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'),)
90    )
91    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
92        ((snmpCommunityEntry.name + (1,) + tblIdx, communityIndex),
93         (snmpCommunityEntry.name + (2,) + tblIdx, communityName),
94         (snmpCommunityEntry.name + (3,) + tblIdx, securityName is not None and securityName or communityIndex),
95         (snmpCommunityEntry.name + (4,) + tblIdx, contextEngineId),
96         (snmpCommunityEntry.name + (5,) + tblIdx, contextName),
97         (snmpCommunityEntry.name + (6,) + tblIdx, transportTag),
98         (snmpCommunityEntry.name + (7,) + tblIdx, 'nonVolatile'),
99         (snmpCommunityEntry.name + (8,) + tblIdx, 'createAndGo'))
100    )
101
102
103def delV1System(snmpEngine, communityIndex):
104    (snmpCommunityEntry, tblIdx,
105     snmpEngineID) = __cookV1SystemInfo(snmpEngine, communityIndex)
106    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
107        ((snmpCommunityEntry.name + (8,) + tblIdx, 'destroy'),)
108    )
109
110
111def __cookV3UserInfo(snmpEngine, securityName, securityEngineId):
112    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
113
114    snmpEngineID, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID')
115
116    if securityEngineId is None:
117        snmpEngineID = snmpEngineID.syntax
118    else:
119        snmpEngineID = snmpEngineID.syntax.clone(securityEngineId)
120
121    usmUserEntry, = mibBuilder.importSymbols('SNMP-USER-BASED-SM-MIB', 'usmUserEntry')
122    tblIdx1 = usmUserEntry.getInstIdFromIndices(snmpEngineID, securityName)
123
124    pysnmpUsmSecretEntry, = mibBuilder.importSymbols('PYSNMP-USM-MIB', 'pysnmpUsmSecretEntry')
125    tblIdx2 = pysnmpUsmSecretEntry.getInstIdFromIndices(securityName)
126
127    return snmpEngineID, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry, tblIdx2
128
129
130def addV3User(snmpEngine, userName,
131              authProtocol=usmNoAuthProtocol, authKey=None,
132              privProtocol=usmNoPrivProtocol, privKey=None,
133              securityEngineId=None,
134              securityName=None,
135              # deprecated parameters follow
136              contextEngineId=None):
137    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
138
139    if securityName is None:
140        securityName = userName
141    if securityEngineId is None:  # backward compatibility
142        securityEngineId = contextEngineId
143    (snmpEngineID, usmUserEntry, tblIdx1,
144     pysnmpUsmSecretEntry, tblIdx2) = __cookV3UserInfo(snmpEngine, userName, securityEngineId)
145
146    # Load augmenting table before creating new row in base one
147    pysnmpUsmKeyEntry, = mibBuilder.importSymbols('PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry')
148
149    # Load clone-from (may not be needed)
150    zeroDotZero, = mibBuilder.importSymbols('SNMPv2-SMI', 'zeroDotZero')
151
152    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
153        ((usmUserEntry.name + (13,) + tblIdx1, 'destroy'),)
154    )
155    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
156        ((usmUserEntry.name + (2,) + tblIdx1, userName),
157         (usmUserEntry.name + (3,) + tblIdx1, securityName),
158         (usmUserEntry.name + (4,) + tblIdx1, zeroDotZero.name),
159         (usmUserEntry.name + (5,) + tblIdx1, authProtocol),
160         (usmUserEntry.name + (8,) + tblIdx1, privProtocol),
161         (usmUserEntry.name + (13,) + tblIdx1, 'createAndGo'))
162    )
163
164    # Localize keys
165    if authProtocol in authServices:
166        hashedAuthPassphrase = authServices[authProtocol].hashPassphrase(
167            authKey and authKey or null
168        )
169        localAuthKey = authServices[authProtocol].localizeKey(
170            hashedAuthPassphrase, snmpEngineID
171        )
172    else:
173        raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol,))
174
175    if privProtocol in privServices:
176        hashedPrivPassphrase = privServices[privProtocol].hashPassphrase(
177            authProtocol, privKey and privKey or null
178        )
179        localPrivKey = privServices[privProtocol].localizeKey(
180            authProtocol, hashedPrivPassphrase, snmpEngineID
181        )
182    else:
183        raise error.PySnmpError('Unknown priv protocol %s' % (privProtocol,))
184
185    # Commit localized keys
186    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
187        ((pysnmpUsmKeyEntry.name + (1,) + tblIdx1, localAuthKey),
188         (pysnmpUsmKeyEntry.name + (2,) + tblIdx1, localPrivKey),
189         (pysnmpUsmKeyEntry.name + (3,) + tblIdx1, hashedAuthPassphrase),
190         (pysnmpUsmKeyEntry.name + (4,) + tblIdx1, hashedPrivPassphrase))
191    )
192
193    # Commit passphrases
194
195    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
196        ((pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),)
197    )
198    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
199        ((pysnmpUsmSecretEntry.name + (1,) + tblIdx2, userName),
200         (pysnmpUsmSecretEntry.name + (2,) + tblIdx2, authKey),
201         (pysnmpUsmSecretEntry.name + (3,) + tblIdx2, privKey),
202         (pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'createAndGo'))
203    )
204
205
206def delV3User(snmpEngine,
207              userName,
208              securityEngineId=None,
209              # deprecated parameters follow
210              contextEngineId=None):
211    if securityEngineId is None:  # backward compatibility
212        securityEngineId = contextEngineId
213    (snmpEngineID, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry,
214     tblIdx2) = __cookV3UserInfo(snmpEngine, userName, securityEngineId)
215    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
216        ((usmUserEntry.name + (13,) + tblIdx1, 'destroy'),)
217    )
218    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
219        ((pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),)
220    )
221
222    # Drop all derived rows
223    varBinds = initialVarBinds = (
224        (usmUserEntry.name + (1,), None),  # usmUserEngineID
225        (usmUserEntry.name + (2,), None),  # usmUserName
226        (usmUserEntry.name + (4,), None)  # usmUserCloneFrom
227    )
228    while varBinds:
229        varBinds = snmpEngine.msgAndPduDsp.mibInstrumController.readNextVars(
230            varBinds
231        )
232        if varBinds[0][1].isSameTypeWith(rfc1905.endOfMibView):
233            break
234        if varBinds[0][0][:len(initialVarBinds[0][0])] != initialVarBinds[0][0]:
235            break
236        elif varBinds[2][1] == tblIdx1:  # cloned from this entry
237            delV3User(snmpEngine, varBinds[1][1], varBinds[0][1])
238            varBinds = initialVarBinds
239
240
241def __cookTargetParamsInfo(snmpEngine, name):
242    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
243
244    snmpTargetParamsEntry, = mibBuilder.importSymbols('SNMP-TARGET-MIB', 'snmpTargetParamsEntry')
245    tblIdx = snmpTargetParamsEntry.getInstIdFromIndices(name)
246    return snmpTargetParamsEntry, tblIdx
247
248
249# mpModel: 0 == SNMPv1, 1 == SNMPv2c, 3 == SNMPv3
250def addTargetParams(snmpEngine, name, securityName, securityLevel, mpModel=3):
251    if mpModel == 0:
252        securityModel = 1
253    elif mpModel in (1, 2):
254        securityModel = 2
255    elif mpModel == 3:
256        securityModel = 3
257    else:
258        raise error.PySnmpError('Unknown MP model %s' % mpModel)
259
260    snmpTargetParamsEntry, tblIdx = __cookTargetParamsInfo(snmpEngine, name)
261
262    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
263        ((snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'),)
264    )
265    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
266        ((snmpTargetParamsEntry.name + (1,) + tblIdx, name),
267         (snmpTargetParamsEntry.name + (2,) + tblIdx, mpModel),
268         (snmpTargetParamsEntry.name + (3,) + tblIdx, securityModel),
269         (snmpTargetParamsEntry.name + (4,) + tblIdx, securityName),
270         (snmpTargetParamsEntry.name + (5,) + tblIdx, securityLevel),
271         (snmpTargetParamsEntry.name + (7,) + tblIdx, 'createAndGo'))
272    )
273
274
275def delTargetParams(snmpEngine, name):
276    snmpTargetParamsEntry, tblIdx = __cookTargetParamsInfo(snmpEngine, name)
277    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
278        ((snmpTargetParamsEntry.name + (7,) + tblIdx, 'destroy'),)
279    )
280
281
282def __cookTargetAddrInfo(snmpEngine, addrName):
283    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
284
285    snmpTargetAddrEntry, = mibBuilder.importSymbols('SNMP-TARGET-MIB', 'snmpTargetAddrEntry')
286    snmpSourceAddrEntry, = mibBuilder.importSymbols('PYSNMP-SOURCE-MIB', 'snmpSourceAddrEntry')
287    tblIdx = snmpTargetAddrEntry.getInstIdFromIndices(addrName)
288    return snmpTargetAddrEntry, snmpSourceAddrEntry, tblIdx
289
290
291def addTargetAddr(snmpEngine, addrName, transportDomain, transportAddress,
292                  params, timeout=None, retryCount=None, tagList=null,
293                  sourceAddress=None):
294    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
295
296    (snmpTargetAddrEntry, snmpSourceAddrEntry,
297     tblIdx) = __cookTargetAddrInfo(snmpEngine, addrName)
298
299    if transportDomain[:len(snmpUDPDomain)] == snmpUDPDomain:
300        SnmpUDPAddress, = mibBuilder.importSymbols('SNMPv2-TM', 'SnmpUDPAddress')
301        transportAddress = SnmpUDPAddress(transportAddress)
302        if sourceAddress is None:
303            sourceAddress = ('0.0.0.0', 0)
304        sourceAddress = SnmpUDPAddress(sourceAddress)
305    elif transportDomain[:len(snmpUDP6Domain)] == snmpUDP6Domain:
306        TransportAddressIPv6, = mibBuilder.importSymbols('TRANSPORT-ADDRESS-MIB', 'TransportAddressIPv6')
307        transportAddress = TransportAddressIPv6(transportAddress)
308        if sourceAddress is None:
309            sourceAddress = ('::', 0)
310        sourceAddress = TransportAddressIPv6(sourceAddress)
311
312    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
313        ((snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'),)
314    )
315    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
316        ((snmpTargetAddrEntry.name + (1,) + tblIdx, addrName),
317         (snmpTargetAddrEntry.name + (2,) + tblIdx, transportDomain),
318         (snmpTargetAddrEntry.name + (3,) + tblIdx, transportAddress),
319         (snmpTargetAddrEntry.name + (4,) + tblIdx, timeout),
320         (snmpTargetAddrEntry.name + (5,) + tblIdx, retryCount),
321         (snmpTargetAddrEntry.name + (6,) + tblIdx, tagList),
322         (snmpTargetAddrEntry.name + (7,) + tblIdx, params),
323         (snmpSourceAddrEntry.name + (1,) + tblIdx, sourceAddress),
324         (snmpTargetAddrEntry.name + (9,) + tblIdx, 'createAndGo'))
325    )
326
327
328def delTargetAddr(snmpEngine, addrName):
329    (snmpTargetAddrEntry, snmpSourceAddrEntry,
330     tblIdx) = __cookTargetAddrInfo(snmpEngine, addrName)
331    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
332        ((snmpTargetAddrEntry.name + (9,) + tblIdx, 'destroy'),)
333    )
334
335
336def addTransport(snmpEngine, transportDomain, transport):
337    if snmpEngine.transportDispatcher:
338        if not transport.isCompatibleWithDispatcher(snmpEngine.transportDispatcher):
339            raise error.PySnmpError(
340                'Transport %r is not compatible with dispatcher %r' % (transport, snmpEngine.transportDispatcher))
341    else:
342        snmpEngine.registerTransportDispatcher(
343            transport.protoTransportDispatcher()
344        )
345        # here we note that we have created transportDispatcher automatically
346        snmpEngine.setUserContext(automaticTransportDispatcher=0)
347
348    snmpEngine.transportDispatcher.registerTransport(transportDomain, transport)
349    automaticTransportDispatcher = snmpEngine.getUserContext(
350        'automaticTransportDispatcher'
351    )
352    if automaticTransportDispatcher is not None:
353        snmpEngine.setUserContext(
354            automaticTransportDispatcher=automaticTransportDispatcher + 1
355        )
356
357
358def getTransport(snmpEngine, transportDomain):
359    if not snmpEngine.transportDispatcher:
360        return
361    try:
362        return snmpEngine.transportDispatcher.getTransport(transportDomain)
363    except error.PySnmpError:
364        return
365
366
367def delTransport(snmpEngine, transportDomain):
368    if not snmpEngine.transportDispatcher:
369        return
370    transport = getTransport(snmpEngine, transportDomain)
371    snmpEngine.transportDispatcher.unregisterTransport(transportDomain)
372    # automatically shutdown automatically created transportDispatcher
373    automaticTransportDispatcher = snmpEngine.getUserContext(
374        'automaticTransportDispatcher'
375    )
376    if automaticTransportDispatcher is not None:
377        automaticTransportDispatcher -= 1
378        snmpEngine.setUserContext(
379            automaticTransportDispatcher=automaticTransportDispatcher
380        )
381        if not automaticTransportDispatcher:
382            snmpEngine.transportDispatcher.closeDispatcher()
383            snmpEngine.unregisterTransportDispatcher()
384            snmpEngine.delUserContext(automaticTransportDispatcher)
385    return transport
386
387
388addSocketTransport = addTransport
389delSocketTransport = delTransport
390
391
392# VACM shortcuts
393
394def __cookVacmContextInfo(snmpEngine, contextName):
395    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
396    vacmContextEntry, = mibBuilder.importSymbols('SNMP-VIEW-BASED-ACM-MIB', 'vacmContextEntry')
397    tblIdx = vacmContextEntry.getInstIdFromIndices(contextName)
398    return vacmContextEntry, tblIdx
399
400
401def addContext(snmpEngine, contextName):
402    vacmContextEntry, tblIdx = __cookVacmContextInfo(snmpEngine, contextName)
403
404    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
405        ((vacmContextEntry.name + (2,) + tblIdx, 'destroy'),)
406    )
407    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
408        ((vacmContextEntry.name + (1,) + tblIdx, contextName),
409         (vacmContextEntry.name + (2,) + tblIdx, 'createAndGo'))
410    )
411
412
413def delContext(snmpEngine, contextName):
414    vacmContextEntry, tblIdx = __cookVacmContextInfo(snmpEngine, contextName)
415
416    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
417        ((vacmContextEntry.name + (2,) + tblIdx, 'destroy'),)
418    )
419
420
421def __cookVacmGroupInfo(snmpEngine, securityModel, securityName):
422    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
423
424    vacmSecurityToGroupEntry, = mibBuilder.importSymbols('SNMP-VIEW-BASED-ACM-MIB',
425                                                         'vacmSecurityToGroupEntry')
426    tblIdx = vacmSecurityToGroupEntry.getInstIdFromIndices(securityModel,
427                                                           securityName)
428    return vacmSecurityToGroupEntry, tblIdx
429
430
431def addVacmGroup(snmpEngine, groupName, securityModel, securityName):
432    (vacmSecurityToGroupEntry,
433     tblIdx) = __cookVacmGroupInfo(snmpEngine, securityModel, securityName)
434    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
435        ((vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'),)
436    )
437    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
438        ((vacmSecurityToGroupEntry.name + (1,) + tblIdx, securityModel),
439         (vacmSecurityToGroupEntry.name + (2,) + tblIdx, securityName),
440         (vacmSecurityToGroupEntry.name + (3,) + tblIdx, groupName),
441         (vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'createAndGo'))
442    )
443
444
445def delVacmGroup(snmpEngine, securityModel, securityName):
446    vacmSecurityToGroupEntry, tblIdx = __cookVacmGroupInfo(
447        snmpEngine, securityModel, securityName
448    )
449    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
450        ((vacmSecurityToGroupEntry.name + (5,) + tblIdx, 'destroy'),)
451    )
452
453
454def __cookVacmAccessInfo(snmpEngine, groupName, contextName, securityModel,
455                         securityLevel):
456    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
457
458    vacmAccessEntry, = mibBuilder.importSymbols('SNMP-VIEW-BASED-ACM-MIB', 'vacmAccessEntry')
459    tblIdx = vacmAccessEntry.getInstIdFromIndices(groupName, contextName,
460                                                  securityModel, securityLevel)
461    return vacmAccessEntry, tblIdx
462
463
464def addVacmAccess(snmpEngine, groupName, contextName, securityModel,
465                  securityLevel, prefix, readView, writeView, notifyView):
466    vacmAccessEntry, tblIdx = __cookVacmAccessInfo(snmpEngine, groupName,
467                                                   contextName, securityModel,
468                                                   securityLevel)
469
470    addContext(snmpEngine, contextName)
471
472    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
473        ((vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),)
474    )
475    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
476        ((vacmAccessEntry.name + (1,) + tblIdx, contextName),
477         (vacmAccessEntry.name + (2,) + tblIdx, securityModel),
478         (vacmAccessEntry.name + (3,) + tblIdx, securityLevel),
479         (vacmAccessEntry.name + (4,) + tblIdx, prefix),
480         (vacmAccessEntry.name + (5,) + tblIdx, readView),
481         (vacmAccessEntry.name + (6,) + tblIdx, writeView),
482         (vacmAccessEntry.name + (7,) + tblIdx, notifyView),
483         (vacmAccessEntry.name + (9,) + tblIdx, 'createAndGo'))
484    )
485
486
487def delVacmAccess(snmpEngine, groupName, contextName, securityModel,
488                  securityLevel):
489    vacmAccessEntry, tblIdx = __cookVacmAccessInfo(snmpEngine, groupName,
490                                                   contextName, securityModel,
491                                                   securityLevel)
492
493    delContext(snmpEngine, contextName)
494
495    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
496        ((vacmAccessEntry.name + (9,) + tblIdx, 'destroy'),)
497    )
498
499
500def __cookVacmViewInfo(snmpEngine, viewName, subTree):
501    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
502
503    vacmViewTreeFamilyEntry, = mibBuilder.importSymbols(
504        'SNMP-VIEW-BASED-ACM-MIB', 'vacmViewTreeFamilyEntry'
505    )
506    tblIdx = vacmViewTreeFamilyEntry.getInstIdFromIndices(viewName, subTree)
507    return vacmViewTreeFamilyEntry, tblIdx
508
509
510def addVacmView(snmpEngine, viewName, viewType, subTree, mask):
511    vacmViewTreeFamilyEntry, tblIdx = __cookVacmViewInfo(snmpEngine, viewName,
512                                                         subTree)
513    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
514        ((vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'),)
515    )
516    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
517        ((vacmViewTreeFamilyEntry.name + (1,) + tblIdx, viewName),
518         (vacmViewTreeFamilyEntry.name + (2,) + tblIdx, subTree),
519         (vacmViewTreeFamilyEntry.name + (3,) + tblIdx, mask),
520         (vacmViewTreeFamilyEntry.name + (4,) + tblIdx, viewType),
521         (vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'createAndGo'))
522    )
523
524
525def delVacmView(snmpEngine, viewName, subTree):
526    vacmViewTreeFamilyEntry, tblIdx = __cookVacmViewInfo(snmpEngine, viewName,
527                                                         subTree)
528    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
529        ((vacmViewTreeFamilyEntry.name + (6,) + tblIdx, 'destroy'),)
530    )
531
532
533# VACM simplicity wrappers
534
535def __cookVacmUserInfo(snmpEngine, securityModel, securityName, securityLevel):
536    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
537
538    groupName = 'v-%s-%d' % (hash(securityName), securityModel)
539    SnmpSecurityLevel, = mibBuilder.importSymbols('SNMP-FRAMEWORK-MIB', 'SnmpSecurityLevel')
540    securityLevel = SnmpSecurityLevel(securityLevel)
541    return (groupName, securityLevel,
542            'r' + groupName, 'w' + groupName, 'n' + groupName)
543
544
545def addVacmUser(snmpEngine, securityModel, securityName, securityLevel,
546                readSubTree=(), writeSubTree=(), notifySubTree=(),
547                contextName=null):
548    (groupName, securityLevel, readView, writeView,
549     notifyView) = __cookVacmUserInfo(snmpEngine, securityModel, securityName,
550                                      securityLevel)
551    addVacmGroup(snmpEngine, groupName, securityModel, securityName)
552    addVacmAccess(snmpEngine, groupName, contextName, securityModel,
553                  securityLevel, 1, readView, writeView, notifyView)
554    if readSubTree:
555        addVacmView(snmpEngine, readView, "included", readSubTree, null)
556    if writeSubTree:
557        addVacmView(snmpEngine, writeView, "included", writeSubTree, null)
558    if notifySubTree:
559        addVacmView(snmpEngine, notifyView, "included", notifySubTree, null)
560
561
562def delVacmUser(snmpEngine, securityModel, securityName, securityLevel,
563                readSubTree=(), writeSubTree=(), notifySubTree=(),
564                contextName=null):
565    (groupName, securityLevel, readView, writeView,
566     notifyView) = __cookVacmUserInfo(snmpEngine, securityModel,
567                                      securityName, securityLevel)
568    delVacmGroup(snmpEngine, securityModel, securityName)
569    delVacmAccess(snmpEngine, groupName, contextName, securityModel, securityLevel)
570    if readSubTree:
571        delVacmView(
572            snmpEngine, readView, readSubTree
573        )
574    if writeSubTree:
575        delVacmView(
576            snmpEngine, writeView, writeSubTree
577        )
578    if notifySubTree:
579        delVacmView(
580            snmpEngine, notifyView, notifySubTree
581        )
582
583
584# Obsolete shortcuts for add/delVacmUser() wrappers
585
586def addRoUser(snmpEngine, securityModel, securityName, securityLevel,
587              subTree, contextName=null):
588    addVacmUser(snmpEngine, securityModel, securityName, securityLevel,
589                subTree, contextName=contextName)
590
591
592def delRoUser(snmpEngine, securityModel, securityName, securityLevel,
593              subTree, contextName=null):
594    delVacmUser(snmpEngine, securityModel, securityName, securityLevel,
595                subTree, contextName=contextName)
596
597
598def addRwUser(snmpEngine, securityModel, securityName, securityLevel,
599              subTree, contextName=null):
600    addVacmUser(snmpEngine, securityModel, securityName, securityLevel,
601                subTree, subTree, contextName=contextName)
602
603
604def delRwUser(snmpEngine, securityModel, securityName, securityLevel,
605              subTree, contextName=null):
606    delVacmUser(snmpEngine, securityModel, securityName, securityLevel,
607                subTree, subTree, contextName=contextName)
608
609
610def addTrapUser(snmpEngine, securityModel, securityName,
611                securityLevel, subTree, contextName=null):
612    addVacmUser(snmpEngine, securityModel, securityName, securityLevel,
613                (), (), subTree, contextName=contextName)
614
615
616def delTrapUser(snmpEngine, securityModel, securityName,
617                securityLevel, subTree, contextName=null):
618    delVacmUser(snmpEngine, securityModel, securityName, securityLevel,
619                (), (), subTree, contextName=contextName)
620
621
622# Notification target setup
623
624def __cookNotificationTargetInfo(snmpEngine, notificationName, paramsName,
625                                 filterSubtree=None):
626    mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
627
628    snmpNotifyEntry, = mibBuilder.importSymbols('SNMP-NOTIFICATION-MIB', 'snmpNotifyEntry')
629    tblIdx1 = snmpNotifyEntry.getInstIdFromIndices(notificationName)
630
631    snmpNotifyFilterProfileEntry, = mibBuilder.importSymbols('SNMP-NOTIFICATION-MIB',
632                                                             'snmpNotifyFilterProfileEntry')
633    tblIdx2 = snmpNotifyFilterProfileEntry.getInstIdFromIndices(paramsName)
634
635    profileName = '%s-filter' % hash(notificationName)
636
637    if filterSubtree:
638        snmpNotifyFilterEntry, = mibBuilder.importSymbols('SNMP-NOTIFICATION-MIB',
639                                                          'snmpNotifyFilterEntry')
640        tblIdx3 = snmpNotifyFilterEntry.getInstIdFromIndices(profileName,
641                                                             filterSubtree)
642    else:
643        snmpNotifyFilterEntry = tblIdx3 = None
644
645    return (snmpNotifyEntry, tblIdx1,
646            snmpNotifyFilterProfileEntry, tblIdx2, profileName,
647            snmpNotifyFilterEntry, tblIdx3)
648
649
650def addNotificationTarget(snmpEngine, notificationName, paramsName,
651                          transportTag, notifyType=None, filterSubtree=None,
652                          filterMask=None, filterType=None):
653    (snmpNotifyEntry, tblIdx1, snmpNotifyFilterProfileEntry, tblIdx2,
654     profileName, snmpNotifyFilterEntry,
655     tblIdx3) = __cookNotificationTargetInfo(snmpEngine, notificationName,
656                                             paramsName, filterSubtree)
657
658    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
659        ((snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'),)
660    )
661    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
662        ((snmpNotifyEntry.name + (2,) + tblIdx1, transportTag),
663         (snmpNotifyEntry.name + (3,) + tblIdx1, notifyType),
664         (snmpNotifyEntry.name + (5,) + tblIdx1, 'createAndGo'))
665    )
666
667    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
668        ((snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'),)
669    )
670    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
671        ((snmpNotifyFilterProfileEntry.name + (1,) + tblIdx2, profileName),
672         (snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'createAndGo'))
673    )
674
675    if not snmpNotifyFilterEntry:
676        return
677
678    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
679        ((snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'),)
680    )
681    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
682        ((snmpNotifyFilterEntry.name + (1,) + tblIdx3, filterSubtree),
683         (snmpNotifyFilterEntry.name + (2,) + tblIdx3, filterMask),
684         (snmpNotifyFilterEntry.name + (3,) + tblIdx3, filterType),
685         (snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'createAndGo'))
686    )
687
688
689def delNotificationTarget(snmpEngine, notificationName, paramsName,
690                          filterSubtree=None):
691    (snmpNotifyEntry, tblIdx1, snmpNotifyFilterProfileEntry,
692     tblIdx2, profileName, snmpNotifyFilterEntry,
693     tblIdx3) = __cookNotificationTargetInfo(snmpEngine, notificationName,
694                                             paramsName, filterSubtree)
695
696    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
697        ((snmpNotifyEntry.name + (5,) + tblIdx1, 'destroy'),)
698    )
699
700    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
701        ((snmpNotifyFilterProfileEntry.name + (3,) + tblIdx2, 'destroy'),)
702    )
703
704    if not snmpNotifyFilterEntry:
705        return
706
707    snmpEngine.msgAndPduDsp.mibInstrumController.writeVars(
708        ((snmpNotifyFilterEntry.name + (5,) + tblIdx3, 'destroy'),)
709    )
710
711
712# rfc3415: A.1
713def setInitialVacmParameters(snmpEngine):
714    # rfc3415: A.1.1 --> initial-semi-security-configuration
715
716    # rfc3415: A.1.2
717    addContext(snmpEngine, "")
718
719    # rfc3415: A.1.3
720    addVacmGroup(snmpEngine, "initial", 3, "initial")
721
722    # rfc3415: A.1.4
723    addVacmAccess(snmpEngine, "initial", "", 3, "noAuthNoPriv", "exact",
724                  "restricted", None, "restricted")
725    addVacmAccess(snmpEngine, "initial", "", 3, "authNoPriv", "exact",
726                  "internet", "internet", "internet")
727    addVacmAccess(snmpEngine, "initial", "", 3, "authPriv", "exact",
728                  "internet", "internet", "internet")
729
730    # rfc3415: A.1.5 (semi-secure)
731    addVacmView(snmpEngine, "internet",
732                "included", (1, 3, 6, 1), "")
733    addVacmView(snmpEngine, "restricted",
734                "included", (1, 3, 6, 1, 2, 1, 1), "")
735    addVacmView(snmpEngine, "restricted",
736                "included", (1, 3, 6, 1, 2, 1, 11), "")
737    addVacmView(snmpEngine, "restricted",
738                "included", (1, 3, 6, 1, 6, 3, 10, 2, 1), "")
739    addVacmView(snmpEngine, "restricted",
740                "included", (1, 3, 6, 1, 6, 3, 11, 2, 1), "")
741    addVacmView(snmpEngine, "restricted",
742                "included", (1, 3, 6, 1, 6, 3, 15, 1, 1), "")
743