def test_GET(logFixture,snoopyDispatcher,twoEndPoints): (coap1,coap2,securityEnabled) = twoEndPoints clientOptions = [] buggyRes = buggyResource() if securityEnabled: clientContext = oscoap.SecurityContext(masterSecret=DUMMYMASTERSECRET, senderID=DUMMYSERVERID, recipientID=DUMMYCLIENTID) clientOptions = [o.ObjectSecurity(context=clientContext)] serverContext = oscoap.SecurityContext(masterSecret=DUMMYMASTERSECRET, senderID=DUMMYCLIENTID, recipientID=DUMMYSERVERID) buggyRes.addSecurityBinding((serverContext, d.METHOD_ALL)) coap1.addResource(buggyRes) # have coap2 do a get with pytest.raises(e.coapRcInternalServerError): reply = coap2.GET( uri = 'coap://[{0}]:{1}/{2}/'.format(IPADDRESS1,d.DEFAULT_UDP_PORT,'buggy'), confirmable = True, options=clientOptions )
def test_GET(logFixture, snoopyDispatcher, twoEndPoints): (coap1, coap2, securityEnabled) = twoEndPoints options = [] if securityEnabled: context = oscoap.SecurityContext(masterSecret=OSCOAPMASTERSECRET, senderID=OSCOAPSERVERID, recipientID=OSCOAPCLIENTID) options = [o.ObjectSecurity(context=context)] # have coap2 do a get reply = coap2.GET(uri='coap://[{0}]:{1}/{2}/'.format( IPADDRESS1, d.DEFAULT_UDP_PORT, RESOURCE), confirmable=False, options=options) assert reply == DUMMYVAL
def test_METHODNOTALLOWED(logFixture, snoopyDispatcher, twoEndPoints, confirmableFixture): (coap1, coap2, securityEnabled) = twoEndPoints options = [] if securityEnabled: context = oscoap.SecurityContext(masterSecret=OSCOAPMASTERSECRET, senderID=OSCOAPSERVERID, recipientID=OSCOAPCLIENTID) options = [o.ObjectSecurity(context=context)] # have coap2 do a post with pytest.raises(e.coapRcMethodNotAllowed): reply = coap2.POST(uri='coap://[{0}]:{1}/{2}/'.format( IPADDRESS1, d.DEFAULT_UDP_PORT, RESOURCE), confirmable=confirmableFixture, options=options)
def test_BADREQUEST(logFixture, snoopyDispatcher, twoEndPoints, confirmableFixture): (coap1, coap2, securityEnabled) = twoEndPoints options = [] if securityEnabled: # have coap2 do a get with the right IDs but wrong master secret clientContext = oscoap.SecurityContext(masterSecret=DUMMYMASTERSECRET, senderID=OSCOAPSERVERID, recipientID=OSCOAPCLIENTID) clientOptions = [o.ObjectSecurity(context=clientContext)] with pytest.raises(e.coapRcBadRequest): reply = coap2.GET(uri='coap://[{0}]:{1}/{2}/'.format( IPADDRESS1, d.DEFAULT_UDP_PORT, RESOURCE), confirmable=confirmableFixture, options=clientOptions) else: pass
def test_UNAUTHORIZED_2(logFixture, snoopyDispatcher, twoEndPoints, confirmableFixture): (coap1, coap2, securityEnabled) = twoEndPoints options = [] if securityEnabled: # have coap2 do a get with wrong context clientContext = oscoap.SecurityContext(masterSecret=DUMMYMASTERSECRET, senderID=DUMMYSERVERID, recipientID=DUMMYCLIENTID) clientOptions = [o.ObjectSecurity(context=clientContext)] with pytest.raises(e.coapRcUnauthorized): reply = coap2.GET( uri='coap://[{0}]:{1}/{2}/'.format(IPADDRESS1, d.DEFAULT_UDP_PORT, RESOURCE), confirmable=confirmableFixture, options=clientOptions ) else: pass
def test_GET(logFixture, snoopyDispatcher, twoEndPoints): (coap1, coap2, securityEnabled) = twoEndPoints # adjust timeouts so test is faster coap2.ackTimeout = 2 coap2.respTimeout = 2 options = [] if securityEnabled: context = oscoap.SecurityContext(masterSecret=OSCOAPMASTERSECRET, senderID=OSCOAPSERVERID, recipientID=OSCOAPCLIENTID) options = [o.ObjectSecurity(context=context)] # have coap2 do a get with pytest.raises(e.coapTimeout): reply = coap2.GET(uri='coap://[{0}]:{1}/{2}/'.format( IPADDRESS_INVALID, d.DEFAULT_UDP_PORT, RESOURCE), confirmable=False, options=options)
from coap import coapObjectSecurity as oscoap import logging_setup SERVER_IP = '::1' # open c = coap.coap(udpPort=5000) context = oscoap.SecurityContext( masterSecret=binascii.unhexlify('000102030405060708090A0B0C0D0E0F'), senderID=binascii.unhexlify('636c69656e74'), recipientID=binascii.unhexlify('736572766572'), aeadAlgorithm=oscoap.AES_CCM_16_64_128()) objectSecurity = o.ObjectSecurity(context=context) try: # retrieve value of 'test' resource p = c.GET('coap://[{0}]/test'.format(SERVER_IP), confirmable=True, options=[objectSecurity]) print '=====' print ''.join([chr(b) for b in p]) print '=====' except Exception as err: print err # close c.close()
def _receive(self, timestamp, sender, rawbytes): # all UDP packets are received here output = [] output += ['\n{0} _receive message:'.format(self.name)] output += ['- timestamp: {0}'.format(timestamp)] output += ['- sender: {0}'.format(sender)] output += ['- bytes: {0}'.format(u.formatBuf(rawbytes))] output = '\n'.join(output) log.debug(output) srcIp = sender[0] srcIp = u.trimAddress(srcIp) srcPort = sender[1] # parse messages try: message = m.parseMessage(rawbytes) options = message['options'] except e.messageFormatError as err: log.warning('malformed message {0}: {1}'.format( u.formatBuf(rawbytes), str(err))) return # dispatch message try: if message['code'] in d.METHOD_ALL: # this is meant for a resource (request) #==== decrypt message if encrypted innerOptions = [] foundContext = None requestPartialIV = None if 'ciphertext' in message.keys(): # retrieve security context # before decrypting we don't know what resource this request is meant for # so we take the first binding with the correct context (recipientID) blindContext = self._securityContextLookup( u.buf2str(message['kid'])) if not blindContext: if self.secContextHandler: appContext = self.secContextHandler( u.buf2str(message['kid'])) if not appContext: raise e.coapRcUnauthorized( 'Security context not found.') else: raise e.coapRcUnauthorized( 'Security context not found.') foundContext = blindContext if blindContext != None else appContext requestPartialIV = u.zeroPadString( u.buf2str(message['partialIV']), foundContext.getIVLength()) # decrypt the message try: (innerOptions, plaintext) = oscoap.unprotectMessage( foundContext, version=message['version'], code=message['code'], options=message['options'], ciphertext=message['ciphertext'], partialIV=requestPartialIV) except e.oscoapError as err: raise e.coapRcBadRequest( 'OSCOAP unprotect failed: {0}'.format(str(err))) payload = plaintext else: # message not encrypted payload = message['payload'] options += innerOptions #==== find right resource # retrieve path path = coapUri.options2path(options) log.debug('path="{0}"'.format(path)) # find resource that matches this path resource = None with self.resourceLock: for r in self.resources: if r.matchesPath(path): resource = r break log.debug('resource={0}'.format(resource)) if not resource: raise e.coapRcNotFound() #==== check if appropriate security context was used for the resource (context, authorizedMethods) = resource.getSecurityBinding() if context is not None: if context != foundContext: raise e.coapRcUnauthorized( 'Unauthorized security context for the given resource' ) objectSecurity = oscoap.objectSecurityOptionLookUp(options) if objectSecurity: objectSecurity.setContext(foundContext) #==== get a response # call the right resource's method try: if message[ 'code'] == d.METHOD_GET and d.METHOD_GET in authorizedMethods: (respCode, respOptions, respPayload) = resource.GET(options=options) elif message[ 'code'] == d.METHOD_POST and d.METHOD_POST in authorizedMethods: (respCode, respOptions, respPayload) = resource.POST(options=options, payload=payload) elif message[ 'code'] == d.METHOD_PUT and d.METHOD_PUT in authorizedMethods: (respCode, respOptions, respPayload) = resource.PUT(options=options, payload=payload) elif message[ 'code'] == d.METHOD_DELETE and d.METHOD_DELETE in authorizedMethods: (respCode, respOptions, respPayload) = resource.DELETE(options=options) elif message['code'] not in d.METHOD_ALL: raise SystemError('unexpected code {0}'.format( message['code'])) else: raise e.coapRcUnauthorized( 'Unauthorized method for the given resource') except Exception as err: if isinstance(err, e.coapRc): raise else: raise e.coapRcInternalServerError() #==== send back response # determine type of response packet if message['type'] == d.TYPE_CON: responseType = d.TYPE_ACK elif message['type'] == d.TYPE_NON: responseType = d.TYPE_NON else: raise SystemError('unexpected type {0}'.format( message['type'])) # if resource is protected with a security context, add Object-Security option if foundContext: # verify that the Object-Security option was not set by the resource handler assert not any( isinstance(option, o.ObjectSecurity) for option in respOptions) objectSecurity = o.ObjectSecurity(context=foundContext) respOptions += [objectSecurity] # if Stateless-Proxy option was present in the request echo it for option in options: if isinstance(option, o.StatelessProxy): respOptions += [option] break # build response packets and pass partialIV from the request for OSCOAP's processing response = m.buildMessage(msgtype=responseType, token=message['token'], code=respCode, messageId=message['messageId'], options=respOptions, payload=respPayload, securityContext=foundContext, partialIV=requestPartialIV) # send self.socketUdp.sendUdp( destIp=srcIp, destPort=srcPort, msg=response, ) elif message['code'] in d.COAP_RC_ALL: # this is meant for a transmitter (response) # find transmitter msgkey = (srcIp, srcPort, message['token'], message['messageId']) found = False with self.transmittersLock: self._cleanupTransmitter() for (k, v) in self.transmitters.items(): # try matching if (msgkey[0] == k[0] and msgkey[1] == k[1] and (msgkey[2] == k[2] or msgkey[3] == k[3])): found = True v.receiveMessage(timestamp, srcIp, srcPort, message) break if found == False: raise e.coapRcBadRequest( 'could not find transmitter corresponding to {0}, transmitters are {1}' .format( msgkey, ','.join( [str(k) for k in self.transmitters.keys()]))) else: raise NotImplementedError() except e.coapRc as err: # log log.warning(err) # determine type of response packet if message['type'] == d.TYPE_CON: responseType = d.TYPE_ACK elif message['type'] == d.TYPE_NON: responseType = d.TYPE_NON else: raise SystemError('unexpected type {0}'.format( message['type'])) # if Stateless-Proxy option was present in the request echo it errorOptions = [] for option in options: if isinstance(option, o.StatelessProxy): errorOptions += [option] break # build response packets response = m.buildMessage( msgtype=responseType, token=message['token'], code=err.rc, messageId=message['messageId'], options=errorOptions, ) # send self.socketUdp.sendUdp( destIp=srcIp, destPort=srcPort, msg=response, ) except Exception as err: log.critical(traceback.format_exc())