From bdea06d4d42ce37ebe19d947f88a87c015aa5042 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 24 May 2021 12:38:12 +0100 Subject: [PATCH] Remove imposters during identify --- README.md | 6 ++++++ miniircd | 29 +++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 91f6544..dc52498 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,10 @@ To identify yourself connect with your previous nick, then: The first account to be registered gets oper status. Note that this applies for all channels. +If there is an imposter occupying your usual nickname then you can identify yourself with your full credentials, and the imposter will be removed. + + /identify [nickname] [password] + A passwords file in the state directory contains password hashes. The word "oper" is appended to any accounts with oper status. To subsequently change password: @@ -176,6 +180,8 @@ To set the allowed number of new registrations: /newreg [number] +So if you encounter a spam flood then you can allow only registered users on channels and set the new registrations temporarily to zero. + License ------- diff --git a/miniircd b/miniircd index 0e76bd3..4bf4a72 100755 --- a/miniircd +++ b/miniircd @@ -511,16 +511,15 @@ class Client: self.server.new_registrations -= 1 return True - def __msg_nickserv_identify(self, password: str) -> bool: - identify_nick = self.nickname.decode('utf-8') - salt = self.__get_salt(identify_nick) + def __msg_nickserv_identify(self, nickname: str, password: str) -> bool: + salt = self.__get_salt(nickname) if not salt: self.reply(b"406 %s :Not registered" % self.nickname) self.is_operator = False self.is_registered = False return False hashed_password = self.__hash_password(salt, password) - retval = self.__identify(identify_nick, salt, hashed_password) + retval = self.__identify(nickname, salt, hashed_password) if retval > 0: self.is_registered = True if retval > 1: @@ -530,6 +529,8 @@ class Client: self.is_registered = False self.reply(b"401 %s :No such nick" % self.nickname) return False + else: + self.server.remove_imposters(self.nickname, nickname) return True def __command_handler( @@ -979,8 +980,13 @@ class Client: self.is_operator = False self.is_registered = False return - password = arguments[0].decode('utf-8') - if self.__msg_nickserv_identify(password): + if len(arguments) == 2: + nickname = arguments[0].decode('utf-8') + password = arguments[1].decode('utf-8') + else: + nickname = self.nickname.decode('utf-8') + password = arguments[-1].decode('utf-8') + if self.__msg_nickserv_identify(nickname, password): self.message((f"Identify success").encode()) else: self.message((f"Identify failed").encode()) @@ -1451,6 +1457,17 @@ class Server: except BaseException: pass + def remove_imposters(curr_nickname: str, true_nickname: str) -> None: + if curr_nickname == true_nickname: + return + imposter = self.get_client(true_nickname) + if imposter: + genuine = self.get_client(curr_nickname) + if genuine: + self.remove_client(imposter, b'imposter') + genuine.nickname = true_nickname + self.client_changed_nickname(genuine, curr_nickname) + def update_bouncer(self, line: bytes) -> None: self.bouncer.append(line) while len(self.bouncer) >= self.bouncer_size: