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