def testReservedLength(self): try: decoder.decode(ints2octs((6, 255, 0))) except PyAsn1Error: pass else: assert 0, 'reserved length tolarated'
def getpac(key, rawticket, debug=False, verbose=False): # attempt decoding of ticket try: ramticket, extra = decoder.decode(rawticket) serverticket = ramticket.getComponentByPosition(2) localticket = ramticket.getComponentByPosition(3) encserverticket = serverticket.getComponentByPosition(0).getComponentByPosition(3).getComponentByPosition(2).asOctets() except: raise ValueError('Unable to decode ticket. Invalid file.') if verbose: print 'Ticket succesfully decoded' decserverticketraw, nonce = kerberos.decrypt(key, 2, encserverticket) if decserverticketraw == None: raise ValueError('Unable to decrypt ticket. Invalid key.') elif verbose: print 'Decryption successful' decserverticket, extra = decoder.decode(decserverticketraw) # have two here because I was using one to verify that the rewrite matched # This stuff should be removed, if it is still here Tim forgot...again origdecserverticket, extra = decoder.decode(decserverticketraw) # change the validity times in the server ticket updatetimestampsserverticket(decserverticket, str(decserverticket[5]), str(decserverticket[6]), str(decserverticket[7]), str(decserverticket[8])) adifrelevant, extra = decoder.decode(decserverticket[9][0][1]) pac = str(adifrelevant.getComponentByPosition(0).getComponentByPosition(1)) return pac
def testNoLongFormEoo(self): try: decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x81, 0x00))) except PyAsn1Error: pass else: assert 0, 'end-of-contents octets accepted with invalid long-form length'
def testDefiniteNoEoo(self): try: decoder.decode(ints2octs((0x23, 0x02, 0x00, 0x00))) except PyAsn1Error: pass else: assert 0, 'end-of-contents octets accepted inside definite-length encoding'
def testNoConstructedEoo(self): try: decoder.decode(ints2octs((0x23, 0x80, 0x20, 0x00))) except PyAsn1Error: pass else: assert 0, 'end-of-contents octets accepted with invalid constructed encoding'
def testNoEooData(self): try: decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x01, 0x00))) except PyAsn1Error: pass else: assert 0, 'end-of-contents octets accepted with unexpected data'
def testTagFormat(self): try: decoder.decode(ints2octs((33, 1, 1))) except PyAsn1Error: pass else: assert 0, 'wrong tagFormat worked out'
def testUnexpectedEoo(self): try: decoder.decode(ints2octs((0, 0))) except PyAsn1Error: pass else: assert 0, 'end-of-contents octets accepted at top level'
def testIndefiniteLength(self): try: decoder.decode(ints2octs((6, 128, 0))) except PyAsn1Error: pass else: assert 0, 'indefinite length tolarated'
def decodeMessageVersion(wholeMsg): try: seq, wholeMsg = decoder.decode(wholeMsg, recursiveFlag=0) ver, wholeMsg = decoder.decode(wholeMsg, recursiveFlag=0) return ver except PyAsn1Error: raise ProtocolError('Invalid BER at SNMP version component')
def testLeading0x80Case4(self): try: decoder.decode(ints2octs((6, 2, 0x80, 0x7F))) except PyAsn1Error: pass else: assert 0, "Leading 0x80 tolarated"
def testLeading0x80Case1(self): try: decoder.decode(ints2octs((6, 5, 85, 4, 128, 129, 0))) except PyAsn1Error: pass else: assert 0, "Leading 0x80 tolarated"
def crackTicket(ticket, label, hashList): try: data = base64.b64decode(ticket) except: #print "DEBUG\n" + str(ticket) + "DEBUG\n\n" return "FAIL" + str(label) + "\n" manager = Manager() enctickets = manager.list() if data[0] == '\x76': try: enctickets.append((str(decoder.decode(data)[0][2][0][3][2]))) except: #print "DEBUG\n" + str(ticket) + "DEBUG\n\n" return "FAIL" + str(label) elif data[:2] == '6d': for ticket in data.strip().split('\n'): try: enctickets.append((str(decoder.decode(ticket.decode('hex'))[0][4][3][2]))) except: #print "DEBUG\n" + str(ticket) + "DEBUG\n\n" return "FAIL" + str(label) print "\nAccount: " + label for currentHash in hashList: ntlmHash_hex = binascii.unhexlify(currentHash) kdata, nonce = kerberos.decrypt(ntlmHash_hex, 2, enctickets[0]) if kdata: print "NTLM Hash: " + currentHash break return ""
def testBadSpec(self): try: decoder.decode(ints2octs((48, 2, 5, 0)), asn1Spec='not an Asn1Item') except PyAsn1Error: pass else: assert 0, 'Invalid asn1Spec accepted'
def testTypeChecking(self): try: decoder.decode(ints2octs((35, 4, 2, 2, 42, 42))) except PyAsn1Error: pass else: assert 0, 'accepted mis-encoded bit-string constructed out of an integer'
def testZeroLength(self): try: decoder.decode(ints2octs((6, 0, 0))) except PyAsn1Error: pass else: assert 0, 'zero length tolarated'
def testShortEncoding(self): try: decoder.decode(ints2octs((9, 1, 131))) except PyAsn1Error: pass else: assert 0, 'accepted too-short real'
def tst_info(self): x, substrate = decoder.decode(str(self.content['contentInfo']['content'])) if substrate: raise ValueError('Incomplete decoding') x, substrate = decoder.decode(str(x), asn1Spec=TSTInfo()) if substrate: raise ValueError('Incomplete decoding') return x
def testSpec(self): try: decoder.decode(ints2octs((2, 1, 12)), asn1Spec=univ.Null()) == (12, null) except PyAsn1Error: pass else: assert 0, "wrong asn1Spec worked out" assert decoder.decode(ints2octs((2, 1, 12)), asn1Spec=univ.Integer()) == (12, null)
def testTagFormat(self): try: decoder.decode( ints2octs((16, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)) ) except PyAsn1Error: pass else: assert 0, 'wrong tagFormat worked out'
def updatepac(key, rawticket, pac, debug=False, verbose=False): # attempt decoding of ticket try: ramticket, extra = decoder.decode(rawticket) serverticket = ramticket.getComponentByPosition(2) localticket = ramticket.getComponentByPosition(3) encserverticket = serverticket.getComponentByPosition(0).getComponentByPosition(3).getComponentByPosition(2).asOctets() except: raise ValueError('Unable to decode ticket. Invalid file.') if verbose: print 'Ticket succesfully decoded' decserverticketraw, nonce = kerberos.decrypt(key, 2, encserverticket) if decserverticketraw == None: raise ValueError('Unable to decrypt ticket. Invalid key.') elif verbose: print 'Decryption successful' decserverticket, extra = decoder.decode(decserverticketraw) #for i in range(len(decserverticket[3])): # print '---%i---' % i # print decserverticket[3][i] # have two here because I was using one to verify that the rewrite matched # This stuff should be removed, if it is still here Tim forgot...again origdecserverticket, extra = decoder.decode(decserverticketraw) # change the validity times in the server ticket updatetimestampsserverticket(decserverticket, str(decserverticket[5]), str(decserverticket[6]), str(decserverticket[7]), str(decserverticket[8])) adifrelevant, extra = decoder.decode(decserverticket[9][0][1]) chksum = kerberos.chksum(key, '\x11\x00\x00\x00', pac) #print 'newchecksum: %s' % chksum.encode('hex') # repair server checksum newpac = pac[:-44] + chksum + pac[-28:] # rebuild AD-IF-RELEVANT #print adifrelevant #print dir(adifrelevant.getComponentByPosition(0).getComponentByPosition(1)) adifrelevant.getComponentByPosition(0).getComponentByPosition(1)._value = newpac #print adifrelevant decserverticket.getComponentByPosition(9).getComponentByPosition(0).getComponentByPosition(1)._value = encoder.encode(adifrelevant) # put the ticket back together again newencserverticket = kerberos.encrypt(key, 2, encoder.encode(decserverticket), nonce) ramticket.getComponentByPosition(2).getComponentByPosition(0).getComponentByPosition(3).getComponentByPosition(2)._value = newencserverticket #print decserverticket return encoder.encode(ramticket)
def ajax(): key_data = request.forms['pubkey'] asn1 = base64.b64decode(key_data) # key = load_privatekey(FILETYPE_ASN1, asn1) t = decoder.decode(asn1) f = t[0][0][0][1] r = decoder.decode(bytes(int(__, 2) for __ in chunk_into(''.join([str(_) for _ in f]), 8)))[0] modulus = int(r[0]) e = int(r[1]) k = rsa.RSAPublicKey(e, modulus) return '{1}\n{0}'.format(modulus, e)
def testSpec(self): try: decoder.decode( '\002\001\014', asn1Spec=univ.Null() ) == (12, '') except PyAsn1Error: pass else: assert 0, 'wrong asn1Spec worked out' assert decoder.decode( '\002\001\014', asn1Spec=univ.Integer() ) == (12, '')
def decodeMessageVersion(wholeMsg): try: seq, wholeMsg = decoder.decode( wholeMsg, asn1Spec=univ.Sequence(), recursiveFlag=0 ) ver, wholeMsg = decoder.decode( wholeMsg, asn1Spec=univ.Integer(), recursiveFlag=0 ) if eoo.endOfOctets.isSameTypeWith(ver): raise ProtocolError('EOO at SNMP version component') return ver except PyAsn1Error: raise ProtocolError('Invalid BER at SNMP version component')
def _parseForREP(self, timestamp, asn_data, ip_packet): # check to see if it's KRB packet try: asn = decoder.decode(asn_data)[0] if asn[0] != 5: return None except: return None # check to see if it's an AS_REP or TGS_REP if asn[1] != constants.ApplicationTagNumbers.AS_REP.value and asn[1] != constants.ApplicationTagNumbers.TGS_REP.value: return None # try decoding (both AS_REP and TGS_REP are KDC_REP packets) try: rep = decoder.decode(asn_data, asn1Spec = AS_REP())[0] except: rep = decoder.decode(asn_data, asn1Spec = TGS_REP())[0] crealm = rep['crealm'] cname = self._getPrinc(rep['cname']) trealm = rep['ticket']['realm'] tname = self._getPrinc(rep['ticket']['sname']) if rep['ticket']['enc-part']['etype'] == Enctype.DES_CRC: tenc = str(rep['ticket']['enc-part']['cipher']) if rep['enc-part']['etype'] == Enctype.DES_CRC: cenc = str(rep['enc-part']['cipher']) try: tenc_packet = KerbPacket(asn, socket.inet_ntoa(ip_packet.src), socket.inet_ntoa(ip_packet.dst), asn[1], cname, crealm, tname, trealm, tenc, 1, timestamp) except: tenc_packet = None try: cenc_packet = KerbPacket(asn, socket.inet_ntoa(ip_packet.src), socket.inet_ntoa(ip_packet.dst), asn[1], cname, crealm, tname, trealm, cenc, 0, timestamp) except: cenc_packet = None return tenc_packet, cenc_packet
def OidFromAttid(prefixTable, attr): # separate the ATTRTYP into two parts upperWord = attr / 65536 lowerWord = attr % 65536 # search in the prefix table to find the upperWord, if found, # construct the binary OID by appending lowerWord to the end of # found prefix. binaryOID = None for j, item in enumerate(prefixTable): if item["ndx"] == upperWord: binaryOID = item["prefix"]["elements"][: item["prefix"]["length"]] if lowerWord < 128: binaryOID.append(chr(lowerWord)) else: if lowerWord >= 32768: lowerWord -= 32768 binaryOID.append(chr(((lowerWord / 128) % 128) + 128)) binaryOID.append(chr(lowerWord % 128)) break if binaryOID is None: return None return str(decoder.decode("\x06" + chr(len(binaryOID)) + "".join(binaryOID), asn1Spec=univ.ObjectIdentifier())[0])
def _parseauthattrs(auth_attrs, required): results = dict.fromkeys(required) for attr in auth_attrs: if (attr['type'] in oids.OID_TO_CLASS and oids.OID_TO_CLASS.get(attr['type']) in required): # There are more than those I require, but I don't know what they are, # and what to do with them. The spec does not talk about them. # One example: # 1.3.6.1.4.1.311.2.1.11 contains as value 1.3.6.1.4.1.311.2.1.21 # SPC_STATEMENT_TYPE_OBJID SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID results[oids.OID_TO_CLASS.get(attr['type'])] = attr['values'] if None in iter(results.values()): raise Asn1Error('Missing mandatory field(s) in auth_attrs.') # making sure that the auth_attrs were processed in correct order # they need to be sorted in ascending order in the SET, when DER encoded # This also makes sure that the tag on Attributes is correct. a = [der_encoder.encode(i) for i in auth_attrs] a.sort() attrs_for_hash = pkcs7.Attributes() for i in range(len(auth_attrs)): d, _ = decoder.decode(a[i], asn1Spec=pkcs7.Attribute()) attrs_for_hash.setComponentByPosition(i, d) encoded_attrs = der_encoder.encode(attrs_for_hash) return results, encoded_attrs
def OidFromAttid(prefixTable, attr): # separate the ATTRTYP into two parts upperWord = attr / 65536 lowerWord = attr % 65536 # search in the prefix table to find the upperWord, if found, # construct the binary OID by appending lowerWord to the end of # found prefix. binaryOID = None for j, item in enumerate(prefixTable): if item['ndx'] == upperWord: binaryOID = item['prefix']['elements'][:item['prefix']['length']] if lowerWord < 128: binaryOID.append(chr(lowerWord)) else: if lowerWord >= 32768: lowerWord -= 32768 binaryOID.append(chr(((lowerWord/128) % 128)+128)) binaryOID.append(chr(lowerWord%128)) break if binaryOID is None: return None from pyasn1.type import univ from pyasn1.codec.ber import decoder return str(decoder.decode('\x06' + chr(len(binaryOID)) + ''.join(binaryOID), asn1Spec = univ.ObjectIdentifier())[0])
def __init__(self, encodedMessage): d = decoder.decode(encodedMessage, asn1Spec = syncInfoValue()) self.newcookie = None self.refreshDelete = None self.refreshPresent = None self.syncIdSet = None for attr in [ 'newcookie', 'refreshDelete', 'refreshPresent', 'syncIdSet']: comp = d[0].getComponentByName(attr) if comp is not None: if attr == 'newcookie': self.newcookie = str(comp) return val = dict() cookie = comp.getComponentByName('cookie') if cookie is not None: val['cookie'] = str(cookie) if attr.startswith('refresh'): val['refreshDone'] = bool(comp.getComponentByName('refreshDone')) elif attr == 'syncIdSet': uuids = [] ids = comp.getComponentByName('syncUUIDs') for i in range(len(ids)): uuid = UUID(bytes=str(ids.getComponentByPosition(i))) uuids.append(str(uuid)) val['syncUUIDs'] = uuids val['refreshDeletes'] = bool(comp.getComponentByName('refreshDeletes')) setattr(self,attr,val) return
def _validateemptyparams(self, params): if params.isValue: param_value, rest = decoder.decode(params) if rest: raise Asn1Error('Extra unparsed content.') if not param_value.isSameTypeWith(univ.Null()): raise Asn1Error('Hasher has parameters. No idea what to do with them.')
def testWithOptionalAndDefaultedDefModeSubst(self): assert decoder.decode( ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), substrateFun=lambda a, b, c: (b, c) ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), 18)
def testIndefModeChunked(self): self.__init() assert decoder.decode( ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s ) == (self.s, null)
def testWithOptionaIndefMode(self): self.__initWithOptional() assert decoder.decode( ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)), asn1Spec=self.s ) == (self.s, null)
def testMinusOne(self): assert decoder.decode(ints2octs((2, 1, 255))) == (-1, null)
def testWithDefaultedIndefModeChunked(self): self.__initWithDefaulted() assert decoder.decode( ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s ) == (self.s, null)
def testByUntaggedSubst(self): assert decoder.decode( ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s, substrateFun=lambda a, b, c: (b, c) ) == (ints2octs((4, 3, 102, 111, 120)), 5)
def testTaggedExSubst(self): assert decoder.decode( ints2octs((164, 5, 4, 3, 102, 111, 120)), asn1Spec=self.s, substrateFun=lambda a, b, c: (b, c) ) == (ints2octs((164, 5, 4, 3, 102, 111, 120)), 7)
def testExpectedEoo(self): result, remainder = decoder.decode(ints2octs((0, 0)), allowEoo=True) assert eoo.endOfOctets.isSameTypeWith(result) and result == eoo.endOfOctets assert remainder == null
def testIndefiniteEoo(self): result, remainder = decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x00))) assert result == () and remainder == null, 'incorrect decoding of indefinite length end-of-octets'
def testWithOptionalAndDefaultedIndefMode(self): assert decoder.decode( ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)) ) == (self.s, null)
def LDAP3KerberosLogin(self, connection, user, password, domain='', lmhash='', nthash='', aesKey='', kdcHost=None, TGT=None, TGS=None, useCache=True): from pyasn1.codec.ber import encoder, decoder from pyasn1.type.univ import noValue """ logins into the target system explicitly using Kerberos. Hashes are used if RC4_HMAC is supported. :param string user: username :param string password: password for the user :param string domain: domain where the account is valid for (required) :param string lmhash: LMHASH used to authenticate using hashes (password is not used) :param string nthash: NTHASH used to authenticate using hashes (password is not used) :param string aesKey: aes256-cts-hmac-sha1-96 or aes128-cts-hmac-sha1-96 used for Kerberos authentication :param string kdcHost: hostname or IP Address for the KDC. If None, the domain will be used (it needs to resolve tho) :param struct TGT: If there's a TGT available, send the structure here and it will be used :param struct TGS: same for TGS. See smb3.py for the format :param bool useCache: whether or not we should use the ccache for credentials lookup. If TGT or TGS are specified this is False :return: True, raises an Exception if error. """ if lmhash != '' or nthash != '': if len(lmhash) % 2: lmhash = '0' + lmhash if len(nthash) % 2: nthash = '0' + nthash try: # just in case they were converted already lmhash = unhexlify(lmhash) nthash = unhexlify(nthash) except TypeError: pass # Importing down here so pyasn1 is not required if kerberos is not used. from impacket.krb5.ccache import CCache from impacket.krb5.asn1 import AP_REQ, Authenticator, TGS_REP, seq_set from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS from impacket.krb5 import constants from impacket.krb5.types import Principal, KerberosTime, Ticket import datetime if TGT is not None or TGS is not None: useCache = False if useCache: try: ccache = CCache.loadFile(os.getenv('KRB5CCNAME')) except Exception as e: # No cache present print(e) pass else: # retrieve domain information from CCache file if needed if domain == '': domain = ccache.principal.realm['data'].decode('utf-8') logging.debug('Domain retrieved from CCache: %s' % domain) logging.debug('Using Kerberos Cache: %s' % os.getenv('KRB5CCNAME')) principal = 'ldap/%s@%s' % (self.__target.upper(), domain.upper()) creds = ccache.getCredential(principal) if creds is None: # Let's try for the TGT and go from there principal = 'krbtgt/%s@%s' % (domain.upper(), domain.upper()) creds = ccache.getCredential(principal) if creds is not None: TGT = creds.toTGT() logging.debug('Using TGT from cache') else: logging.debug('No valid credentials found in cache') else: TGS = creds.toTGS(principal) logging.debug('Using TGS from cache') # retrieve user information from CCache file if needed if user == '' and creds is not None: user = creds['client'].prettyPrint().split(b'@')[0].decode( 'utf-8') logging.debug('Username retrieved from CCache: %s' % user) elif user == '' and len(ccache.principal.components) > 0: user = ccache.principal.components[0]['data'].decode( 'utf-8') logging.debug('Username retrieved from CCache: %s' % user) # First of all, we need to get a TGT for the user userName = Principal( user, type=constants.PrincipalNameType.NT_PRINCIPAL.value) if TGT is None: if TGS is None: tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT( userName, password, domain, lmhash, nthash, aesKey, kdcHost) else: tgt = TGT['KDC_REP'] cipher = TGT['cipher'] sessionKey = TGT['sessionKey'] if TGS is None: serverName = Principal( 'ldap/%s' % self.__target, type=constants.PrincipalNameType.NT_SRV_INST.value) tgs, cipher, oldSessionKey, sessionKey = getKerberosTGS( serverName, domain, kdcHost, tgt, cipher, sessionKey) else: tgs = TGS['KDC_REP'] cipher = TGS['cipher'] sessionKey = TGS['sessionKey'] # Let's build a NegTokenInit with a Kerberos REQ_AP blob = SPNEGO_NegTokenInit() # Kerberos blob['MechTypes'] = [TypesMech['MS KRB5 - Microsoft Kerberos 5']] # Let's extract the ticket from the TGS tgs = decoder.decode(tgs, asn1Spec=TGS_REP())[0] ticket = Ticket() ticket.from_asn1(tgs['ticket']) # Now let's build the AP_REQ apReq = AP_REQ() apReq['pvno'] = 5 apReq['msg-type'] = int(constants.ApplicationTagNumbers.AP_REQ.value) opts = [] apReq['ap-options'] = constants.encodeFlags(opts) seq_set(apReq, 'ticket', ticket.to_asn1) authenticator = Authenticator() authenticator['authenticator-vno'] = 5 authenticator['crealm'] = domain seq_set(authenticator, 'cname', userName.components_to_asn1) now = datetime.datetime.utcnow() authenticator['cusec'] = now.microsecond authenticator['ctime'] = KerberosTime.to_asn1(now) encodedAuthenticator = encoder.encode(authenticator) # Key Usage 11 # AP-REQ Authenticator (includes application authenticator # subkey), encrypted with the application session key # (Section 5.5.1) encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 11, encodedAuthenticator, None) apReq['authenticator'] = noValue apReq['authenticator']['etype'] = cipher.enctype apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator blob['MechToken'] = encoder.encode(apReq) request = ldap3.operation.bind.bind_operation(connection.version, ldap3.SASL, user, None, 'GSS-SPNEGO', blob.getData()) # Done with the Kerberos saga, now let's get into LDAP if connection.closed: # try to open connection if closed connection.open(read_server_info=False) connection.sasl_in_progress = True response = connection.post_send_single_response( connection.send('bindRequest', request, None)) connection.sasl_in_progress = False if response[0]['result'] != 0: raise Exception(response) connection.bound = True return True
def prepareDataElements( self, snmpEngine, transportDomain, transportAddress, wholeMsg ): # 7.2.2 try: msg, restOfwholeMsg = decoder.decode( wholeMsg, asn1Spec=self._snmpMsgSpec ) except PyAsn1Error: debug.logger & debug.flagMP and debug.logger('prepareDataElements: %s' % (sys.exc_info()[1],)) snmpInASNParseErrs, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpInASNParseErrs') snmpInASNParseErrs.syntax = snmpInASNParseErrs.syntax + 1 raise error.StatusInformation( errorIndication = errind.parseError ) debug.logger & debug.flagMP and debug.logger('prepareDataElements: %s' % (msg.prettyPrint(),)) # 7.2.3 headerData = msg.getComponentByPosition(1) msgVersion = messageProcessingModel = msg.getComponentByPosition(0) msgID = headerData.getComponentByPosition(0) msgFlags, = headerData.getComponentByPosition(2).asNumbers() maxMessageSize = headerData.getComponentByPosition(1) securityModel = headerData.getComponentByPosition(3) securityParameters = msg.getComponentByPosition(2) debug.logger & debug.flagMP and debug.logger('prepareDataElements: msg data msgVersion %s msgID %s securityModel %s' % (msgVersion, msgID, securityModel)) # 7.2.4 if securityModel not in snmpEngine.securityModels: snmpUnknownSecurityModels, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpUnknownSecurityModels') snmpUnknownSecurityModels.syntax = snmpUnknownSecurityModels.syntax + 1 raise error.StatusInformation( errorIndication = errind.unsupportedSecurityModel ) # 7.2.5 if msgFlags & 0x03 == 0x00: securityLevel = 1 elif (msgFlags & 0x03) == 0x01: securityLevel = 2 elif (msgFlags & 0x03) == 0x03: securityLevel = 3 else: snmpInvalidMsgs = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMPv2-MIB', 'snmpInvalidMsgs') snmpInvalidMsgs.syntax = snmpInvalidMsgs.syntax + 1 raise error.StatusInformation( errorIndication = errind.invalidMsg ) if msgFlags & 0x04: reportableFlag = 1 else: reportableFlag = 0 # 7.2.6 smHandler = snmpEngine.securityModels[securityModel] try: ( securityEngineID, securityName, scopedPDU, maxSizeResponseScopedPDU, securityStateReference ) = smHandler.processIncomingMsg( snmpEngine, messageProcessingModel, maxMessageSize, securityParameters, securityModel, securityLevel, wholeMsg, msg ) debug.logger & debug.flagMP and debug.logger('prepareDataElements: SM succeeded') except error.StatusInformation: statusInformation, origTraceback = sys.exc_info()[1:3] debug.logger & debug.flagMP and debug.logger('prepareDataElements: SM failed, statusInformation %s' % statusInformation) if 'errorIndication' in statusInformation: # 7.2.6a if 'oid' in statusInformation: # 7.2.6a1 securityStateReference = statusInformation[ 'securityStateReference' ] contextEngineId = statusInformation['contextEngineId'] contextName = statusInformation['contextName'] if 'scopedPDU' in statusInformation: scopedPDU = statusInformation['scopedPDU'] pdu = scopedPDU.getComponentByPosition(2).getComponent() else: pdu = None maxSizeResponseScopedPDU = statusInformation[ 'maxSizeResponseScopedPDU' ] securityName = None # XXX secmod cache used # 7.2.6a2 stateReference = self._cache.newStateReference() self._cache.pushByStateRef( stateReference, msgVersion=messageProcessingModel, msgID=msgID, contextEngineId=contextEngineId, contextName=contextName, securityModel=securityModel, securityName=securityName, securityLevel=securityLevel, securityStateReference=securityStateReference, reportableFlag=reportableFlag, msgMaxSize=maxMessageSize, maxSizeResponseScopedPDU=maxSizeResponseScopedPDU, transportDomain=transportDomain, transportAddress=transportAddress ) # 7.2.6a3 try: snmpEngine.msgAndPduDsp.returnResponsePdu( snmpEngine, 3, securityModel, securityName, securityLevel, contextEngineId, contextName, 1, pdu, maxSizeResponseScopedPDU, stateReference, statusInformation ) except error.StatusInformation: pass debug.logger & debug.flagMP and debug.logger('prepareDataElements: error reported') # 7.2.6b if sys.version_info[0] <= 2: raise statusInformation else: try: raise statusInformation.with_traceback(origTraceback) finally: # Break cycle between locals and traceback object # (seems to be irrelevant on Py3 but just in case) del origTraceback else: # Sniff for engineIDs k = (transportDomain, transportAddress) if k not in self.__engineIDs: contextEngineId, contextName, pdus = scopedPDU pdu = pdus.getComponent() # Here we assume that authentic/default EngineIDs # come only in the course of engine-to-engine communication. if pdu.tagSet in rfc3411.internalClassPDUs: self.__engineIDs[k] = { 'securityEngineID': securityEngineID, 'contextEngineId': contextEngineId, 'contextName': contextName } expireAt = int(self.__expirationTimer + 300 / snmpEngine.transportDispatcher.getTimerResolution()) if expireAt not in self.__engineIDsExpQueue: self.__engineIDsExpQueue[expireAt] = [] self.__engineIDsExpQueue[expireAt].append(k) debug.logger & debug.flagMP and debug.logger('prepareDataElements: cache securityEngineID %r for %r %r' % (securityEngineID, transportDomain, transportAddress)) snmpEngineID, = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineID') snmpEngineID = snmpEngineID.syntax # 7.2.7 XXX PDU would be parsed here? contextEngineId, contextName, pdu = scopedPDU pdu = pdu.getComponent() # PDUs # 7.2.8 pduVersion = api.protoVersion2c # 7.2.9 pduType = pdu.tagSet # 7.2.10 if pduType in rfc3411.responseClassPDUs or \ pduType in rfc3411.internalClassPDUs: # 7.2.10a try: cachedReqParams = self._cache.popByMsgId(msgID) except error.ProtocolError: smHandler.releaseStateInformation(securityStateReference) raise error.StatusInformation( errorIndication = errind.dataMismatch ) # 7.2.10b sendPduHandle = cachedReqParams['sendPduHandle'] else: sendPduHandle = None debug.logger & debug.flagMP and debug.logger('prepareDataElements: using sendPduHandle %s for msgID %s' % (sendPduHandle, msgID)) # 7.2.11 if pduType in rfc3411.internalClassPDUs: # 7.2.11a varBinds = pMod.apiPDU.getVarBinds(pdu) if varBinds: statusInformation = error.StatusInformation( errorIndication=_snmpErrors.get( varBinds[0][0], 'errorReportReceived' ), oid=varBinds[0][0], val=varBinds[0][1], sendPduHandle=sendPduHandle ) # 7.2.11b (incomplete implementation) # 7.2.11c smHandler.releaseStateInformation(securityStateReference) # 7.2.11d stateReference = None # 7.2.11e XXX may need to pass Reports up to app in some cases... raise statusInformation statusInformation = None # no errors ahead # 7.2.12 if pduType in rfc3411.responseClassPDUs: # 7.2.12a -> noop # 7.2.12b if securityModel != cachedReqParams['securityModel'] or \ securityName != cachedReqParams['securityName'] or \ securityLevel != cachedReqParams['securityLevel'] or \ contextEngineId != cachedReqParams['contextEngineId'] or \ contextName != cachedReqParams['contextName']: smHandler.releaseStateInformation(securityStateReference) raise error.StatusInformation( errorIndication = errind.dataMismatch ) # 7.2.12c smHandler.releaseStateInformation(securityStateReference) stateReference = None # 7.2.12d return ( messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, pdu, pduType, sendPduHandle, maxSizeResponseScopedPDU, statusInformation, stateReference ) # 7.2.13 if pduType in rfc3411.confirmedClassPDUs: # 7.2.13a if securityEngineID != snmpEngineID: smHandler.releaseStateInformation(securityStateReference) raise error.StatusInformation( errorIndication = errind.engineIDMismatch ) # 7.2.13b stateReference = self._cache.newStateReference() self._cache.pushByStateRef( stateReference, msgVersion=messageProcessingModel, msgID=msgID, contextEngineId=contextEngineId, contextName=contextName, securityModel=securityModel, securityName=securityName, securityLevel=securityLevel, securityStateReference=securityStateReference, reportableFlag=reportableFlag, msgMaxSize=maxMessageSize, maxSizeResponseScopedPDU=maxSizeResponseScopedPDU, transportDomain=transportDomain, transportAddress=transportAddress ) debug.logger & debug.flagMP and debug.logger('prepareDataElements: new stateReference %s' % stateReference) # 7.2.13c return ( messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, pdu, pduType, sendPduHandle, maxSizeResponseScopedPDU, statusInformation, stateReference ) # 7.2.14 if pduType in rfc3411.unconfirmedClassPDUs: # Pass new stateReference to let app browse request details stateReference = self._cache.newStateReference() # This is not specified explicitly in RFC smHandler.releaseStateInformation(securityStateReference) return ( messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, pdu, pduType, sendPduHandle, maxSizeResponseScopedPDU, statusInformation, stateReference ) smHandler.releaseStateInformation(securityStateReference) raise error.StatusInformation( errorIndication = errind.unsupportedPDUtype )
def message_handler(self, transportDispatcher, transportDomain, transportAddress, whole_message): while whole_message: message_version = api.decodeMessageVersion(whole_message) if message_version in api.protoModules: protocol = api.protoModules[message_version] else: self.logger.warn( 'Unsupported SNMP version "{}"'.format(message_version)) return request, whole_message = decoder.decode( whole_message, asn1Spec=protocol.Message()) response = protocol.apiMessage.getResponse(request) request_pdus = protocol.apiMessage.getPDU(request) community = protocol.apiMessage.getCommunity(request) if not self.valid_community(community): self.logger.warn('Invalid community "{}"'.format(community)) return response_pdus = protocol.apiMessage.getPDU(response) var_binds = [] pending_errors = [] error_index = 0 if request_pdus.isSameTypeWith(protocol.GetRequestPDU()): for oid, val in protocol.apiPDU.getVarBinds(request_pdus): if oid in self.pdu.oid_mapping: var_binds.append( (oid, self.pdu.oid_mapping[oid].value)) else: return elif request_pdus.isSameTypeWith(protocol.GetNextRequestPDU()): for oid, val in protocol.apiPDU.getVarBinds(request_pdus): error_index += 1 try: oid = TraversableOidMapping(self.pdu.oid_mapping)\ .next(to=oid) val = self.pdu.oid_mapping[oid].value except (KeyError, IndexError): pending_errors.append( (protocol.apiPDU.setNoSuchInstanceError, error_index)) var_binds.append((oid, val)) elif request_pdus.isSameTypeWith(protocol.SetRequestPDU()): for oid, val in protocol.apiPDU.getVarBinds(request_pdus): error_index += 1 if oid in self.pdu.oid_mapping: self.pdu.oid_mapping[oid].value = val var_binds.append((oid, val)) else: var_binds.append((oid, val)) pending_errors.append( (protocol.apiPDU.setNoSuchInstanceError, error_index)) else: protocol.apiPDU.setErrorStatus(response_pdus, 'genErr') protocol.apiPDU.setVarBinds(response_pdus, var_binds) # Commit possible error indices to response PDU for f, i in pending_errors: f(response_pdus, i) transportDispatcher.sendMessage(encoder.encode(response), transportDomain, transportAddress) return whole_message
def testTaggedImIndefMode(self): s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null)
def testWithDefaultedDefMode(self): self.__initWithDefaulted() assert decoder.decode( ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s ) == (self.s, null)
def testByUntaggedIndefMode(self): assert decoder.decode( ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s ) == (univ.Any('\004\003fox'), null)
def testWithOptionalDefModeChunked(self): self.__initWithOptional() assert decoder.decode( ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)), asn1Spec=self.s ) == (self.s, null)
def testExplicitTagUndefLength(self): s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4)) s.setComponentByPosition(0, univ.Null(null)) assert decoder.decode(ints2octs((164, 128, 5, 0, 0, 0)), asn1Spec=s) == (s, null)
def testZeroLong(self): assert decoder.decode(ints2octs((2, 1, 0))) == (0, null)
def testNegLong(self): assert decoder.decode( ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1)) ) == (-0xffffffffffffffff, null)
def testNegInt(self): assert decoder.decode(ints2octs((2, 1, 244))) == (-12, null)
def testUndefLength(self): self.s.setComponentByPosition(2, univ.OctetString('abcdefgh')) assert decoder.decode(ints2octs((36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0)), asn1Spec=self.s) == (self.s, null)
def testPosInt(self): assert decoder.decode(ints2octs((2, 1, 12))) == (12, null)
def testWithoutSpec(self): self.s.setComponentByPosition(0, univ.Null(null)) assert decoder.decode(ints2octs((5, 0))) == (self.s, null) assert decoder.decode(ints2octs((5, 0))) == (univ.Null(null), null)
def testWithOptionalAndDefaultedDefModeChunked(self): assert decoder.decode( ints2octs( (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)) ) == (self.s, null)
def testBySpec(self): self.s.setComponentByPosition(0, univ.Null(null)) assert decoder.decode( ints2octs((5, 0)), asn1Spec=self.s ) == (self.s, null)
def testWithOptionalAndDefaultedIndefModeChunked(self): self.__initWithOptionalAndDefaulted() assert decoder.decode( ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s ) == (self.s, null)
def testPosLong(self): assert decoder.decode( ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255)) ) == (0xffffffffffffffff, null)
def testDecoder(self): assert decoder.decode(ints2octs((12, 3, 97, 98, 99))) == (char.UTF8String(version_info[0] == 3 and 'abc' or unicode('abc')), null)
def testTrue(self): assert decoder.decode(ints2octs((1, 1, 1))) == (1, null)