def fixedSizeTemplate(self, n, m): bytes = "" msgBuilder = MessageData.GetMessageBuilder(DummyMessage) for i in range(1,n): msgBuilder["data"].setData(str(i)*m) bytes += Packet.MsgToPacketBytes(msgBuilder) bufferOffset = 0 for i in range(1,n): resultCode, result = Packet.RestorePacket(bytes, bufferOffset) # check that we got a message self.assertEqual(resultCode, Packet.BUFFER_STATUS_CONTAINS_MESSAGE, "Message %d failed: %s" % (i, resultCode)) # deserialize the message restoredData, bufferOffset = result restoredMsgBuilder, bytesUsed = MessageData.Deserialize(restoredData) # make sure the data matches self.assertEqual(restoredMsgBuilder["data"].data(), str(i)*m, "Restoration of message %d failed. Bad data" % i) self.assertEqual(bytesUsed, len(restoredData), "Didn't use up all bytes in message %d deserialization" % i) # make sure that we used up all the bytes self.assertEqual(bufferOffset, len(bytes),"Didn't use up all bytes in packet processing")
def write(self, data): if self.__written: raise Exception("Internal Error. This should never happen") self.__written = True if not self.__deserialized: self.__deserialized, desBytes = MessageData.Deserialize(data) endTime = time.time() runTimeInSeconds = int(endTime - self.__ctx.startTime) runTimeInSeconds += 1 logger.info("Finished execution of code in %f seconds" % runTimeInSeconds) response = MessageData.GetMessageBuilder(EncryptedMobileCodeResult) response["Cookie"].setData(self.__ctx.cookie) response["RunTime"].setData(runTimeInSeconds) response["RunMobileCodeHash"].setData(self.__ctx.runMobileCodeHash) if self.__deserialized.topLevelData( )[0] != definitions.playground.base.MobileCodeResult.PLAYGROUND_IDENTIFIER: response["Success"].setData(False) response["EncryptedResult"].setData("") else: encrypter = AES.new(self.__key, mode=AES.MODE_CBC, IV=self.__iv) padder = playground.crypto.Pkcs7Padding(AES.block_size) encrypted = encrypter.encrypt(padder.padData(data)) response["Success"].setData(self.__deserialized["success"].data()) response["EncryptedMobileCodeResultPacket"].setData(encrypted) # in some ways, it would be easier to save "response" rather than # response serialized. But we're saving this stuff to disk in case # of interruption or disconnect. So serialized it is. self.__ctx.finishCallback(self.__ctx, response.serialize()) packetTrace(logger, response, "Encrypted mobile code result ready for transmission")
def __handleOpenSession(self, protocol, msg): msgObj = msg.data() if msgObj.Authenticated: return self.__error("Authenticated operation not yet supported", fatal=True, ClientNonce=msgObj.ClientNonce) self.__curState = self.__factory.getNewSessionState( msgObj.ClientNonce, msgObj.MobileCodeId) if not self.__curState: logger.info( "Unwilling to serve this mobile code operation (%s). Refused to create state." % msgObj.MobileCodeId) response = MessageData.GetMessageBuilder(SessionOpenFailure) response["ClientNonce"].setData(msgObj.ClientNonce) response["ErrorMessage"].setData( "Unwilling to serve mobile code operation %s" % msgObj.MobileCodeId) self.writeMsgAndClose(response) return self.__curState.state = self.STATE_OPEN response = MessageData.GetMessageBuilder(SessionOpen) response["ClientNonce"].setData(msgObj.ClientNonce) response["Cookie"].setData(self.__curState.cookie) response["ServiceLevel"].setData(self.__curState.level) response["BillingRate"].setData(self.__curState.billingRate) response["Account"].setData(self.__accountName) response["ServiceExtras"].setData(self.__curState.extras) packetTrace( logger, response, "Received opensession message from %s. State is now open" % str(self.transport.getPeer())) self.writeMsgAndClose(response)
def __error(self, errMsg, **kargs): logger.error("MobileCodeServer had an error %s" % errMsg) if kargs.has_key("fatal"): fatal = kargs["fatal"] del kargs["fatal"] else: fatal = True if not self.__curState or self.__curState.state == self.STATE_ERROR: if self.transport: self.transport.loseConnection() return None if self.__curState.state == self.STATE_UNINIT: response = MessageData.GetMessageBuilder(SessionOpenFailure) response["ClientNonce"].setData(kargs.get("ClientNonce", 0)) self.__curState.state = self.STATE_ERROR else: if self.__curState.state == self.STATE_OPEN: response = MessageData.GetMessageBuilder(RunMobileCodeFailure) elif self.__curState.state == self.STATE_PURCHASE or self.__state == self.STATE_REREQUEST: response = MessageData.GetMessageBuilder( AcquireDecryptionKeyFailure) else: response = MessageData.GetMessageBuilder(GeneralFailure) response["Cookie"].setData(self.__curState.cookie) for karg in kargs.keys(): response[karg].setData(kargs[karg]) response["ErrorMessage"].setData(errMsg) if fatal: self.__state = self.STATE_ERROR packetTrace(logger, response, "Had an error %s" % errMsg) self.writeMsgAndClose(response) return None
def __handleRunMobileCode(self, prot, msg): msgObj = msg.data() self.__curState = self.__factory.getSessionState(msgObj.Cookie) if not self.__curState or not self.__curState.state == self.STATE_OPEN: curState = self.__curState and self.__curState.state or "<NO STATE>" return self.__error( "Invalid command. Cannot run mobile code unless session open (%s)" % curState, fatal=True) logger.info("State found for cookie %s. State=%s" % (msgObj.Cookie, self.__curState.state)) if msgObj.MaxRuntime > self.CODE_TIMEOUT: response = MessageData.GetMessageBuilder(RunMobileCodeAck) response["Cookie"].setData(self.__curState.cookie) response["MobileCodeAccepted"].setData(False) response["Message"].setData("Max Run Time parameter is too long.") self.writeMsgAndClose(response) rawRunMobileCodeMsg = msgObj.RunMobileCodePacket startTime = time.time() ctx = CodeExecutionContext() ctx.startTime = startTime ctx.cookie = self.__curState.cookie ctx.runMobileCodeHash = SHA.new(rawRunMobileCodeMsg).digest() ctx.finishCallback = lambda ctx, response: self.__factory.mobileCodeComplete( ctx.cookie, response) aesKey = os.urandom(16) aesIv = os.urandom(16) succeed, errmsg = self.__factory.createMobileCodeRecord( self.__curState.cookie, aesKey, aesIv, msgObj.MaxRuntime) if not succeed: return self.__error("Could not run this code. Reason: " + errmsg, fatal=True) transport = WrapMobileCodeResultTransport(self.transport.getPeer(), self.transport.getHost(), aesKey, aesIv, ctx) wrappedProtocol = WrapMobileCodeResultProtocol(transport) logger.info("Starting execution of mobile code. MaxRunTime: %d" % msgObj.MaxRuntime) #realCodeHandler = playground.extras.sandbox.SandboxCodeunitAdapter(self.SANDBOX_CONTROLLER, #timeout=min(msgObj.MaxRuntime,self.CODE_TIMEOUT)) #codeHandler = lambda codeUnit: self.__codeHandlerWrapper(realCodeHandler, codeUnit) runMobileCodeHandler = RunMobileCodeHandler( self, sandbox=SandboxCodeRunner()) runMobileCodeHandler(wrappedProtocol, MessageData.Deserialize(rawRunMobileCodeMsg)[0]) self.__curState.state = self.STATE_RUNNING response = MessageData.GetMessageBuilder(RunMobileCodeAck) response["Cookie"].setData(self.__curState.cookie) response["MobileCodeAccepted"].setData(True) self.writeMsgAndClose(response)
def test_basicProtocol(self): for messageSize in [0, 1, 100, 100000, 1000000]: randomMessage = os.urandom(messageSize) echoMessage = MessageData.GetMessageBuilder(EchoProtocolMessage) echoMessage["original"].setData("True") echoMessage["data"].setData(randomMessage) self.clientTransport.writeMessage(echoMessage) response = self.serverTransport.storage.pop() responseMessageBuilder, bytesConsumed = MessageData.Deserialize(response) responseData = responseMessageBuilder.data() self.assertEqual(responseData.original, False, "Echo response should not be original") self.assertEqual(responseData.data, randomMessage, "Echo message doesn't match") self.assertEqual(len(response), bytesConsumed, "Message only took up %d bytes of %d byte response" % (bytesConsumed, len(response)))
def __handleCheckMobileCodeResult(self, prot, msg): msgObj = msg.data() self.__curState = self.__factory.getSessionState(msgObj.Cookie) if not self.__curState: return self.__error("No such session found for cookie %s." % msgObj.Cookie, fatal=True) elif self.__curState.state == self.STATE_RUNNING: response = MessageData.GetMessageBuilder(RunMobileCodeAck) response["Cookie"].setData(self.__curState.cookie) response["MobileCodeAccepted"].setData(True) response["Message"].setData("Still running") return self.writeMsgAndClose(response) elif self.__curState.state == self.STATE_PURCHASE: # curState.encryptedResult is an already serialized packet. # so we can't use writeMsg. Have to write, then close # Can't do this here: self.writeMsgAndClose(self.__curState.encryptedResult) self.transport.write(self.__curState.encryptedResult) return self.transport.loseConnection() if self.__curState.state not in [ self.STATE_RUNNING, self.STATE_PURCHASE ]: return self.__error( "Invalid command. Cannot check result in state (%s) cookie %s" % (self.__curState.state, self.__curState.cookie), fatal=False)
def set(self, name, addr, nameCerts, addrCerts, nameSig, addrSig, unset=False): if not self.__connected: errD = defer.Deferred() self.callLater( .1, lambda: errD.errback(Exception("set called before connect"))) return errD if self.__setD.has_key((name, addr)): errD = defer.Deferred() self.callLater( .1, lambda: errD.errback( Exception("set called on same key before completion"))) return errD self.__setD[(name, addr)] = defer.Deferred() mb = MessageData.GetMessageBuilder(N2PSet) mb["Name"].setData(name) mb["Address"].setData(addr) mb["NameCertChain"].setData(nameCerts) mb["AddrCertChain"].setData(addrCerts) mb["NameSignature"].setData(nameSig) mb["AddrSignature"].setData(addrSig) mb["Unset"].setData(unset) self.transport.writeMessage(mb) return self.__setD[(name, addr)]
def __handlePurchase(self, prot, msg): msgObj = msg.data() self.__curState = self.__factory.getSessionState(msgObj.Cookie) if self.__curState.state != self.STATE_PURCHASE: return self.__error( "Invalid command. Not in correct state for purchase (%s)" % self.__curState.state, fatal=False) if not self.__factory.validatePurchase(msgObj.Cookie, msgObj.Receipt, msgObj.ReceiptSignature): return self.__error("Invalid purchase receipt", fatal=True) decryptionKey, decryptionIv = self.__factory.getDecryptionData( msgObj.Cookie) if not decryptionKey or not decryptionIv: return self.__error("Unexpected failure in getDecryptionData!", fatal=True) response = MessageData.GetMessageBuilder(ResultDecryptionKey) response["Cookie"].setData(msgObj.Cookie) response["key"].setData(decryptionKey) response["iv"].setData(decryptionIv) self.__state = self.STATE_FINISHED packetTrace( logger, response, "%s sending key %s, iv %s" % (msgObj.Cookie, binascii.hexlify(decryptionKey), binascii.hexlify(decryptionIv))) self.writeMsgAndClose(response)
def rerouteResponse(self, srcAddress, srcPort, dstAddress, dstPort, buf): mb = MessageData.GetMessageBuilder(Gate2GateMessage) mb["srcAddress"].setData(srcAddress) mb["srcPort"].setData(srcPort) mb["dstAddress"].setData(dstAddress) mb["dstPort"].setData(dstPort) mb["clientPacket"].setData(buf) self.transport.writeMessage(mb)
def __getHandler(self, protocol, msg): msgObj = msg.data() mb = MessageData.GetMessageBuilder(N2PGetResponse) mb["Name"].setData(msgObj.Name) address, authoritative = self._factory.resolveNameToAddress( msgObj.Name) mb["Address"].setData(address) mb["Authoritative"].setData(authoritative) self.transport.writeMessage(mb)
def packMaker(self): package = MessageData.GetMessageBuilder("PCPMessageID") package["Packet_Type"].setData("") package["Sequence_Number"].setData(0) package["Data"].setData("") package["Segment_END"].setData(False) package["Checksum"].setData(0) package["Timestamp"].setData(0) return package
def __buildHandshakeMessage(self, msg_type, cert_chain, key, nonce_s, nonce_c, data): message_builder = MessageData.GetMessageBuilder(PSSTHandshakeMessage) message_builder["MessageType"].setData(msg_type) message_builder["Cert_Chain"].setData(cert_chain) message_builder["Key"].setData(key) message_builder["Nonce_S"].setData(nonce_s) message_builder["Nonce_C"].setData(nonce_c) message_builder["Data"].setData(data) return message_builder
def encapsulatedMessageHandler(protocol, msg): try: c2cMsg, actualBytes = MessageData.Deserialize(msg.G2GMessage) except: # todo, this is an error. There wasn't a full message. Add logging? return if g_InterceptionDb.has_key(msg.Address) and g_InterceptionDb[ msg.Address].chaperoneProtocol == protocol: key = c2cMsg.playground_msgID messageInterceptor.ignore.add(key) protocol.dataReceived(Packet.MsgToPacketBytes(c2cMsg))
def __sendResponse(self): if not self.__responseComp: raise Exception("could not compute response") if self.__responseComp.errorMessage: raise Exception("Error during computation: %s" % self.__responseComp.errorMessage) if not self.__responseComp.response: raise Exception("No response or error message generated") respMsg = MessageData.GetMessageBuilder(intercept.ChallengeResponse) respMsg["Address"].setData(self.__interceptAddress) respMsg["Response"].setData(self.__responseComp.response) reactor.callFromThread( lambda: self.transport.write(Packet.MsgToPacketBytes(respMsg)))
def releaseAddress(self, address, msg): if address in self.currentRegistrations: self.currentRegistrations.remove(address) curData = g_InterceptionDb.get(address, None) if not curData: return del g_InterceptionDb[address] if not curData.chaperoneProtocol: return if not curData.chaperoneProtocol.transport: return termMsg = MessageData.GetMessageBuilder(intercept.Terminated) termMsg["Address"].setData(address) termMsg["Reason"].setData(msg) curData.chaperoneProtocol.transport.write( Packet.MsgToPacketBytes(termMsg))
def wrap_send_buffer(self, buf, seq): # Add a PTCL Header onto the buffer. Wrap it into a packet and send to C2C responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage) responseMessageBuilder["Hash"].setData('0') responseMessageBuilder["MessageType"].setData("DATA") responseMessageBuilder["MessageSeq"].setData(seq) responseMessageBuilder["AckSeq"].setData(self.__curr_ackSeq) responseMessageBuilder["Data"].setData(buf) responseMessageBuilder["Hash"].setData( self.hash_it(responseMessageBuilder)) logger.info("Harsh: " + str(self._addr) + " Sending Data and the sequence number I am sending is: " + str(seq)) self.transport.writeMessage(responseMessageBuilder)
def get(self, name): if not self.__connected: errD = defer.Deferred() self.callLater( .1, lambda: errD.errback(Exception("set called before connect"))) return errD if self.__getD.has_key(name): errD = defer.Deferred() self.callLater( .1, lambda: errD.errback( Exception("duplicate lookup before completion"))) return errD self.__getD[name] = defer.Deferred() mb = MessageData.GetMessageBuilder(N2PGet) mb["Name"].setData(name) self.transport.writeMessage(mb) return self.__getD[name]
def __handleRerequest(self, prot, msg): msgObj = msg.data() self.__curState = self.__factory.getSessionState(msgObj.Cookie) if not self.__curState.state == self.STATE_FINISHED: return self.__error("Cannot re-request a key until the session is finished", fatal=False) self.__state = self.STATE_REREQUEST msgObj = msg.data() decryptionKey, decryptionIv = self.__factory.getDecryptionData(msgObj.Cookie) if not decryptionKey or not decryptionIv: return self.__error("No decryption key found", fatal=False) response = MessageData.GetMessageBuilder(ResultDecryptionKey) response["Cookie"].setData(msgObj.Cookie) response["key"].setData(decryptionKey) response["iv"].setData(decryptionIv) packetTrace(logger, response, "%s re-sending key %s, iv %s" % (msgObj.Cookie, binascii.hexlify(decryptionKey), binascii.hexlify(decryptionIv))) self.writeMsgAndClose(response)
class Protocol(SimpleMessageHandlingProtocol): """ The actual Protocol launched by Hijacker when a connection is received """ def __init__(self, hijacker, addr=None): SimpleMessageHandlingProtocol.__init__(self) self.hijacker = hijacker self.registerMessageHandler( definitions.playground.base.RunMobileCode, self.__handleRemoteCodeMessage) def connectionMade(self): """ Connect to the Hijacker's own address in order to send a message to the real recipient """ self.connectToSelf = self.hijacker.clientBase.connect( MobileCodeClient(), self.hijacker.clientBase.getAddress(), 100) def __handleRemoteCodeMessage(self, protocol, msg): msgObj = msg.data() try: codeObj = pickle.loads(msgObj.pythonCode) except Exception, e: """ Ignore code objects that can't be loaded """ return if hasattr(codeObj, "HIJACKER_ATTR_ID"): """ If the Code Object has this attr, it came from us and needs to be ignored """ return """ Send the Kill message to the real recipient """ killSwitch = DefaultPlaygroundMobileCodeUnit( g_KILL_PYTHON_CODE_STRING) killSwitch.HIJACKER_ATTR_ID = 0 self.connectToSelf.sendPythonCode(killSwitch, MobileCodeClient.CodeCallback()) """ Send a corrupted result (0) back to the original recipient """ toClientMsg = MessageData.GetMessageBuilder( definitions.playground.base.MobileCodeResult) toClientMsg["ID"].setData(msgObj.ID) toClientMsg["success"].setData(True) toClientMsg["result"].setData("0") toClientMsg["resultPickled"].setData(pickle.dumps(0)) toClientMsg["exception"].setData("") toClientMsg["exceptionPickled"].setData("") self.transport.writeMessage(toClientMsg)
def __MIBRequestHandler(self, prot, msg): msgObj = msg.data() authData = msgObj.authData resp = MessageData.GetMessageBuilder(MIBResponse) resp["ID"].setData(msgObj.ID) resp["responses"].init() if self.__authenticate and not self.__factory.authenticate( prot.transport.getHost(), authData): resp["success"].setData(False) resp["responses"].add() resp["responses"][-1].setData("Authentication failed") prot.transport.write(resp.serialize()) return resp["success"].setData(True) mib = msgObj.MIB args = msgObj.args callbacks = self.__factory.getCallbacksForKey(mib) responses = [] for c in callbacks: try: responses += map(str, c(mib, args)) except Exception, e: print e
def __setHandler(self, protocol, msg): msgObj = msg.data() mb = MessageData.GetMessageBuilder(N2PSetResponse) mb["Address"].setData(msgObj.Address) mb["Name"].setData(msgObj.Name) if msgObj.AddrCertChain: if msgObj.AddrCertChain[-1] != self.__root: msgObj.AddrCertChain.append(self.__root) if msgObj.NameCertChain[-1] != self.__root: msgObj.NameCertChain.append(self.__root) addrCertChain = map(X509Certificate.loadPEM, msgObj.AddrCertChain) nameCertChain = map(X509Certificate.loadPEM, msgObj.NameCertChain) if not self.__verifySignature(msgObj.Address, msgObj.AddrSignature, addrCertChain[0]): result, resultMsg = False, "Address is not signed by a valid cert" elif not self.__verifySignature(msgObj.Name, msgObj.NameSignature, nameCertChain[0]): result, resultMsg = False, "Name is not signed by a valid cert" else: result, resultMsg = self.__verifySet(msgObj.Name, msgObj.Address, nameCertChain, addrCertChain) if not result: mb["Result"].setData(resultMsg) self.transport.writeMessage(mb) return authoritative = True else: authoritative = False res, resMsg = self._factory.registerNameToAddress( msgObj.Name, msgObj.Address, authoritative, msgObj.Unset) if not res: mb["Result"].setData(resMsg) else: mb["Result"].setData(self.SET_SUCCESSFUL) self.transport.writeMessage(mb)
def handleChallengeResponse(self, chaperone, msg): # got an unexpected challenge response. Shut down connection. if not self.outstandingRegistrations.has_key(msgObj.Address): chaperone.transport.loseConnection() return algorithm, message, zerosRequired = self.outstandingRegistrations[ msgObj.Address] realhash = hashlib.sha256(message + msgObj.Response).hexdigest() realhashAsNumber = int(realhash, 16) resultMsg = MessageData.GetMessageBuilder(intercept.RegistrationResult) resultMsg["Address"].setData(msg.Address) if (realhashAsNumber >> (256 - zerosRequired)) != 0: resultMsg["Result"].setData(False) chaperone.transport.write(Packet.MsgToPacketBytes(resultMsg)) chaperone.callLater(0.5, chaperone.transport.loseConnection) else: resultMsg["Result"].setData(True) del self.outstandingRegistrations[msg.Address] curData = g_InterceptionDb.get(msg.Address, None) if curData: curData.interceptionHandler.releaseAddress( msg.Address, "Bumped") del g_InterceptionDb[msg.Address] g_InterceptionDb[msg.Address] = InterceptionData() g_InterceptionDb[msg.Address].starttime = time.time() g_InterceptionDb[msg.Address].chaperoneProtocol = chaperone g_InterceptionDb[msg.Address].interceptionHandler = self g_InterceptionDb[msg.Address].zerosRequired = zerosRequired + 1 self.currentRegistrations.add(msg.Address) timeout = InterceptionData.DEFAULT_TIMEOUT / (2**( zerosRequired - InterceptionData.DEFAULT_ZEROS)) chaperone.callLater( timeout, lambda: self.releaseAddress(msg.Address, "Timeout")) chaperone.transport.write(Packet.MsgToPacketBytes(resultMsg))
def __handleConnectionMessages(self, state, msgObj=None): if state == 0: self.__state = 0 self.__connected = 0 self.__handshake = 1 self.__currSeq = random.getrandbits(32) ##print "Preparing to send a SYN Message" ##print "The sequence number I am sending is :", self.__currSeq responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage) responseMessageBuilder["Hash"].setData('0') responseMessageBuilder["MessageType"].setData("SYN") responseMessageBuilder["MessageSeq"].setData(self.__currSeq) responseMessageBuilder["AckSeq"].setData(0) responseMessageBuilder["Data"].setData("") # TODO Calculate the hash of the whole packet created above # and fill it in the HASH field of the packet msg_hash = self.hash_it(responseMessageBuilder) responseMessageBuilder["Hash"].setData(msg_hash) self.__waiting = 1 self.transport.writeMessage(responseMessageBuilder) Timer.callLater(0.1, lambda: self.checkState(0)) elif state == 1: # Server state where server received a SYN packet and will now send an SYNACK if (self.__state == 3 or self.__state == 2): ##print "Already Connected" return ##print "I have got a SYN and will now Send a SYNACK" self.__state = 1 self.__currSeq = random.getrandbits(32) #self.__curr_ackSeq = msgObj.MessageSeq ##print "The sequence number I got in the SYN is : ",msgObj.MessageSeq,"and the sequence number I am sending in the SYNACK is: ", self.__currSeq if (msgObj != None): self.__curr_ackSeq = msgObj.MessageSeq logger.debug( "Harsh: %s Hey! We got our SYN, setting curr_ackSeq to %d" % (self._addr, self.__curr_ackSeq)) #Prepare and send a SYNACK Message responseMessageBuilder = MessageData.GetMessageBuilder( PTCLMessage) responseMessageBuilder["Hash"].setData('0') responseMessageBuilder["MessageType"].setData("SYNACK") responseMessageBuilder["MessageSeq"].setData(self.__currSeq) responseMessageBuilder["AckSeq"].setData(self.__curr_ackSeq) responseMessageBuilder["Data"].setData("") msg_hash = self.hash_it(responseMessageBuilder) responseMessageBuilder["Hash"].setData(msg_hash) self.transport.writeMessage(responseMessageBuilder) Timer.callLater(0.1, lambda: self.checkState(1)) elif state == 2: if (self.__state >= 2): ##print "Multiple SYNACK, Discard" return self.__state = 2 ##print "I have got a SYNACK and will now send an ACK followed by data" ##print "The sequence number I got is : ",msgObj.MessageSeq, "and the sequence number i am sending is : ", self.__currSeq # Extract sequence number and set state variable self.__curr_ackSeq = msgObj.MessageSeq logger.debug( "Harsh: %s Hey! We got our SYNACK, setting curr_ackSeq to %d" % (self._addr, self.__curr_ackSeq)) #Prepare and send an ACK Message responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage) responseMessageBuilder["Hash"].setData('0') responseMessageBuilder["MessageType"].setData("ACK") responseMessageBuilder["MessageSeq"].setData(0) responseMessageBuilder["AckSeq"].setData(msgObj.MessageSeq) responseMessageBuilder["Data"].setData("") #TODO Calculate the hash of the whole packet created above # and fill it in the HASH field of the packet msg_hash = self.hash_it(responseMessageBuilder) responseMessageBuilder["Hash"].setData(msg_hash) self.transport.writeMessage(responseMessageBuilder) ##print "sent an ACK , we are connected ,now sending Data:" ##print "Setting connected in client" self.__handshake = 1 self.__connected = 1 #self.__last_contig = self.__curr_ackSeq #set the timer #No timer because now data has to be sent, after sending ACK you don't # wait and start pushing data directly ##print "Sent Data" #print "Setting hb timer on receiver" self.__hb_timer = Timer.OneshotTimer(lambda: self.checkData()) self.__hb_timer.run(10) Timer.callLater(0.1, lambda: self.processQueue()) self.__session_timer = Timer.OneshotTimer( lambda: self.checkSession()) self.__session_timer.run(35) #Timer.callLater(0.1,lambda:self.checkState(2,msgObj)) #Check if the state has looped back to the same state. Store the current time # and check if it has changed after timeout elif state == 3: # Server side state, once server has received ACK from Client in response to SYNACK self.__state = 3 # Extract sequence number, check and set state variable ##print "I have got an ACK" #self.__currSeq = self.__currSeq +1 ##print "Setting connected in server" self.__connected = 1 self.__handshake = 1 self.__last_contig = msgObj.MessageSeq ##print "The sequence number I got is: ", msgObj.MessageSeq #print "Setting hb timer on sender" self.__hb_timer = Timer.OneshotTimer(lambda: self.checkData()) self.__hb_timer.run(10) self.__session_timer = Timer.OneshotTimer( lambda: self.checkSession()) self.__session_timer.run(35) elif state == 5: self.__state = 5 # Extract sequence number and set state variable ##print "I am going to send a FIN Message" self.__currSeq = self.__currSeq + 1 #Prepare and send an FIN Message responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage) responseMessageBuilder["Hash"].setData('0') responseMessageBuilder["MessageType"].setData("FIN") responseMessageBuilder["MessageSeq"].setData(self.__currSeq) responseMessageBuilder["AckSeq"].setData(0) responseMessageBuilder["Data"].setData("") #TODO Calculate the hash of the whole packet created above # and fill it in the HASH field of the packet msg_hash = self.hash_it(responseMessageBuilder) responseMessageBuilder["Hash"].setData(msg_hash) self.transport.writeMessage(responseMessageBuilder) #set the timer self.__timely = Timer.callLater(0.1, lambda: self.checkState(5)) elif state == 6: ##print "I got a FIN Message and I will send a FINACK" self.__finhandshake = 1 self.__state = 6 self.__curr_ackSeq = msgObj.MessageSeq #Prepare and send an FINACK Message responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage) responseMessageBuilder["Hash"].setData('0') responseMessageBuilder["MessageType"].setData("FINACK") responseMessageBuilder["MessageSeq"].setData(0) responseMessageBuilder["AckSeq"].setData(self.__curr_ackSeq) responseMessageBuilder["Data"].setData("") #TODO Calculate the hash of the whole packet created above # and fill it in the HASH field of the packet msg_hash = self.hash_it(responseMessageBuilder) responseMessageBuilder["Hash"].setData(msg_hash) ##print "Sending FINACK now: " self.transport.writeMessage(responseMessageBuilder) Timer.callLater( 0.1, lambda: self.getHigherProtocol().connectionLost( "Received FIN")) self.transport.loseConnection() self.__connected = 0 elif state == 7: ###print "I am suppose to send an ACK for data received:" responseMessageBuilder = MessageData.GetMessageBuilder(PTCLMessage) responseMessageBuilder["Hash"].setData('0') responseMessageBuilder["MessageType"].setData("ACK") responseMessageBuilder["MessageSeq"].setData(0) logger.info("Harsh: %s Sending ACK with ACK Sequence %d" % (self._addr, self.__curr_ackSeq)) responseMessageBuilder["AckSeq"].setData(self.__curr_ackSeq) # There is no data being piggy bagged on the ACK , if required put the data here from the # buffer where it is stored. responseMessageBuilder["Data"].setData("") responseMessageBuilder["Hash"].setData( self.hash_it(responseMessageBuilder)) self.transport.writeMessage(responseMessageBuilder) elif state == 8: self.__state = 8 self.__currSeq = 0 self.__curr_ackSeq = 0 ##print "I received a FINACK - Trying to terminate connection" ##print "dataList and rcvWindow are both empty, safe to terminate, connectionLost() called" Timer.callLater( 0.2, lambda: self.getHigherProtocol().connectionLost( "Received FINACK")) self.transport.loseConnection() if self.__timely: self.__timely.cancel() self.__connected = 0 else: pass
def __buildDataMessage(self, msg_type, mac, data): message_builder = MessageData.GetMessageBuilder(PSSTDataMessage) message_builder["MessageType"].setData(msg_type) message_builder["MAC"].setData(mac) message_builder["Data"].setData(data) return message_builder
def write(self, data): encap = MessageData.GetMessageBuilder(intercept.EncapsulatedC2C) encap["Address"].setData(self.__interceptAddress) encap["C2CMessage"].setData(data) self.transport.write(Packet.MsgToPacketBytes(encap))
def connectionMade(self): intMsg = MessageData.GetMessageBuilder(intercept.Register) intMsg["Address"].setData(self.__interceptAddress) self.transport.write(Packet.MsgToPacketBytes(intMsg))