Ejemplo n.º 1
0
	def handle_connection(self):
		buf = ""
		buffer_length = 0
		while self.sock.connect:
			if buffer_length < HEADER_LENGTH:
				buf = self.sock.recv(4096)
				buffer_length = len(buf)

			if buffer_length < HEADER_LENGTH:
				break

			(msg_type, msg_length) = struct.unpack(b"!hi", buffer(buf, 0, HEADER_LENGTH))
			buf = buffer(buf, HEADER_LENGTH)
			buffer_length -= HEADER_LENGTH

			if buffer_length >= msg_length:
				packet = buffer(buf, 0, msg_length)
				buf = buffer(buf, msg_length)
				buffer_length -= msg_length
			else:
				packet = buf + self.sock.recv(msg_length - buffer_length)
				buf = ""
				buffer_length = 0

			msg = MessageTypes[msg_type]()

			if msg.__class__ != MumbleProto.UDPTunnel:
				msg.ParseFromString(packet)

			if msg.__class__ != MumbleProto.Ping and msg.__class__ != MumbleProto.UDPTunnel:
				print b"<< " + str(msg.__class__)
				print msg

			if msg.__class__ == MumbleProto.Ping:
				self.send_message(msg)

			if msg.__class__ == MumbleProto.Authenticate:
				self.username = msg.username

				error = False
				for i in connections:
					if i == self: continue
					if i.username == self.username:
						r = MumbleProto.Reject()
						r.type = MumbleProto.Reject.UsernameInUse
						self.send_message(r)
						error = True
						break

				if error == True: break

				self.authenticated = True
				r = MumbleProto.Version()
				r.version = (1 << 16 | 2 << 8 | 2 & 0xFF)
				r.release = b"Stackless Server 0.0.0.1"
				r.os = platform.system()
				r.os_version = sys.version
				self.send_message(r)

				self.cs = CryptState()
				key = random_bytes(16)
				cn = random_bytes(16)
				sn = random_bytes(16)
				self.cs.setKey(key, sn, cn)

				r = MumbleProto.CryptSetup()
				r.key = key
				r.client_nonce = cn
				r.server_nonce = sn
				self.send_message(r)

				r = MumbleProto.CodecVersion()
				r.alpha = r.beta = 0x8000000b
				r.prefer_alpha = False
				self.send_message(r)

				r = MumbleProto.ChannelState()
				r.channel_id = 0
				r.name = "Root"
				self.send_message(r)

				for i in connections:
					if i == self: continue
					r = MumbleProto.UserState()
					r.session = i.session
					r.name = i.username
					self.send_message(r)

				r = MumbleProto.UserState()
				r.session = self.session
				r.name = msg.username
				self.send_all(r)

				r = MumbleProto.ServerSync()
				r.session = self.session
				r.max_bandwidth = 240000
				r.permissions = permissions
				self.send_message(r)

			if msg.__class__ == MumbleProto.PermissionQuery:
				msg.permissions = permissions
				self.send_message(msg)

			if msg.__class__ == MumbleProto.TextMessage:
				msg.actor = self.session
				self.send_all_except_self(msg)

			if msg.__class__ == MumbleProto.UserState:
				msg.actor = self.session
				msg.session = self.session
				if msg.HasField(b"self_mute"):
					self.mute = msg.self_mute
				if msg.HasField(b"self_deaf"):
					self.deaf = msg.self_deaf
				self.send_all(msg)

			if msg.__class__ == MumbleProto.UDPTunnel:
				self.handle_voice_msg(packet)

			stackless.schedule()
		print b"Closing connection %s:%d" % (self.addr[0], self.addr[1])
		self.sock.close()
		connections.remove(self)

		if self.authenticated == True:
			r = MumbleProto.UserRemove()
			r.session = self.session
			self.send_all(r)