예제 #1
0
    def Recv(self):
        num_received_bytes = len(self.socket_data)

        try:
            self.socket_data += self.host_socket.recv(4096)
        except:
            return

        if (len(self.socket_data) == num_received_bytes):
            return
        if (self.socket_data.count(DATA_PARTIT_BYTE) == 0):
            return

        split_data = self.socket_data.split(DATA_PARTIT_BYTE)
        data_blobs = split_data[:len(split_data) - 1]
        final_blob = split_data[len(split_data) - 1:][0]

        def check_message_timestamp(msg):
            ctr = str_to_int32(msg)

            if (ctr <= self.incoming_msg_ctr):
                return False

            self.incoming_msg_ctr = ctr
            return True

        for raw_data_blob in data_blobs:
            if (len(raw_data_blob) == 0):
                continue

            if (self.use_secure_session()):
                dec_data_blob = decrypt_auth_message(self.aes_cipher_obj,
                                                     raw_data_blob,
                                                     self.use_msg_auth_codes())

                ## can only happen in case of an invalid MAC or missing timestamp
                if (len(dec_data_blob) < 4):
                    continue

                ## ignore any replayed messages
                if (not check_message_timestamp(dec_data_blob[0:4])):
                    continue

                ## after decryption dec_command might represent a batch of
                ## commands separated by newlines, all of which need to be
                ## handled successfully
                split_commands = dec_data_blob[4:].split(DATA_PARTIT_BYTE)
                strip_commands = [(cmd.rstrip('\r')).lstrip(' ')
                                  for cmd in split_commands]

                for command in strip_commands:
                    self.Handle(command)
            else:
                if (raw_data_blob[0] == DATA_MARKER_BYTE):
                    continue

                ## strips leading spaces and trailing carriage return
                self.Handle((raw_data_blob.rstrip('\r')).lstrip(' '))

        self.socket_data = final_blob
예제 #2
0
	def Recv(self):
		num_received_bytes = len(self.socket_data)

		try:
			self.socket_data += self.host_socket.recv(4096)
		except:
			return

		if (len(self.socket_data) == num_received_bytes):
			return
		if (self.socket_data.count(DATA_PARTIT_BYTE) == 0):
			return

		split_data = self.socket_data.split(DATA_PARTIT_BYTE)
		data_blobs = split_data[: len(split_data) - 1  ]
		final_blob = split_data[  len(split_data) - 1: ][0]

		def check_message_timestamp(msg):
			ctr = str_to_int32(msg)

			if (ctr <= self.incoming_msg_ctr):
				return False

			self.incoming_msg_ctr = ctr
			return True

		for raw_data_blob in data_blobs:
			if (len(raw_data_blob) == 0):
				continue

			if (self.use_secure_session()):
				dec_data_blob = decrypt_auth_message(self.aes_cipher_obj, raw_data_blob, self.use_msg_auth_codes())

				## can only happen in case of an invalid MAC or missing timestamp
				if (len(dec_data_blob) < 4):
					continue

				## ignore any replayed messages
				if (not check_message_timestamp(dec_data_blob[0: 4])):
					continue

				## after decryption dec_command might represent a batch of
				## commands separated by newlines, all of which need to be
				## handled successfully
				split_commands = dec_data_blob[4: ].split(DATA_PARTIT_BYTE)
				strip_commands = [(cmd.rstrip('\r')).lstrip(' ') for cmd in split_commands]

				for command in strip_commands:
					self.Handle(command)
			else:
				if (raw_data_blob[0] == DATA_MARKER_BYTE):
					continue

				## strips leading spaces and trailing carriage return
				self.Handle((raw_data_blob.rstrip('\r')).lstrip(' '))

		self.socket_data = final_blob
예제 #3
0
	def HandleProtocolCommands(self, split_data, msg_limits):
		assert(type(split_data) == list)
		assert(type(split_data[-1]) == str)

		msg_length_limit = msg_limits['msglength']
		check_msg_limits = (not ('disabled' in msg_limits))

		## either a list of commands, or a list of encrypted data
		## blobs which may contain embedded (post-decryption) NLs
		##
		## note: will be empty if len(split_data) == 1
		raw_data_blobs = split_data[: len(split_data) - 1]

		## will be a single newline in most cases, or an incomplete
		## command which should be saved for a later time when more
		## data is in buffer
		self.data = split_data[-1]

		commands_buffer = []

		def check_message_timestamp(msg):
			ctr = str_to_int32(msg)

			if (ctr <= self.incoming_msg_ctr):
				return False

			self.incoming_msg_ctr = ctr
			return True

		for raw_data_blob in raw_data_blobs:
			if (len(raw_data_blob) == 0):
				continue

			if (self.use_secure_session()):
				dec_data_blob = decrypt_auth_message(self.aes_cipher_obj, raw_data_blob, self.use_msg_auth_codes())

				## can only happen in case of an invalid MAC or missing timestamp
				if (len(dec_data_blob) < 4):
					continue

				## handle an encrypted client command, using the AES session key
				## previously exchanged between client and server by SETSHAREDKEY
				## (this includes LOGIN and REGISTER, key can be set before login)
				##
				## this assumes (!) a client message to be of the form
				##   ENCODE(ENCRYPT_AES("CMD ARG1 ARG2 ...", AES_KEY))
				## where ENCODE is the standard base64 encoding scheme
				##
				## if this is not the case (e.g. if a command was sent UNENCRYPTED
				## by client after session-key exchange) the decryption will yield
				## garbage and command will be rejected
				##
				## NOTE:
				##   blocks of encrypted data are always base64-encoded and will be
				##   separated by newlines, but after decryption might contain more
				##   embedded newlines themselves (e.g. if encryption was performed
				##   over *batches* of plaintext commands)
				##
				##   client -->   C=ENCODE(ENCRYPT("CMD1 ARG11 ARG12 ...\nCMD2 ARG21 ...\n"))
				##   server --> DECRYPT(DECODE(C))="CMD1 ARG11 ARG12 ...\nCMD2 ARG21 ...\n"
				##
				## ignore any replayed messages
				if (not check_message_timestamp(dec_data_blob[0: 4])):
					continue

				split_commands = dec_data_blob[4: ].split(DATA_PARTIT_BYTE)
				strip_commands = [(cmd.rstrip('\r')).lstrip(' ') for cmd in split_commands]
			else:
				if (raw_data_blob[0] == DATA_MARKER_BYTE):
					continue

				## strips leading spaces and trailing carriage returns
				strip_commands = [(raw_data_blob.rstrip('\r')).lstrip(' ')]

			commands_buffer += strip_commands

		for command in commands_buffer:
			if (check_msg_limits and (len(command) > msg_length_limit)):
				self.Send('SERVERMSG message-length limit (%d) exceeded: command \"%s...\" dropped.' % (msg_length_limit, command[0: 8]))
			else:
				self.HandleProtocolCommand(command)