From 8043d686c5d7859edf3d93c63955964ae052b8e6 Mon Sep 17 00:00:00 2001 From: goeo_ Date: Sat, 22 Jul 2017 22:41:42 +0200 Subject: [PATCH 1/9] Fix all multi passwords being sent to each user in lobby --- constants/serverPackets.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/constants/serverPackets.py b/constants/serverPackets.py index 4756e8c..f8eb309 100644 --- a/constants/serverPackets.py +++ b/constants/serverPackets.py @@ -202,7 +202,9 @@ def createMatch(matchID): # Get match binary data and build packet match = glob.matches.matches[matchID] - return packetHelper.buildPacket(packetIDs.server_newMatch, match.getMatchData()) + matchData = match.getMatchData() + matchData.matchPassword = "" + return packetHelper.buildPacket(packetIDs.server_newMatch, matchData) # TODO: Add match object argument to save some CPU def updateMatch(matchID): From 76bb15f9f345553e545d34bb5a57629f758173dd Mon Sep 17 00:00:00 2001 From: goeo_ Date: Sun, 23 Jul 2017 02:35:29 +0200 Subject: [PATCH 2/9] Banned/Restricted people can't use the IRC gateway. Silenced people can't send messages on it. --- irc/ircserver.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/irc/ircserver.py b/irc/ircserver.py index 40a27e6..7d4ee36 100644 --- a/irc/ircserver.py +++ b/irc/ircserver.py @@ -310,6 +310,12 @@ class Client: self.reply("464 :Password incorrect") return + # Make sure that the user is not banned/restricted: + privileges = glob.db.fetch("SELECT privileges FROM users WHERE username = %s LIMIT 1", [self.supposedUsername] + if privileges & 3 != 3: + self.reply("465 :You're banned") + return + # Make sure we are not connected to Bancho token = glob.tokens.getTokenFromUsername(chat.fixUsernameForBancho(nick), True) if token is not None: @@ -466,6 +472,13 @@ class Client: recipientIRC = arguments[0] message = arguments[1] + # Check if the user is silenced + # TODO: Maybe don't run a sql query every time + silence_end = glob.db.fetch("SELECT silence_end FROM users WHERE username = %s LIMIT 1", [self.supposedUsername]) + if silence_end - int(time.time()) > 0: + self.reply("404 : You can't send messages.") + return + # Send the message to bancho and reply if not recipientIRC.startswith("#"): recipientBancho = chat.fixUsernameForBancho(recipientIRC) From 941cf818777b0b8a51e6ae8c5e3d18e48b42495c Mon Sep 17 00:00:00 2001 From: goeo_ Date: Sun, 23 Jul 2017 02:38:37 +0200 Subject: [PATCH 3/9] Parenthesis haha coding on windows sucks because the easiest way to test the code is to push the code then pull it from my dev server --- irc/ircserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc/ircserver.py b/irc/ircserver.py index 7d4ee36..371b318 100644 --- a/irc/ircserver.py +++ b/irc/ircserver.py @@ -311,7 +311,7 @@ class Client: return # Make sure that the user is not banned/restricted: - privileges = glob.db.fetch("SELECT privileges FROM users WHERE username = %s LIMIT 1", [self.supposedUsername] + privileges = glob.db.fetch("SELECT privileges FROM users WHERE username = %s LIMIT 1", [self.supposedUsername]) if privileges & 3 != 3: self.reply("465 :You're banned") return From 25df2228e3b4cf468d3d0ae8ea24a67143b13d36 Mon Sep 17 00:00:00 2001 From: goeo_ Date: Sun, 23 Jul 2017 02:58:47 +0200 Subject: [PATCH 4/9] Finally tested the code and it works now --- irc/ircserver.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/irc/ircserver.py b/irc/ircserver.py index 371b318..7c69ccf 100644 --- a/irc/ircserver.py +++ b/irc/ircserver.py @@ -311,7 +311,7 @@ class Client: return # Make sure that the user is not banned/restricted: - privileges = glob.db.fetch("SELECT privileges FROM users WHERE username = %s LIMIT 1", [self.supposedUsername]) + privileges = glob.db.fetch("SELECT privileges FROM users WHERE username = %s LIMIT 1", [self.supposedUsername])["privileges"] if privileges & 3 != 3: self.reply("465 :You're banned") return @@ -474,7 +474,7 @@ class Client: # Check if the user is silenced # TODO: Maybe don't run a sql query every time - silence_end = glob.db.fetch("SELECT silence_end FROM users WHERE username = %s LIMIT 1", [self.supposedUsername]) + silence_end = glob.db.fetch("SELECT silence_end FROM users WHERE username = %s LIMIT 1", [self.supposedUsername])["silence_end"] if silence_end - int(time.time()) > 0: self.reply("404 : You can't send messages.") return From c14c86fe0d0f3ee404a5d5bf5c30c46e6d00915b Mon Sep 17 00:00:00 2001 From: goeo_ Date: Sun, 23 Jul 2017 03:40:51 +0200 Subject: [PATCH 5/9] Fixed The Underscore Bug (i think) --- constants/fokabotCommands.py | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/constants/fokabotCommands.py b/constants/fokabotCommands.py index 85c0834..7cad3a8 100644 --- a/constants/fokabotCommands.py +++ b/constants/fokabotCommands.py @@ -84,9 +84,8 @@ def alert(fro, chan, message): return False def alertUser(fro, chan, message): - target = message[0].replace("_", " ") - - targetToken = glob.tokens.getTokenFromUsername(target) + target = message[0].lower() + targetToken = glob.tokens.getTokenFromUsername(target, safe=True) if targetToken is not None: targetToken.enqueue(serverPackets.notification(' '.join(message[1:]))) return False @@ -127,12 +126,12 @@ def kickAll(fro, chan, message): def kick(fro, chan, message): # Get parameters - target = message[0].lower().replace("_", " ") + target = message[0].lower() if target == "fokabot": return "Nope." # Get target token and make sure is connected - tokens = glob.tokens.getTokenFromUsername(target, _all=True) + tokens = glob.tokens.getTokenFromUsername(target, safe=True, _all=True) if len(tokens) == 0: return "{} is not online".format(target) @@ -155,13 +154,13 @@ def fokabotReconnect(fro, chan, message): def silence(fro, chan, message): for i in message: i = i.lower() - target = message[0].replace("_", " ") + target = message[0] amount = message[1] unit = message[2] reason = ' '.join(message[3:]) # Get target user ID - targetUserID = userUtils.getID(target) + targetUserID = userUtils.getIDSafe(target) userID = userUtils.getID(fro) # Make sure the user exists @@ -201,10 +200,10 @@ def removeSilence(fro, chan, message): # Get parameters for i in message: i = i.lower() - target = message[0].replace("_", " ") + target = message[0] # Make sure the user exists - targetUserID = userUtils.getID(target) + targetUserID = userUtils.getIDSafe(target) userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) @@ -224,10 +223,10 @@ def ban(fro, chan, message): # Get parameters for i in message: i = i.lower() - target = message[0].replace("_", " ") + target = message[0] # Make sure the user exists - targetUserID = userUtils.getID(target) + targetUserID = userUtils.getIDSafe(target) userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) @@ -247,10 +246,10 @@ def unban(fro, chan, message): # Get parameters for i in message: i = i.lower() - target = message[0].replace("_", " ") + target = message[0] # Make sure the user exists - targetUserID = userUtils.getID(target) + targetUserID = userUtils.getIDSafe(target) userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) @@ -265,10 +264,10 @@ def restrict(fro, chan, message): # Get parameters for i in message: i = i.lower() - target = message[0].replace("_", " ") + target = message[0] # Make sure the user exists - targetUserID = userUtils.getID(target) + targetUserID = userUtils.getIDSafe(target) userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) @@ -288,10 +287,10 @@ def unrestrict(fro, chan, message): # Get parameters for i in message: i = i.lower() - target = message[0].replace("_", " ") + target = message[0] # Make sure the user exists - targetUserID = userUtils.getID(target) + targetUserID = userUtils.getIDSafe(target) userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) From a177e65fcff875b133b94657dd7af1f1151543fe Mon Sep 17 00:00:00 2001 From: goeo_ Date: Sun, 23 Jul 2017 12:16:29 +0200 Subject: [PATCH 6/9] Silence check is already done in bancho; made the ban check look better weirdly, the original bug report said silenced people could talk using irc --- irc/ircserver.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/irc/ircserver.py b/irc/ircserver.py index 7c69ccf..2ff379c 100644 --- a/irc/ircserver.py +++ b/irc/ircserver.py @@ -17,6 +17,7 @@ import traceback import raven from common.log import logUtils as log +from common.ripple import userUtils from helpers import chatHelper as chat from objects import glob @@ -44,6 +45,7 @@ class Client: self.IRCUsername = "" self.banchoUsername = "" self.supposedUsername = "" + self.supposedUserID = 0 self.joinedChannels = [] def messageChannel(self, channel, command, message, includeSelf=False): @@ -280,9 +282,10 @@ class Client: m = hashlib.md5() m.update(arguments[0].encode("utf-8")) tokenHash = m.hexdigest() - supposedUsername = glob.db.fetch("SELECT users.username FROM users LEFT JOIN irc_tokens ON users.id = irc_tokens.userid WHERE irc_tokens.token = %s LIMIT 1", [tokenHash]) - if supposedUsername: - self.supposedUsername = chat.fixUsernameForIRC(supposedUsername["username"]) + supposedUser = glob.db.fetch("SELECT users.username, users.id FROM users LEFT JOIN irc_tokens ON users.id = irc_tokens.userid WHERE irc_tokens.token = %s LIMIT 1", [tokenHash]) + if supposedUser: + self.supposedUsername = chat.fixUsernameForIRC(supposedUser["username"]) + self.supposedUserID = supposedUser["id"] self.__handleCommand = self.registerHandler else: # Wrong IRC Token @@ -311,8 +314,7 @@ class Client: return # Make sure that the user is not banned/restricted: - privileges = glob.db.fetch("SELECT privileges FROM users WHERE username = %s LIMIT 1", [self.supposedUsername])["privileges"] - if privileges & 3 != 3: + if not userUtils.isAllowed(self.supposedUserID) self.reply("465 :You're banned") return @@ -472,13 +474,6 @@ class Client: recipientIRC = arguments[0] message = arguments[1] - # Check if the user is silenced - # TODO: Maybe don't run a sql query every time - silence_end = glob.db.fetch("SELECT silence_end FROM users WHERE username = %s LIMIT 1", [self.supposedUsername])["silence_end"] - if silence_end - int(time.time()) > 0: - self.reply("404 : You can't send messages.") - return - # Send the message to bancho and reply if not recipientIRC.startswith("#"): recipientBancho = chat.fixUsernameForBancho(recipientIRC) From f4d0a2424d20be798ce3cfbc26a71554f4de4032 Mon Sep 17 00:00:00 2001 From: goeo_ Date: Sun, 23 Jul 2017 12:17:57 +0200 Subject: [PATCH 7/9] .HIDE. I suck at coding does the hide tag even work lol --- irc/ircserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc/ircserver.py b/irc/ircserver.py index 2ff379c..92a1e22 100644 --- a/irc/ircserver.py +++ b/irc/ircserver.py @@ -314,7 +314,7 @@ class Client: return # Make sure that the user is not banned/restricted: - if not userUtils.isAllowed(self.supposedUserID) + if not userUtils.isAllowed(self.supposedUserID): self.reply("465 :You're banned") return From d43949002942418f49ab3c65ee28bb52ca31ef62 Mon Sep 17 00:00:00 2001 From: goeo_ Date: Sun, 23 Jul 2017 12:21:38 +0200 Subject: [PATCH 8/9] I should get a proper development environment --- irc/ircserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/irc/ircserver.py b/irc/ircserver.py index 92a1e22..863a4d3 100644 --- a/irc/ircserver.py +++ b/irc/ircserver.py @@ -45,7 +45,7 @@ class Client: self.IRCUsername = "" self.banchoUsername = "" self.supposedUsername = "" - self.supposedUserID = 0 + self.supposedUserID = 0 self.joinedChannels = [] def messageChannel(self, channel, command, message, includeSelf=False): From 401dd5ecdb8af41f1d8d942f59e61173a34ca6a9 Mon Sep 17 00:00:00 2001 From: goeo_ Date: Sun, 23 Jul 2017 14:37:12 -0400 Subject: [PATCH 9/9] Fix the multiplayer password bug while not breaking anything else, especially not multiplayer as a whole. (tested code) --- constants/serverPackets.py | 9 ++++----- objects/match.py | 22 +++++++++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/constants/serverPackets.py b/constants/serverPackets.py index f8eb309..101d0cd 100644 --- a/constants/serverPackets.py +++ b/constants/serverPackets.py @@ -202,19 +202,18 @@ def createMatch(matchID): # Get match binary data and build packet match = glob.matches.matches[matchID] - matchData = match.getMatchData() - matchData.matchPassword = "" + matchData = match.getMatchData(censored=True) return packetHelper.buildPacket(packetIDs.server_newMatch, matchData) # TODO: Add match object argument to save some CPU -def updateMatch(matchID): +def updateMatch(matchID, censored = False): # Make sure the match exists if matchID not in glob.matches.matches: return bytes() # Get match binary data and build packet match = glob.matches.matches[matchID] - return packetHelper.buildPacket(packetIDs.server_updateMatch, match.getMatchData()) + return packetHelper.buildPacket(packetIDs.server_updateMatch, match.getMatchData(censored=censored)) def matchStart(matchID): # Make sure the match exists @@ -271,4 +270,4 @@ def notification(message): return packetHelper.buildPacket(packetIDs.server_notification, [[message, dataTypes.STRING]]) def banchoRestart(msUntilReconnection): - return packetHelper.buildPacket(packetIDs.server_restart, [[msUntilReconnection, dataTypes.UINT32]]) \ No newline at end of file + return packetHelper.buildPacket(packetIDs.server_restart, [[msUntilReconnection, dataTypes.UINT32]]) diff --git a/objects/match.py b/objects/match.py index 796941e..f51eeeb 100644 --- a/objects/match.py +++ b/objects/match.py @@ -66,7 +66,7 @@ class match: # Create #multiplayer channel glob.channels.addTempChannel("#multi_{}".format(self.matchID)) - def getMatchData(self): + def getMatchData(self, censored = False): """ Return binary match data structure for packetHelper @@ -80,12 +80,18 @@ class match: [int(safeMatch.inProgress), dataTypes.BYTE], [0, dataTypes.BYTE], [safeMatch.mods, dataTypes.UINT32], - [safeMatch.matchName, dataTypes.STRING], - [safeMatch.matchPassword, dataTypes.STRING], + [safeMatch.matchName, dataTypes.STRING] + ] + if censored and safeMatch.matchPassword: + struct.append(["redacted", dataTypes.STRING]) + else: + struct.append([safeMatch.matchPassword, dataTypes.STRING]) + + struct.extend([ [safeMatch.beatmapName, dataTypes.STRING], [safeMatch.beatmapID, dataTypes.UINT32], - [safeMatch.beatmapMD5, dataTypes.STRING], - ] + [safeMatch.beatmapMD5, dataTypes.STRING] + ]) # Slots status IDs, always 16 elements for i in range(0,16): @@ -611,9 +617,11 @@ class match: :return: """ self.matchDataCache = serverPackets.updateMatch(self.matchID) + censoredDataCache = serverPackets.updateMatch(self.matchID, censored=True) if self.matchDataCache is not None: glob.streams.broadcast(self.streamName, self.matchDataCache) - glob.streams.broadcast("lobby", self.matchDataCache) + if censoredDataCache is not None: + glob.streams.broadcast("lobby", censoredDataCache) else: log.error("MPROOM{}: Can't send match update packet, match data is None!!!".format(self.matchID)) @@ -671,4 +679,4 @@ class match: glob.streams.broadcast(self.playingStreamName, serverPackets.matchStart(self.matchID)) # Send updates - self.sendUpdates() \ No newline at end of file + self.sendUpdates()