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 __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 __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 __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 __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)