Ejemplo n.º 1
0
class Connection(object):
	def __init__(self, sock, addr):
		self.sock = sock
		self.addr = addr
		self.authenticated = False
		self.cs = None
		self.udpSocket = None
		self.udpAddr = None
		self.mute = False
		self.deaf = False
		print b"new connection from %s:%d" % (addr[0], addr[1])
		connections.append(self)
		self.session = connections.index(self) + 1
		stackless.tasklet(self.handle_connection)()

	def send_message(self, msg):
		type = MessageTypes.index(msg.__class__)
		if msg.__class__ != MumbleProto.Ping:
			print b">> " + str(msg.__class__)
			print msg
		length = msg.ByteSize()
		header = struct.pack(b"!hi", type, length)
		data = header + msg.SerializeToString()
		self.sock.send(data)

	def send_tunnel_message(self, msg):
		type = MessageTypes.index(MumbleProto.UDPTunnel)
		length = len(msg)
		header = struct.pack(b"!hi", type, length)
		data = header + b"".join(msg)
		self.sock.send(data)

	def send_all(self, msg):
		for i in connections:
			i.send_message(msg)

	def send_all_except_self(self, msg):
		for i in connections:
			if i == self: continue
			i.send_message(msg)

	def send_tunnel_all_except_self(self, msg):
		for i in connections:
			if i == self or i.deaf == True: continue
			i.send_tunnel_message(msg)

	def send_udp_message(self, msg):
		if not (self.cs and self.cs.isValid() and self.udpAddr):
			return
		msg = self.cs.encrypt(msg)
		self.udpSocket.sendto(msg, self.udpAddr)

	def handle_voice_msg(self, packet):
		udp_type = UDPMessageTypes[(ord(packet[0]) >> 5) & 0x7]
		type = ord(packet[0]) & 0xe0;
		target = ord(packet[0]) & 0x1f;
		data = b'\x00' * 1024
		pds = packetdatastream.PacketDataStream(data)
		# session
		pds.putInt(self.session)
		pds.appendDataBlock(packet[1:])
		size = pds.size()
		pds.rewind()
		data = []
		data.append(chr(type | 0))
		data.extend(pds.getDataBlock(size))
		self.send_tunnel_all_except_self(data)

	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)
Ejemplo n.º 2
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)