V5.2.4 multiple changes related to clones

This commit is contained in:
adator
2024-09-17 00:14:53 +02:00
parent c1c0b480ce
commit a7de16f7ad
6 changed files with 39 additions and 26 deletions

View File

@@ -414,6 +414,7 @@ class Clones:
nickname: str nickname: str
username: str username: str
realname: str realname: str
vhost: str = None
connected: bool = False connected: bool = False
UID_CLONE_DB: list[CloneModel] = [] UID_CLONE_DB: list[CloneModel] = []

View File

@@ -429,7 +429,7 @@ class Base:
except AssertionError as ae: except AssertionError as ae:
self.logs.error(f'Assertion Error -> {ae}') self.logs.error(f'Assertion Error -> {ae}')
def create_thread(self, func:object, func_args: tuple = (), run_once:bool = False) -> None: def create_thread(self, func:object, func_args: tuple = (), run_once:bool = False, daemon: bool = True) -> None:
"""Create a new thread and store it into running_threads variable """Create a new thread and store it into running_threads variable
Args: Args:
@@ -445,7 +445,7 @@ class Base:
if thread.getName() == func_name: if thread.getName() == func_name:
return None return None
th = threading.Thread(target=func, args=func_args, name=str(func_name), daemon=True) th = threading.Thread(target=func, args=func_args, name=str(func_name), daemon=daemon)
th.start() th.start()
self.running_threads.append(th) self.running_threads.append(th)

View File

@@ -15,7 +15,7 @@ class Connection:
self.nickname = nickname self.nickname = nickname
self.username = username self.username = username
self.realname = realname self.realname = realname
self.chanlog = '#clones' self.clone_chanlog = self.Config.SALON_CLONES
self.channels:list[str] = channels self.channels:list[str] = channels
self.CHARSET = ['utf-8', 'iso-8859-1'] self.CHARSET = ['utf-8', 'iso-8859-1']
self.Clones = CloneObject self.Clones = CloneObject
@@ -62,7 +62,7 @@ class Connection:
self.Base.logs.critical(f"AttributeError __create_socket: {ae} - {soc.fileno()}") self.Base.logs.critical(f"AttributeError __create_socket: {ae} - {soc.fileno()}")
return False return False
def send2socket(self, send_message:str) -> None: def send2socket(self, send_message:str, disconnect: bool = False) -> None:
"""Envoit les commandes à envoyer au serveur. """Envoit les commandes à envoyer au serveur.
Args: Args:
@@ -70,9 +70,8 @@ class Connection:
""" """
try: try:
with self.Base.lock: with self.Base.lock:
# print(f">{str(send_message)}")
self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0])) self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0]))
self.Base.logs.debug(f'{send_message}') self.Base.logs.debug(f'<<{self.currentCloneObject.nickname}>>: {send_message}')
except UnicodeDecodeError: except UnicodeDecodeError:
self.Base.logs.error(f'Decode Error try iso-8859-1 - message: {send_message}') self.Base.logs.error(f'Decode Error try iso-8859-1 - message: {send_message}')
@@ -114,7 +113,6 @@ class Connection:
def connect(self): def connect(self):
try: try:
while self.signal: while self.signal:
try: try:
# 4072 max what the socket can grab # 4072 max what the socket can grab
@@ -132,6 +130,7 @@ class Connection:
data = data_in_bytes.splitlines(True) data = data_in_bytes.splitlines(True)
if not data: if not data:
# If no data then quit the loop
break break
self.parser(data) self.parser(data)
@@ -145,10 +144,6 @@ class Connection:
self.Base.logs.error(f"OSError __connect_to_irc: {oe} - {data}") self.Base.logs.error(f"OSError __connect_to_irc: {oe} - {data}")
self.signal = False self.signal = False
self.IrcSocket.shutdown(socket.SHUT_RDWR)
self.IrcSocket.close()
self.Base.logs.info("--> Clone Disconnected ...")
except AssertionError as ae: except AssertionError as ae:
self.Base.logs.error(f'Assertion error : {ae}') self.Base.logs.error(f'Assertion error : {ae}')
except ValueError as ve: except ValueError as ve:
@@ -159,12 +154,17 @@ class Connection:
self.Base.logs.critical(f"{atte}") self.Base.logs.critical(f"{atte}")
except Exception as e: except Exception as e:
self.Base.logs.error(f"Exception: {e}") self.Base.logs.error(f"Exception: {e}")
finally:
self.IrcSocket.shutdown(socket.SHUT_WR)
self.IrcSocket.shutdown(socket.SHUT_RD)
self.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> Clone Disconnected ...")
# self.IrcSocket.close()
def parser(self, cmd:list[bytes]): def parser(self, cmd:list[bytes]):
try: try:
for data in cmd: for data in cmd:
response = data.decode(self.CHARSET[0]).split() response = data.decode(self.CHARSET[0]).split()
self.signal = self.currentCloneObject.alive
current_clone_nickname = self.currentCloneObject.nickname current_clone_nickname = self.currentCloneObject.nickname
# print(response) # print(response)
@@ -176,7 +176,8 @@ class Connection:
case 'ERROR': case 'ERROR':
error_value = str(response[1]).replace(':','') error_value = str(response[1]).replace(':','')
if error_value == 'Closing': if error_value == 'Closing':
self.signal = False self.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> {response} ...")
# self.signal = False
match response[1]: match response[1]:
case '376': case '376':
@@ -184,17 +185,22 @@ class Connection:
self.currentCloneObject.connected = True self.currentCloneObject.connected = True
for channel in self.channels: for channel in self.channels:
self.send2socket(f"JOIN {channel}") self.send2socket(f"JOIN {channel}")
self.send2socket(f"JOIN {self.clone_chanlog}")
return None return None
case '422': case '422':
# Missing MOTD # Missing MOTD
self.currentCloneObject.connected = True self.currentCloneObject.connected = True
for channel in self.channels: for channel in self.channels:
self.send2socket(f"JOIN {channel}") self.send2socket(f"JOIN {channel}")
self.send2socket(f"JOIN {self.clone_chanlog}")
return None return None
case 'PRIVMSG': case 'PRIVMSG':
self.Base.logs.debug(response) self.Base.logs.debug(f'<<{self.currentCloneObject.nickname}>> Response: {response}')
self.Base.logs.debug(f'{self.currentCloneObject.nickname} - {self.currentCloneObject.alive}') self.Base.logs.debug(f'<<{self.currentCloneObject.nickname}>> Alive: {self.currentCloneObject.alive}')
fullname = str(response[0]).replace(':', '') fullname = str(response[0]).replace(':', '')
nickname = fullname.split('!')[0].replace(':','') nickname = fullname.split('!')[0].replace(':','')
@@ -203,14 +209,13 @@ class Connection:
for i in range(3, len(response)): for i in range(3, len(response)):
message.append(response[i]) message.append(response[i])
final_message = ' '.join(message) final_message = ' '.join(message)
self.send2socket(f"PRIVMSG {self.chanlog} :{fullname} => {final_message[1:]}") self.send2socket(f"PRIVMSG {self.clone_chanlog} :{fullname} => {final_message[1:]}")
if nickname == self.Config.SERVICE_NICKNAME: if nickname == self.Config.SERVICE_NICKNAME:
command = str(response[3]).replace(':','') command = str(response[3]).replace(':','')
if command == 'KILL': if command == 'KILL':
self.send2socket(f'QUIT :Thanks and goodbye') self.send2socket(f'QUIT :Thanks and goodbye', disconnect=True)
self.signal = self.currentCloneObject.alive
if command == 'JOIN': if command == 'JOIN':
channel_to_join = str(response[4]) channel_to_join = str(response[4])

View File

@@ -82,6 +82,9 @@ class ConfigDataModel:
SALON_LIBERER: str SALON_LIBERER: str
"""Channel where the nickname will be released""" """Channel where the nickname will be released"""
SALON_CLONES: str
"""Channel to host clones"""
API_TIMEOUT: int API_TIMEOUT: int
"""Default api timeout in second""" """Default api timeout in second"""
@@ -184,6 +187,7 @@ class Config:
SALON_JAIL=import_config["SALON_JAIL"], SALON_JAIL=import_config["SALON_JAIL"],
SALON_JAIL_MODES=import_config["SALON_JAIL_MODES"], SALON_JAIL_MODES=import_config["SALON_JAIL_MODES"],
SALON_LIBERER=import_config["SALON_LIBERER"], SALON_LIBERER=import_config["SALON_LIBERER"],
SALON_CLONES=import_config["SALON_CLONES"],
API_TIMEOUT=import_config["API_TIMEOUT"], API_TIMEOUT=import_config["API_TIMEOUT"],
PORTS_TO_SCAN=import_config["PORTS_TO_SCAN"], PORTS_TO_SCAN=import_config["PORTS_TO_SCAN"],
WHITELISTED_IP=import_config["WHITELISTED_IP"], WHITELISTED_IP=import_config["WHITELISTED_IP"],

View File

@@ -126,6 +126,9 @@ class Clone():
fake = faker.Faker('en_GB') fake = faker.Faker('en_GB')
for clone in self.Clone.UID_CLONE_DB: for clone in self.Clone.UID_CLONE_DB:
if not clone.vhost is None:
continue
rand_1 = fake.random_elements(['A','B','C','D','E','F','0','1','2','3','4','5','6','7','8','9'], unique=True, length=8) rand_1 = fake.random_elements(['A','B','C','D','E','F','0','1','2','3','4','5','6','7','8','9'], unique=True, length=8)
rand_2 = fake.random_elements(['A','B','C','D','E','F','0','1','2','3','4','5','6','7','8','9'], unique=True, length=8) rand_2 = fake.random_elements(['A','B','C','D','E','F','0','1','2','3','4','5','6','7','8','9'], unique=True, length=8)
rand_3 = fake.random_elements(['A','B','C','D','E','F','0','1','2','3','4','5','6','7','8','9'], unique=True, length=8) rand_3 = fake.random_elements(['A','B','C','D','E','F','0','1','2','3','4','5','6','7','8','9'], unique=True, length=8)
@@ -137,6 +140,7 @@ class Clone():
if clone.connected: if clone.connected:
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} CHGHOST {clone.nickname} {rand_ip}') self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} CHGHOST {clone.nickname} {rand_ip}')
found = True found = True
clone.vhost = rand_ip
break break
def thread_create_clones(self, nickname: str, username: str, realname: str, channels: list, server_port: int, ssl: bool) -> None: def thread_create_clones(self, nickname: str, username: str, realname: str, channels: list, server_port: int, ssl: bool) -> None:
@@ -146,16 +150,16 @@ class Clone():
return None return None
def thread_join_channels(self, channel_name: str, wait: float, clone_name:str = None): def thread_join_channels(self, channel_name: str, wait: float, clone_name:str = None):
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Clones start to join {channel_name} with {wait} secondes frequency')
if clone_name is None: if clone_name is None:
for clone in self.Clone.UID_CLONE_DB: for clone in self.Clone.UID_CLONE_DB:
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone.nickname} :JOIN {channel_name}')
time.sleep(wait) time.sleep(wait)
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone.nickname} :JOIN {channel_name}')
else: else:
for clone in self.Clone.UID_CLONE_DB: for clone in self.Clone.UID_CLONE_DB:
if clone_name == clone.nickname: if clone_name == clone.nickname:
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone.nickname} :JOIN {channel_name}')
time.sleep(wait) time.sleep(wait)
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone.nickname} :JOIN {channel_name}')
def generate_names(self) -> tuple[str, str, str]: def generate_names(self) -> tuple[str, str, str]:
try: try:
@@ -237,12 +241,11 @@ class Clone():
nickname, username, realname = self.generate_names() nickname, username, realname = self.generate_names()
self.Base.create_thread( self.Base.create_thread(
self.thread_create_clones, self.thread_create_clones,
(nickname, username, realname, ['#clones'], 6697, True) (nickname, username, realname, [], 6697, True)
) )
self.Base.create_thread( self.Base.create_thread(
self.thread_change_hostname, self.thread_change_hostname
run_once=True
) )
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :{str(number_of_clones)} clones joined the network') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :{str(number_of_clones)} clones joined the network')

View File

@@ -1,3 +1,3 @@
{ {
"version": "5.2.3" "version": "5.2.4"
} }