def __diffieHellmanSessionMessageHandler(
        self, sentSeqNumber, sessionID, iv, encryptedMessage, prevSeqNumber, mk, sessionKey, expirationDate
    ):

        iv = base64.b64decode(iv)
        self.__verifyExpirationDate(expirationDate)
        decryptedMessage = self.__decryptData(sessionKey, iv, encryptedMessage)
        sentSeqNumber = self.__decryptData(sessionKey, iv, sentSeqNumber)

        try:
            lastSeqNumber = self.activeUsers.getDiffieHellmanUserLastSeqNumber(sessionID)
        except Exception as e:
            raise e

        if lastSeqNumber > sentSeqNumber:
            raise Exception("Wrong SeqNumber")

        try:
            parsedMessage = unmarshal(decryptedMessage[:-1])
            iv = self.__generateIV()
            newSeqNumber = self.__encryptData(sessionKey, iv, sentSeqNumber)
        except Exception as e:
            raise Exception("Unmarshal failed of: " + str(decryptedMessage) + ": " + str(e))

        if isinstance(parsedMessage, ClientAuthentication):
            secretSignature = parsedMessage.secretSignature
            nBI = parsedMessage.nBI
            name = parsedMessage.name
            userName = parsedMessage.userName
            hostName = parsedMessage.hostName

            publicKey = self.__userRSAPublicKey(nBI)
            self.__verifySignature(base64.b64decode(mk), publicKey, secretSignature)

            timmer = time.time()

            self.activeUsers.addSessionEstablishedUser(
                nBI, name, userName, hostName, sessionID, sentSeqNumber, sessionKey, expirationDate, timmer
            )

            ack = Acknowledge()
            ackXML = ack.creatXMLMessage()

            encryptedMessageText = self.__encryptData(sessionKey, iv, ackXML)
            encryptedMessage = EncryptedMessage(newSeqNumber, sessionID, iv, encryptedMessageText)

        else:
            notAck = NotAcknowledge()
            encryptedMessageText = self.__encryptData(sessionKey, iv, notAck.creatXMLMessage())
            encryptedMessage = EncryptedMessage(newSeqNumber, sessionID, iv, encryptedMessageText)

        return encryptedMessage.creatXMLMessage()
    def run(self):

        while True:

            originalMessage, sendAddress = self.inQueue.get()

            try:
                parsedMessage = unmarshal(originalMessage[:-1])
            except Exception as e:
                print "Unmarshal failed of: " + originalMessage + ": " + str(e)
                continue
            if isinstance(parsedMessage, DiffieHellmanRequest):
                try:
                    messageToSend = self.__diffieHellmanRequestHandler(parsedMessage)
                    print "sent: " + messageToSend
                    self.udpSocket.sendto(messageToSend, sendAddress)
                except Exception as e:
                    print e

            elif isinstance(parsedMessage, EncryptedMessage):
                sentSeqNumber = parsedMessage.seqNumber
                sessionID = parsedMessage.sessionID
                iv = parsedMessage.iv
                encryptedMessage = parsedMessage.encryptedMessage

                diffieHellmanSession = 0

                try:
                    prevSeqNumber, mk, sessionKey, expirationDate, _ = self.activeUsers.getDiffieHellmanUser(sessionID)
                    diffieHellmanSession = 1
                except:
                    try:
                        nBI, prevSeqNumber, sessionKey, expirationDate, _ = self.activeUsers.getSessionEstablishedUser(
                            sessionID
                        )
                    except Exception as e:
                        print str(e)
                        raise e

                if diffieHellmanSession == 1:
                    try:
                        messageToSend = self.__diffieHellmanSessionMessageHandler(
                            sentSeqNumber,
                            sessionID,
                            iv,
                            encryptedMessage,
                            prevSeqNumber,
                            mk,
                            sessionKey,
                            expirationDate,
                        )
                        print "sent: " + messageToSend
                        self.udpSocket.sendto(messageToSend, sendAddress)
                    except Exception as e:
                        print str(e) + "\n it was not possible terminate authentication"
                        continue
                else:
                    try:
                        messageToSend = self.__sessionEstablishedMessageHandler(
                            nBI,
                            sentSeqNumber,
                            sessionID,
                            iv,
                            encryptedMessage,
                            prevSeqNumber,
                            sessionKey,
                            expirationDate,
                        )
                        print "sent: " + messageToSend
                        self.udpSocket.sendto(messageToSend, sendAddress)
                    except Exception as e:
                        print str(e)
                        continue
    def __sessionEstablishedMessageHandler(
        self, nBI, sentSeqNumber, sessionID, iv, encryptedMessage, prevSeqNumber, sessionKey, expirationDate
    ):
        iv = base64.b64decode(iv)
        decryptedMessage = self.__decryptData(sessionKey, iv, encryptedMessage)
        sentSeqNumber = self.__decryptData(sessionKey, iv, sentSeqNumber)

        try:
            lastSeqNumber = self.activeUsers.getSessionEstablishedUserLastSeqNumber(sessionID)
        except Exception as e:
            raise e

        if lastSeqNumber > sentSeqNumber:
            raise Exception("Wrong SeqNumber")

        try:
            parsedMessage = unmarshal(decryptedMessage[:-1])
            iv = self.__generateIV()
            newSeqNumber = self.__encryptData(sessionKey, iv, sentSeqNumber)
        except Exception as e:
            raise Exception("Unmarshal failed: " + str(e))

        if isinstance(parsedMessage, Command):
            self.__verifyExpirationDate(expirationDate)
            date = parsedMessage.date
            command = parsedMessage.command

            self.activeUsers.addCommand(sessionID, date, command)
            self.activeUsers.updateTimmerSessionEstablishedUsers(sessionID)
            self.activeUsers.updateSeqNumberSessionEstablishedUsers(sessionID, sentSeqNumber)

            ack = Acknowledge()
            ackXML = ack.creatXMLMessage()

            encryptedMessageText = self.__encryptData(sessionKey, iv, ackXML)

            encryptedMessage = EncryptedMessage(newSeqNumber, sessionID, iv, encryptedMessageText)

        elif isinstance(parsedMessage, TearDown):
            self.__verifyExpirationDate(expirationDate)
            try:
                self.activeUsers.removeSessionEstablished(sessionID)
                ack = Acknowledge()
                ackXML = ack.creatXMLMessage()

                encryptedMessageText = self.__encryptData(sessionKey, iv, ackXML)
                encryptedMessage = EncryptedMessage(newSeqNumber, sessionID, iv, encryptedMessageText)
            except:
                notAck = NotAcknowledge()
                encryptedMessageText = self.__encryptData(sessionKey, iv, notAck.creatXMLMessage())
                encryptedMessage = EncryptedMessage(newSeqNumber, sessionID, iv, encryptedMessageText)

        elif isinstance(parsedMessage, NewSecretRequest):
            newSessionKey = hashlib.sha1(self.__generateSymmetricKey()).hexdigest()
            newExpirationDate = self.__generateExpirationDate(5)  # 5min

            newSessionKeyResponse = NewSecretResponse(
                sessionID, newSessionKey, newExpirationDate, self.certificate, self.serverIP, Constants.UDP_PORT
            )
            tokenSignature = self.__signMessage(newSessionKeyResponse.getTokenXML())
            newSessionKeyResponse.tokenSignature = tokenSignature

            print "new sessionkey: " + newSessionKeyResponse.creatXMLMessage()

            encryptedMessageText = self.__encryptData(sessionKey, iv, newSessionKeyResponse.creatXMLMessage())

            self.activeUsers.updateSessionEstablishedUsers(sessionID, sentSeqNumber, newSessionKey, newExpirationDate)

            encryptedMessage = EncryptedMessage(newSeqNumber, sessionID, iv, encryptedMessageText)

        else:
            notAck = NotAcknowledge()
            encryptedMessageText = self.__encryptData(sessionKey, iv, notAck.creatXMLMessage())
            encryptedMessage = EncryptedMessage(newSeqNumber, sessionID, iv, encryptedMessageText)

        return encryptedMessage.creatXMLMessage()