37 Commits

Author SHA1 Message Date
adator
e14c97de03 Merge pull request #44 from adator85/dev
V5.3.0
2024-09-22 16:20:45 +02:00
adator
ff603ab2a4 V5.3.0 2024-09-22 16:20:02 +02:00
adator
69360be3ad Merge pull request #43 from adator85/dev
Update info command
2024-09-21 20:28:29 +02:00
adator
d7503768b6 Update info command 2024-09-21 20:28:02 +02:00
adator
bfa90c6bd5 Merge pull request #42 from adator85/dev
V5.2.9
2024-09-21 20:22:42 +02:00
adator
b5503d23d7 V5.2.9 2024-09-21 20:22:09 +02:00
adator
5c8378a0e7 Merge pull request #41 from adator85/dev
V5.2.9
2024-09-21 16:43:14 +02:00
adator
7be3f51bf4 V5.2.9 2024-09-21 16:28:50 +02:00
adator
e3b212ea88 Merge pull request #40 from adator85/dev
finetune clone connection
2024-09-20 23:13:33 +02:00
adator
2c0510b2a3 finetune clone connection 2024-09-20 23:12:57 +02:00
adator
0c2a350d38 Merge pull request #39 from adator85/dev
Dev
2024-09-20 21:12:59 +02:00
adator
ee039322d4 V5.2.7 2024-09-19 21:06:07 +02:00
adator
8f08a1e77f update readme.md 2024-09-18 20:29:33 +02:00
adator
c59dd16e87 V5.2.6 2024-09-18 20:21:44 +02:00
adator
1cea8d0601 Merge pull request #38 from adator85/dev
V5.2.1
2024-09-15 03:09:22 +02:00
adator
652b400d5e Merge pull request #37 from adator85/dev
update mode clone
2024-09-15 02:50:27 +02:00
adator
2f8b965b59 Merge pull request #36 from adator85/dev
Dev
2024-09-15 02:04:32 +02:00
adator
3c043cefd8 Merge pull request #35 from adator85/dev
V5.1.8
2024-09-08 00:42:57 +02:00
adator
59a75cecd8 Merge pull request #34 from adator85/dev
V5.1.7
2024-09-03 00:21:32 +02:00
adator
71053437a7 Merge pull request #33 from adator85/dev
V5.1.6
2024-09-01 22:15:54 +02:00
adator
7796d05206 Merge pull request #32 from adator85/dev
Update vote kick commands
2024-09-01 18:55:57 +02:00
adator
5f2567f9e5 Merge pull request #31 from adator85/dev
mod_command update
2024-09-01 17:30:05 +02:00
adator
aaa1dd9a1a Merge pull request #30 from adator85/dev
adding Say command for clones
2024-09-01 16:40:25 +02:00
adator
a02f2f9a26 Merge pull request #29 from adator85/dev
update mod_clone module
2024-09-01 15:54:50 +02:00
adator
d73adb6f0b Merge pull request #28 from adator85/dev
update readme
2024-09-01 15:35:59 +02:00
adator
b812e64992 Merge pull request #27 from adator85/dev
Dev
2024-09-01 15:24:18 +02:00
adator
9bd1f68df2 Merge pull request #26 from adator85/dev
Dev
2024-09-01 14:59:38 +02:00
adator
f44b08bf36 Merge pull request #25 from adator85/dev
fix Installation
2024-08-29 01:36:38 +02:00
adator
1a19e1613a Merge pull request #24 from adator85/dev
Fix Bug installation
2024-08-29 01:31:19 +02:00
adator
cdc15b7b47 Merge pull request #23 from adator85/dev
Dev
2024-08-29 01:16:55 +02:00
adator
31fe9f62ec Merge pull request #22 from adator85/dev
Dev
2024-08-24 01:39:11 +02:00
adator
f0853e3afb Merge pull request #21 from adator85/dev
New Installation file created for unix system
2024-08-22 01:02:00 +02:00
adator
6dade09257 Merge pull request #20 from adator85/dev
README Update
2024-08-21 00:50:31 +02:00
adator
9533b010b2 Merge pull request #19 from adator85/dev
V5.0.4 - Delete a user when a user has been kicked
2024-08-20 02:24:37 +02:00
adator
824db73590 Merge pull request #18 from adator85/dev
Delete channel mode information
2024-08-20 02:14:31 +02:00
adator
96bf4b6f80 Merge pull request #17 from adator85/dev
Fix channel update
2024-08-20 02:08:09 +02:00
adator
922336363e Merge pull request #16 from adator85/dev
Dev
2024-08-20 01:56:04 +02:00
11 changed files with 394 additions and 187 deletions

View File

@@ -102,8 +102,6 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
DEBUG (Debug) DEBUG (Debug)
DEBUG_LEVEL: Niveau de verbosité des messages de debug (plus grand est le nombre, plus il y a d'informations). (default : 20) Pour une production DEBUG_LEVEL: Niveau de verbosité des messages de debug (plus grand est le nombre, plus il y a d'informations). (default : 20) Pour une production
COULEURS (Couleurs)
CONFIG_COLOR: Dictionnaire contenant des codes de couleurs IRC pour un meilleur affichage des messages.
``` ```
Modification de la configuration Modification de la configuration
@@ -121,24 +119,14 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
"SERVEUR_SSL": true, "SERVEUR_SSL": true,
"SERVICE_NAME": "defender", "SERVICE_NAME": "defender",
"SERVICE_NICKNAME": "Dev-PyDefender", "SERVICE_NICKNAME": "PyDefender",
"SERVICE_REALNAME": "Python Defender Security", "SERVICE_REALNAME": "Python Defender Security",
"SERVICE_USERNAME": "Dev-PyDefender", "SERVICE_USERNAME": "PyDefender",
"SERVICE_HOST": "HOST.DE.TON.DEFENDER", "SERVICE_HOST": "HOST.DE.TON.DEFENDER",
"OWNER": "TON_NICK_NAME", "OWNER": "TON_NICK_NAME",
"PASSWORD": "admin", "PASSWORD": "TON_PASSWORD"
"CONFIG_COLOR": {
"blanche": "\\u0003\\u0030",
"noire": "\\u0003\\u0031",
"bleue": "\\u0003\\u0020",
"verte": "\\u0003\\u0033",
"rouge": "\\u0003\\u0034",
"jaune": "\\u0003\\u0036",
"gras": "\\u0002",
"nogc": "\\u0002\\u0003"
}
} }
``` ```
@@ -147,17 +135,17 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
```json ```json
{ {
"SERVEUR_IP": "YOUR.SERVER.IP", "SERVEUR_IP": "YOUR.SERVER.IP",
"SERVEUR_HOSTNAME": "irc.deb.biz.st", "SERVEUR_HOSTNAME": "YOUR.SERVER.HOST",
"SERVEUR_LINK": "defenderdev.deb.biz.st", "SERVEUR_LINK": "LINK.DE.TON.SERVER",
"SERVEUR_PORT": 6901, "SERVEUR_PORT": 6901,
"SERVEUR_PASSWORD": "yourpassword", "SERVEUR_PASSWORD": "YOUR_LINK_PASSWORD",
"SERVEUR_ID": "10Z", "SERVEUR_ID": "10Z",
"SERVEUR_SSL": true, "SERVEUR_SSL": true,
"SERVICE_NAME": "defender", "SERVICE_NAME": "defender",
"SERVICE_NICKNAME": "Dev-PyDefender", "SERVICE_NICKNAME": "PyDefender",
"SERVICE_REALNAME": "Python Defender Security", "SERVICE_REALNAME": "Python Defender Security",
"SERVICE_USERNAME": "Dev-PyDefender", "SERVICE_USERNAME": "PyDefender",
"SERVICE_HOST": "HOST.DE.TON.DEFENDER", "SERVICE_HOST": "HOST.DE.TON.DEFENDER",
"SERVICE_INFO": "Network IRC Service", "SERVICE_INFO": "Network IRC Service",
"SERVICE_CHANLOG": "#services", "SERVICE_CHANLOG": "#services",
@@ -167,13 +155,16 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
"SERVICE_PREFIX": "!", "SERVICE_PREFIX": "!",
"OWNER": "TON_NICK_NAME", "OWNER": "TON_NICK_NAME",
"PASSWORD": "admin", "PASSWORD": "TON_PASSWORD",
"SALON_JAIL": "#jail", "SALON_JAIL": "#jail",
"SALON_JAIL_MODES": "sS", "SALON_JAIL_MODES": "sS",
"SALON_LIBERER": "#welcome", "SALON_LIBERER": "#welcome",
"SALON_CLONES": "#clones", "CLONE_CHANNEL": "#clones",
"CLONE_CMODES": "+nts",
"CLONE_LOG_HOST_EXEMPT": ["HOST.TO.SKIP"],
"CLONE_CHANNEL_PASSWORD": "YOUR_CHANNEL_PASSWORD",
"API_TIMEOUT": 2, "API_TIMEOUT": 2,
@@ -181,18 +172,7 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
"WHITELISTED_IP": ["127.0.0.1"], "WHITELISTED_IP": ["127.0.0.1"],
"GLINE_DURATION": "30", "GLINE_DURATION": "30",
"DEBUG_LEVEL": 10, "DEBUG_LEVEL": 20
"CONFIG_COLOR": {
"blanche": "\\u0003\\u0030",
"noire": "\\u0003\\u0031",
"bleue": "\\u0003\\u0020",
"verte": "\\u0003\\u0033",
"rouge": "\\u0003\\u0034",
"jaune": "\\u0003\\u0036",
"gras": "\\u0002",
"nogc": "\\u0002\\u0003"
}
} }
``` ```
@@ -201,10 +181,46 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
Le mot de passe de l'administrateur et le mot de passe du service doivent être modifiés pour des raisons de sécurité. Le mot de passe de l'administrateur et le mot de passe du service doivent être modifiés pour des raisons de sécurité.
Ne partagez pas vos informations de connexion au serveur IRC avec des tiers. Ne partagez pas vos informations de connexion au serveur IRC avec des tiers.
a votre premiere connexion vous devez tapez a votre premiere connexion vous devez tapez
```
/msg [NomDuService] auth [nickname] [password]
-- Une fois identifié tapez la commande suivante
/msg [NomDuService] editaccess [nickname] [Nouveau-Password] 5
```
# Unrealircd configuration
```
listen {
ip *;
port 6901;
options { tls; serversonly; }
}
/msg [NomDuService] auth [nickname] [password] link LINK.DE.TON.SERVER
-- Une fois identifié tapez la commande suivante {
/msg [NomDuService] editaccess [nickname] [Nouveau-Password] 5
incoming {
mask *;
bind-ip *;
port 6901;
//options { tls; };
}
outgoing {
bind-ip *; /* ou une IP précise */
hostname LINK.DE.TON.SERVER;
port 6901;
//options { tls; }
}
password "YOUR_LINK_PASSWORD";
class servers;
}
ulines {
LINK.DE.TON.SERVER;
}
```
# Extension: # Extension:
Le code est modulaire et conçu pour être facilement étendu. Vous pouvez ajouter de nouvelles commandes, de nouvelles fonctionnalités (mods/mod_test.py est un exemple pour bien demarrer la création de son module). Le code est modulaire et conçu pour être facilement étendu. Vous pouvez ajouter de nouvelles commandes, de nouvelles fonctionnalités (mods/mod_test.py est un exemple pour bien demarrer la création de son module).

View File

@@ -416,6 +416,7 @@ class Clones:
realname: str realname: str
channels: list channels: list
vhost: str = None vhost: str = None
init: bool = True
connected: bool = False connected: bool = False
UID_CLONE_DB: list[CloneModel] = [] UID_CLONE_DB: list[CloneModel] = []

View File

@@ -26,8 +26,6 @@ class Base:
self.engine, self.cursor = self.db_init() # Initialisation de la connexion a la base de données self.engine, self.cursor = self.db_init() # Initialisation de la connexion a la base de données
self.__create_db() # Initialisation de la base de données self.__create_db() # Initialisation de la base de données
self.db_create_first_admin() # Créer un nouvel admin si la base de données est vide
def __set_current_defender_version(self) -> None: def __set_current_defender_version(self) -> None:
"""This will put the current version of Defender """This will put the current version of Defender
located in version.json located in version.json

View File

@@ -1,4 +1,6 @@
import socket, ssl import socket
import ssl
import traceback
from ssl import SSLSocket from ssl import SSLSocket
from core.loadConf import Config from core.loadConf import Config
from core.Model import Clones from core.Model import Clones
@@ -15,7 +17,8 @@ class Connection:
self.nickname = nickname self.nickname = nickname
self.username = username self.username = username
self.realname = realname self.realname = realname
self.clone_chanlog = self.Config.SALON_CLONES self.clone_chanlog = self.Config.CLONE_CHANNEL
self.clone_log_exempt = self.Config.CLONE_LOG_HOST_EXEMPT
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
@@ -144,6 +147,11 @@ 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_WR)
self.IrcSocket.shutdown(socket.SHUT_RD)
self.currentCloneObject.init = False
self.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> 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:
@@ -152,13 +160,9 @@ class Connection:
self.Base.logs.error(f"OS Error __connect_to_irc: {soe}") self.Base.logs.error(f"OS Error __connect_to_irc: {soe}")
except AttributeError as atte: except AttributeError as atte:
self.Base.logs.critical(f"{atte}") self.Base.logs.critical(f"{atte}")
self.Base.logs.critical(f"{traceback.format_exc()}")
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:
@@ -176,6 +180,9 @@ 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.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> {response} ...")
self.currentCloneObject.connected = False
else:
self.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> {response} ...") self.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> {response} ...")
# self.signal = False # self.signal = False
@@ -183,19 +190,30 @@ class Connection:
case '376': case '376':
# End of MOTD # End of MOTD
self.currentCloneObject.connected = True self.currentCloneObject.connected = True
self.currentCloneObject.init = False
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}") self.send2socket(f"JOIN {self.clone_chanlog} {self.Config.CLONE_CHANNEL_PASSWORD}")
return None return None
case '422': case '422':
# Missing MOTD # Missing MOTD
self.currentCloneObject.connected = True self.currentCloneObject.connected = True
self.currentCloneObject.init = False
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}") self.send2socket(f"JOIN {self.clone_chanlog} {self.Config.CLONE_CHANNEL_PASSWORD}")
return None
case '433':
# Nickname already in use
self.currentCloneObject.connected = False
self.currentCloneObject.init = False
self.send2socket(f'QUIT :Thanks and goodbye')
self.Base.logs.warning(f"Nickname {self.currentCloneObject.nickname} already in use >> Clone should be disconnected")
return None return None
case 'PRIVMSG': case 'PRIVMSG':
@@ -209,13 +227,20 @@ 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.clone_chanlog} :{fullname} => {final_message[1:]}")
exampt = False
for log_exception in self.clone_log_exempt:
if log_exception in fullname:
exampt = True
if not exampt:
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', disconnect=True) self.send2socket(f'QUIT :Thanks and goodbye')
if command == 'JOIN': if command == 'JOIN':
channel_to_join = str(response[4]) channel_to_join = str(response[4])

View File

@@ -1,48 +1,42 @@
{ {
"SERVEUR_IP": "0.0.0.0", "SERVEUR_IP": "YOUR.SERVER.IP",
"SERVEUR_HOSTNAME": "your.host.name", "SERVEUR_HOSTNAME": "YOUR.SERVER.HOST",
"SERVEUR_LINK": "your.link.to.server", "SERVEUR_LINK": "LINK.DE.TON.SERVER",
"SERVEUR_PORT": 7002, "SERVEUR_PORT": 7002,
"SERVEUR_PASSWORD": "link_password", "SERVEUR_PASSWORD": "YOUR_LINK_PASSWORD",
"SERVEUR_ID": "006", "SERVEUR_ID": "006",
"SERVEUR_SSL": true, "SERVEUR_SSL": true,
"SERVICE_NAME": "defender", "SERVICE_NAME": "defender",
"SERVICE_NICKNAME": "BotNickname", "SERVICE_NICKNAME": "PyDefender",
"SERVICE_REALNAME": "BotRealname", "SERVICE_REALNAME": "Python Defender Security",
"SERVICE_USERNAME": "BotUsername", "SERVICE_USERNAME": "PyDefender",
"SERVICE_HOST": "your.service.hostname", "SERVICE_HOST": "HOST.DE.TON.DEFENDER",
"SERVICE_INFO": "Network IRC Service", "SERVICE_INFO": "Network IRC Service",
"SERVICE_CHANLOG": "#services", "SERVICE_CHANLOG": "#services",
"SERVICE_SMODES": "+ioqBS", "SERVICE_SMODES": "+ioqBS",
"SERVICE_CMODES": "ntsO", "SERVICE_CMODES": "ntsOP",
"SERVICE_UMODES": "o", "SERVICE_UMODES": "o",
"SERVICE_PREFIX": "!", "SERVICE_PREFIX": "!",
"OWNER": "admin", "OWNER": "TON_NICK_NAME",
"PASSWORD": "password", "PASSWORD": "TON_PASSWORD",
"SALON_JAIL": "#jail", "SALON_JAIL": "#jail",
"SALON_JAIL_MODES": "sS", "SALON_JAIL_MODES": "sS",
"SALON_LIBERER": "#welcome", "SALON_LIBERER": "#welcome",
"CLONE_CHANNEL": "#clones",
"CLONE_CMODES": "+nts",
"CLONE_LOG_HOST_EXEMPT": ["HOST.TO.SKIP"],
"CLONE_CHANNEL_PASSWORD": "YOUR_CHANNEL_PASSWORD",
"API_TIMEOUT": 2, "API_TIMEOUT": 2,
"PORTS_TO_SCAN": [3028, 8080, 1080, 1085, 4145, 9050], "PORTS_TO_SCAN": [3028, 8080, 1080, 1085, 4145, 9050],
"WHITELISTED_IP": ["127.0.0.1"], "WHITELISTED_IP": ["127.0.0.1"],
"GLINE_DURATION": "30", "GLINE_DURATION": "30",
"DEBUG_LEVEL": 20, "DEBUG_LEVEL": 20
"CONFIG_COLOR": {
"blanche": "\\u0003\\u0030",
"noire": "\\u0003\\u0031",
"bleue": "\\u0003\\u0020",
"verte": "\\u0003\\u0033",
"rouge": "\\u0003\\u0034",
"jaune": "\\u0003\\u0036",
"gras": "\\u0002",
"nogc": "\\u0002\\u0003"
}
} }

View File

@@ -29,7 +29,7 @@ class Irc:
# Liste des commandes internes du bot # Liste des commandes internes du bot
self.commands_level = { self.commands_level = {
0: ['help', 'auth', 'copyright', 'uptime'], 0: ['help', 'auth', 'copyright', 'uptime', 'firstauth'],
1: ['load','reload','unload', 'deauth', 'checkversion'], 1: ['load','reload','unload', 'deauth', 'checkversion'],
2: ['show_modules', 'show_timers', 'show_threads', 'show_channels', 'show_users', 'show_admins'], 2: ['show_modules', 'show_timers', 'show_threads', 'show_channels', 'show_users', 'show_admins'],
3: ['quit', 'restart','addaccess','editaccess', 'delaccess'] 3: ['quit', 'restart','addaccess','editaccess', 'delaccess']
@@ -175,8 +175,8 @@ class Irc:
except AttributeError as atte: except AttributeError as atte:
self.Base.logs.critical(f"AttributeError: {atte}") self.Base.logs.critical(f"AttributeError: {atte}")
except Exception as e: except Exception as e:
self.Base.logs.critical(f"Exception: {e}") self.Base.logs.critical(f"General Error: {e}")
self.Base.logs.critical(traceback.print_exc()) self.Base.logs.critical(traceback.format_exc())
def __link(self, writer:Union[socket.socket, SSLSocket]) -> None: def __link(self, writer:Union[socket.socket, SSLSocket]) -> None:
"""Créer le link et envoyer les informations nécessaires pour la """Créer le link et envoyer les informations nécessaires pour la
@@ -222,7 +222,7 @@ class Irc:
writer.send(f":{service_id} MODE {chan} +{cmodes}\r\n".encode(charset)) writer.send(f":{service_id} MODE {chan} +{cmodes}\r\n".encode(charset))
writer.send(f":{service_id} MODE {chan} +{umodes} {service_id}\r\n".encode(charset)) writer.send(f":{service_id} MODE {chan} +{umodes} {service_id}\r\n".encode(charset))
self.Base.logs.debug('Link information sent to the server') self.Base.logs.debug('>> Link information sent to the server')
return None return None
except AttributeError as ae: except AttributeError as ae:
@@ -249,7 +249,6 @@ class Irc:
""" """
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'{send_message}')
@@ -268,6 +267,41 @@ class Irc:
except OSError as oe: except OSError as oe:
self.Base.logs.error(f"OSError: {oe} - {send_message}") self.Base.logs.error(f"OSError: {oe} - {send_message}")
def sendNotice(self, msg:str, nickname: str) -> None:
"""Sending NOTICE by batches
Args:
msg (str): The message to send to the server
nickname (str): The reciever Nickname
"""
batch_size = self.Config.BATCH_SIZE
service_nickname = self.Config.SERVICE_NICKNAME
for i in range(0, len(str(msg)), batch_size):
batch = str(msg)[i:i+batch_size]
self.send2socket(f":{service_nickname} NOTICE {nickname} :{batch}")
def sendPrivMsg(self, msg: str, channel: str = None, nickname: str = None):
"""Sending PRIVMSG to a channel or to a nickname by batches
could be either channel or nickname not both together
Args:
msg (str): The message to send
channel (str, optional): The receiver channel. Defaults to None.
nickname (str, optional): The reciever nickname. Defaults to None.
"""
batch_size = self.Config.BATCH_SIZE
service_nickname = self.Config.SERVICE_NICKNAME
if not channel is None:
for i in range(0, len(str(msg)), batch_size):
batch = str(msg)[i:i+batch_size]
self.send2socket(f":{service_nickname} PRIVMSG {channel} :{batch}")
if not nickname is None:
for i in range(0, len(str(msg)), batch_size):
batch = str(msg)[i:i+batch_size]
self.send2socket(f":{service_nickname} PRIVMSG {nickname} :{batch}")
def send_response(self, responses:list[bytes]) -> None: def send_response(self, responses:list[bytes]) -> None:
try: try:
# print(data) # print(data)
@@ -452,11 +486,11 @@ class Irc:
except ModuleNotFoundError as moduleNotFound: except ModuleNotFoundError as moduleNotFound:
self.Base.logs.error(f"MODULE_NOT_FOUND: {moduleNotFound}") self.Base.logs.error(f"MODULE_NOT_FOUND: {moduleNotFound}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.CONFIG_COLOR['rouge']}MODULE_NOT_FOUND{self.Config.CONFIG_COLOR['noire']} ]: {moduleNotFound}") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.COLORS.red}MODULE_NOT_FOUND{self.Config.COLORS.black} ]: {moduleNotFound}")
self.Base.db_delete_module(module_name) self.Base.db_delete_module(module_name)
except Exception as e: except Exception as e:
self.Base.logs.error(f"Something went wrong with a module you want to load : {e}") self.Base.logs.error(f"Something went wrong with a module you want to load : {e}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.CONFIG_COLOR['rouge']}ERROR{self.Config.CONFIG_COLOR['noire']} ]: {e}") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.COLORS.red}ERROR{self.Config.COLORS.black} ]: {e}")
def insert_db_admin(self, uid:str, level:int) -> None: def insert_db_admin(self, uid:str, level:int) -> None:
@@ -655,6 +689,30 @@ class Irc:
# self.Base.create_thread(self.abuseipdb_scan, (cmd[7], )) # self.Base.create_thread(self.abuseipdb_scan, (cmd[7], ))
pass pass
case 'SQUIT':
# ['@msgid=QOEolbRxdhpVW5c8qLkbAU;time=2024-09-21T17:33:16.547Z', 'SQUIT', 'defender.deb.biz.st', ':Connection', 'closed']
server_hostname = interm_response[1]
uid_to_delete = ''
for s_user in self.User.UID_DB:
if s_user.hostname == server_hostname and 'S' in s_user.umodes:
uid_to_delete = s_user.uid
self.User.delete(uid_to_delete)
self.Channel.delete_user_from_all_channel(uid_to_delete)
case 'SJOIN':
# If Server Join channels
# [':11Z', 'SJOIN', '1726940687', '#welcome', '+', ':11ZAAAAAB']
channel_joined = original_response[3]
server_uid = self.Base.clean_uid(original_response[5])
self.Channel.insert(
self.Channel.ChannelModel(
name=channel_joined,
uids=[server_uid]
)
)
case 'REPUTATION': case 'REPUTATION':
# :001 REPUTATION 91.168.141.239 118 # :001 REPUTATION 91.168.141.239 118
try: try:
@@ -728,6 +786,7 @@ class Irc:
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} : New Version available {version}") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} : New Version available {version}")
# Initialisation terminé aprés le premier PING # Initialisation terminé aprés le premier PING
self.sendPrivMsg(msg=f'[{self.Config.COLORS.green}INFORMATION{self.Config.COLORS.nogc}] >> Defender is ready', channel='#devservices')
self.INIT = 0 self.INIT = 0
case _: case _:
@@ -967,6 +1026,9 @@ class Irc:
except IndexError as ie: except IndexError as ie:
self.Base.logs.error(f"{ie} / {original_response} / length {str(len(original_response))}") self.Base.logs.error(f"{ie} / {original_response} / length {str(len(original_response))}")
except Exception as err:
self.Base.logs.error(f"General Error: {err}")
self.Base.logs.error(f"General Error: {traceback.format_exc()}")
def _hcmds(self, user: str, channel: Union[str, None], cmd: list, fullcmd: list = []) -> None: def _hcmds(self, user: str, channel: Union[str, None], cmd: list, fullcmd: list = []) -> None:
"""_summary_ """_summary_
@@ -1007,7 +1069,7 @@ class Irc:
case 'notallowed': case 'notallowed':
try: try:
current_command = cmd[0] current_command = cmd[0]
self.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR["rouge"]}{current_command}{self.Config.CONFIG_COLOR["noire"]} ] - Accès Refusé à {self.User.get_nickname(fromuser)}') self.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.red}{current_command}{self.Config.COLORS.black} ] - Accès Refusé à {self.User.get_nickname(fromuser)}')
self.send2socket(f':{dnickname} NOTICE {fromuser} : Accès Refusé') self.send2socket(f':{dnickname} NOTICE {fromuser} : Accès Refusé')
except IndexError as ie: except IndexError as ie:
self.Base.logs.error(f'{ie}') self.Base.logs.error(f'{ie}')
@@ -1017,7 +1079,57 @@ class Irc:
current_command = cmd[0] current_command = cmd[0]
uid_to_deauth = self.User.get_uid(fromuser) uid_to_deauth = self.User.get_uid(fromuser)
self.delete_db_admin(uid_to_deauth) self.delete_db_admin(uid_to_deauth)
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}{current_command}{self.Config.CONFIG_COLOR['noire']} ] - {self.User.get_nickname(fromuser)} est désormais déconnecter de {dnickname}") self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.red}{str(current_command).upper()} ]{self.Config.COLORS.black} - {self.User.get_nickname(fromuser)} est désormais déconnecter de {dnickname}")
case 'firstauth':
# firstauth OWNER_NICKNAME OWNER_PASSWORD
current_nickname = self.User.get_nickname(fromuser)
current_uid = self.User.get_uid(fromuser)
current_command = str(cmd[0])
query = f"SELECT count(id) as c FROM {self.Config.table_admin}"
result = self.Base.db_execute_query(query)
result_db = result.fetchone()
if result_db[0] > 0:
self.send2socket(f":{dnickname} NOTICE {fromuser} :You can't use this command anymore ! Please use [{self.Config.SERVICE_PREFIX}auth] instead")
return False
if current_nickname is None:
self.Base.logs.critical(f"This nickname [{fromuser}] don't exist")
return False
# Credentials sent from the user
cmd_owner = str(cmd[1])
cmd_password = str(cmd[2])
# Credentials coming from the Configuration
config_owner = self.Config.OWNER
config_password = self.Config.PASSWORD
if current_nickname != cmd_owner:
self.Base.logs.critical(f"The current nickname [{fromuser}] is different than the nickname sent [{cmd_owner}] !")
self.send2socket(f":{dnickname} NOTICE {fromuser} :The current nickname [{fromuser}] is different than the nickname sent [{cmd_owner}] !")
return False
if current_nickname != config_owner:
self.Base.logs.critical(f"The current nickname [{current_nickname}] is different than the configuration owner [{config_owner}] !")
self.send2socket(f":{dnickname} NOTICE {fromuser} :The current nickname [{current_nickname}] is different than the configuration owner [{config_owner}] !")
return False
if cmd_owner != config_owner:
self.Base.logs.critical(f"The nickname sent [{cmd_owner}] is different than the configuration owner [{config_owner}] !")
self.send2socket(f":{dnickname} NOTICE {fromuser} :The nickname sent [{cmd_owner}] is different than the configuration owner [{config_owner}] !")
return False
if cmd_owner == config_owner and cmd_password == config_password:
self.Base.db_create_first_admin()
self.insert_db_admin(current_uid, 5)
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}{str(current_command).upper()} ]{self.Config.COLORS.black} - {self.User.get_nickname(fromuser)} est désormais connecté a {dnickname}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Connexion a {dnickname} réussie!")
else:
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.red}{str(current_command).upper()} ]{self.Config.COLORS.black} - {self.User.get_nickname(fromuser)} a tapé un mauvais mot de pass")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Mot de passe incorrecte")
case 'auth': case 'auth':
# ['auth', 'adator', 'password'] # ['auth', 'adator', 'password']
@@ -1039,10 +1151,10 @@ class Irc:
if not user_from_db is None: if not user_from_db is None:
uid_user = self.User.get_uid(user_to_log) uid_user = self.User.get_uid(user_to_log)
self.insert_db_admin(uid_user, user_from_db[1]) self.insert_db_admin(uid_user, user_from_db[1])
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}{current_command}{self.Config.CONFIG_COLOR['noire']} ] - {self.User.get_nickname(fromuser)} est désormais connecté a {dnickname}") self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}{str(current_command).upper()} ]{self.Config.COLORS.black} - {self.User.get_nickname(fromuser)} est désormais connecté a {dnickname}")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Connexion a {dnickname} réussie!") self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Connexion a {dnickname} réussie!")
else: else:
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}{current_command}{self.Config.CONFIG_COLOR['noire']} ] - {self.User.get_nickname(fromuser)} a tapé un mauvais mot de pass") self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.red}{str(current_command).upper()} ]{self.Config.COLORS.black} - {self.User.get_nickname(fromuser)} a tapé un mauvais mot de pass")
self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Mot de passe incorrecte") self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Mot de passe incorrecte")
else: else:
@@ -1051,6 +1163,10 @@ class Irc:
case 'addaccess': case 'addaccess':
try: try:
# .addaccess adator 5 password # .addaccess adator 5 password
if len(cmd) < 4:
self.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} addaccess [nickname] [level] [password]')
self.send2socket(f':{dnickname} NOTICE {fromuser} : level: from 1 to 4')
newnickname = cmd[1] newnickname = cmd[1]
newlevel = self.Base.int_if_possible(cmd[2]) newlevel = self.Base.int_if_possible(cmd[2])
password = cmd[3] password = cmd[3]
@@ -1177,13 +1293,13 @@ class Irc:
else: else:
user_level = 0 user_level = 0
self.send2socket(f':{dnickname} NOTICE {fromuser} : **************** LIST DES COMMANDES *****************') self.send2socket(f':{dnickname} NOTICE {fromuser} : ***************** LISTE DES COMMANDES *****************')
self.send2socket(f':{dnickname} NOTICE {fromuser} : ') self.send2socket(f':{dnickname} NOTICE {fromuser} : ')
for levDef in self.commands_level: for levDef in self.commands_level:
if int(user_level) >= int(count_level_definition): if int(user_level) >= int(count_level_definition):
self.send2socket(f':{dnickname} NOTICE {fromuser} : **************** {self.Config.CONFIG_COLOR["noire"]}[ {self.Config.CONFIG_COLOR["verte"]}LEVEL {str(levDef)} {self.Config.CONFIG_COLOR["noire"]}] ****************') self.send2socket(f':{dnickname} NOTICE {fromuser} : ***************** {self.Config.COLORS.nogc}[ {self.Config.COLORS.green}LEVEL {str(levDef)} {self.Config.COLORS.nogc}] *****************')
count_commands = 0 count_commands = 0
help = '' help = ''
for comm in self.commands_level[count_level_definition]: for comm in self.commands_level[count_level_definition]:
@@ -1197,7 +1313,7 @@ class Irc:
count_level_definition += 1 count_level_definition += 1
self.send2socket(f':{dnickname} NOTICE {fromuser} : **************** FIN DES COMMANDES *****************') self.send2socket(f':{dnickname} NOTICE {fromuser} : ***************** FIN DES COMMANDES *****************')
case 'load': case 'load':
@@ -1333,9 +1449,9 @@ class Irc:
found = True found = True
if found: if found:
self.send2socket(f":{dnickname} NOTICE {fromuser} :{module} - {self.Config.CONFIG_COLOR['verte']}Loaded{self.Config.CONFIG_COLOR['nogc']}") self.send2socket(f":{dnickname} NOTICE {fromuser} :{module} - {self.Config.COLORS.green}Loaded{self.Config.COLORS.nogc}")
else: else:
self.send2socket(f":{dnickname} NOTICE {fromuser} :{module} - {self.Config.CONFIG_COLOR['rouge']}Not Loaded{self.Config.CONFIG_COLOR['nogc']}") self.send2socket(f":{dnickname} NOTICE {fromuser} :{module} - {self.Config.COLORS.red}Not Loaded{self.Config.COLORS.nogc}")
found = False found = False

View File

@@ -7,6 +7,17 @@ from dataclasses import dataclass, field
# CONFIGURATION FILE # # CONFIGURATION FILE #
########################################## ##########################################
@dataclass
class ColorModel:
white: str = "\x0300"
black: str = "\x0301"
blue: str = "\x0302"
green: str = "\x0303"
red: str = "\x0304"
yellow: str = "\x0306"
bold: str = "\x02"
nogc: str = "\x03"
@dataclass @dataclass
class ConfigDataModel: class ConfigDataModel:
@@ -82,8 +93,17 @@ 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 CLONE_CHANNEL: str
"""Channel to host clones""" """Channel where clones are hosted and will log PRIVMSG"""
CLONE_CMODES: str
"""Clone channel modes"""
CLONE_LOG_HOST_EXEMPT: list[str]
"""Hosts that clones will not log"""
CLONE_CHANNEL_PASSWORD: str
"""Clone password channel"""
API_TIMEOUT: int API_TIMEOUT: int
"""Default api timeout in second""" """Default api timeout in second"""
@@ -100,8 +120,6 @@ class ConfigDataModel:
DEBUG_LEVEL:Literal[10, 20, 30, 40, 50] DEBUG_LEVEL:Literal[10, 20, 30, 40, 50]
"""Logs level: DEBUG 10 | INFO 20 | WARNING 30 | ERROR 40 | CRITICAL 50""" """Logs level: DEBUG 10 | INFO 20 | WARNING 30 | ERROR 40 | CRITICAL 50"""
CONFIG_COLOR: dict[str, str]
table_admin: str table_admin: str
"""Admin table""" """Admin table"""
@@ -132,6 +150,12 @@ class ConfigDataModel:
db_path: str db_path: str
"""The database path""" """The database path"""
COLORS: ColorModel = ColorModel()
"""Available colors in Defender"""
BATCH_SIZE: int = 400
"""The batch size used for privmsg and notice"""
def __post_init__(self): def __post_init__(self):
# Initialiser SERVICE_ID après la création de l'objet # Initialiser SERVICE_ID après la création de l'objet
self.SERVICE_ID:str = f"{self.SERVEUR_ID}AAAAAB" self.SERVICE_ID:str = f"{self.SERVEUR_ID}AAAAAB"
@@ -150,40 +174,15 @@ class Config:
with open(conf_filename, 'r') as configuration_data: with open(conf_filename, 'r') as configuration_data:
configuration:dict[str, Union[str, int, list, dict]] = json.load(configuration_data) configuration:dict[str, Union[str, int, list, dict]] = json.load(configuration_data)
config_dict = {"CONFIG_COLOR" : {
"blanche": "\\u0003\\u0030",
"noire": "\\u0003\\u0031",
"bleue": "\\u0003\\u0020",
"verte": "\\u0003\\u0033",
"rouge": "\\u0003\\u0034",
"jaune": "\\u0003\\u0036",
"gras": "\\u0002",
"nogc": "\\u0002\\u0003"
}
}
missing_color = False
if not "CONFIG_COLOR" in configuration:
missing_color = True
configuration_color = config_dict
else:
configuration_color = configuration["CONFIG_COLOR"]
if missing_color:
for key, value in configuration_color.items():
configuration_color['CONFIG_COLOR'][key] = str(value).encode('utf-8').decode('unicode_escape')
configuration['CONFIG_COLOR'] = configuration_color['CONFIG_COLOR']
else:
for key, value in configuration['CONFIG_COLOR'].items():
configuration['CONFIG_COLOR'][key] = str(value).encode('utf-8').decode('unicode_escape')
return configuration return configuration
except FileNotFoundError as fe: except FileNotFoundError as fe:
print(f'FileNotFound: {fe}') print(f'FileNotFound: {fe}')
print('Configuration file not found please create core/configuration.json') print('Configuration file not found please create core/configuration.json')
sys.exit(0) sys.exit(0)
except KeyError as ke:
print(f'Key Error: {ke}')
print('The key must be defined in core/configuration.json')
def __load_service_configuration(self) -> ConfigDataModel: def __load_service_configuration(self) -> ConfigDataModel:
import_config = self.__load_json_service_configuration() import_config = self.__load_json_service_configuration()
@@ -212,13 +211,15 @@ class Config:
SALON_JAIL=import_config["SALON_JAIL"] if "SALON_JAIL" in import_config else '#jail', SALON_JAIL=import_config["SALON_JAIL"] if "SALON_JAIL" in import_config else '#jail',
SALON_JAIL_MODES=import_config["SALON_JAIL_MODES"] if "SALON_JAIL_MODES" in import_config else 'sS', SALON_JAIL_MODES=import_config["SALON_JAIL_MODES"] if "SALON_JAIL_MODES" in import_config else 'sS',
SALON_LIBERER=import_config["SALON_LIBERER"] if "SALON_LIBERER" in import_config else '#welcome', SALON_LIBERER=import_config["SALON_LIBERER"] if "SALON_LIBERER" in import_config else '#welcome',
SALON_CLONES=import_config["SALON_CLONES"] if "SALON_CLONES" in import_config else '#clones', CLONE_CHANNEL=import_config["CLONE_CHANNEL"] if "CLONE_CHANNEL" in import_config else '#clones',
CLONE_CMODES=import_config["CLONE_CMODES"] if "CLONE_CMODES" in import_config else '+nts',
CLONE_LOG_HOST_EXEMPT=import_config["CLONE_LOG_HOST_EXEMPT"] if "CLONE_LOG_HOST_EXEMPT" in import_config else [],
CLONE_CHANNEL_PASSWORD=import_config["CLONE_CHANNEL_PASSWORD"] if "CLONE_CHANNEL_PASSWORD" in import_config else "clone_Password_1234",
API_TIMEOUT=import_config["API_TIMEOUT"] if "API_TIMEOUT" in import_config else 2, API_TIMEOUT=import_config["API_TIMEOUT"] if "API_TIMEOUT" in import_config else 2,
PORTS_TO_SCAN=import_config["PORTS_TO_SCAN"] if "PORTS_TO_SCAN" in import_config else [], PORTS_TO_SCAN=import_config["PORTS_TO_SCAN"] if "PORTS_TO_SCAN" in import_config else [],
WHITELISTED_IP=import_config["WHITELISTED_IP"] if "WHITELISTED_IP" in import_config else ['127.0.0.1'], WHITELISTED_IP=import_config["WHITELISTED_IP"] if "WHITELISTED_IP" in import_config else ['127.0.0.1'],
GLINE_DURATION=import_config["GLINE_DURATION"] if "GLINE_DURATION" in import_config else '30', GLINE_DURATION=import_config["GLINE_DURATION"] if "GLINE_DURATION" in import_config else '30',
DEBUG_LEVEL=import_config["DEBUG_LEVEL"] if "DEBUG_LEVEL" in import_config else 20, DEBUG_LEVEL=import_config["DEBUG_LEVEL"] if "DEBUG_LEVEL" in import_config else 20,
CONFIG_COLOR=import_config["CONFIG_COLOR"],
table_admin='core_admin', table_admin='core_admin',
table_commande='core_command', table_commande='core_command',
table_log='core_log', table_log='core_log',

View File

@@ -1,5 +1,5 @@
from dataclasses import dataclass, fields, field from dataclasses import dataclass, fields, field
import random, faker, time import random, faker, time, logging
from datetime import datetime from datetime import datetime
from typing import Union from typing import Union
from core.irc import Irc from core.irc import Irc
@@ -58,6 +58,11 @@ class Clone():
# Load module configuration (Mandatory) # Load module configuration (Mandatory)
self.__load_module_configuration() self.__load_module_configuration()
self.Base.db_query_channel(action='add', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL)
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} JOIN {self.Config.CLONE_CHANNEL}")
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} MODE {self.Config.CLONE_CHANNEL} +nts")
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} MODE {self.Config.CLONE_CHANNEL} +k {self.Config.CLONE_CHANNEL_PASSWORD}")
def __set_commands(self, commands:dict[int, list[str]]) -> None: def __set_commands(self, commands:dict[int, list[str]]) -> None:
"""### Rajoute les commandes du module au programme principal """### Rajoute les commandes du module au programme principal
@@ -120,8 +125,34 @@ class Clone():
for clone in self.ModConfig.clone_nicknames: for clone in self.ModConfig.clone_nicknames:
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone} :KILL') self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone} :KILL')
self.Base.db_query_channel(action='del', module_name=self.module_name, channel_name=self.Config.CLONE_CHANNEL)
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PART {self.Config.CLONE_CHANNEL}")
return None return None
def thread_clone_clean_up(self, wait: float):
activated = True
while activated:
clone_to_kill: list[str] = []
for clone in self.Clone.UID_CLONE_DB:
if not clone.connected and clone.alive and not clone.init:
clone_to_kill.append(clone.nickname)
clone.alive = False
for clone_nickname in clone_to_kill:
if self.Clone.delete(clone_nickname):
self.Logs.debug(f'<<{clone_nickname}>> object has been deleted')
del clone_to_kill
# If LIST empty then stop this thread
if not self.Clone.UID_CLONE_DB:
break
time.sleep(wait)
def thread_change_hostname(self): def thread_change_hostname(self):
fake = faker.Faker('en_GB') fake = faker.Faker('en_GB')
@@ -142,6 +173,27 @@ class Clone():
found = True found = True
clone.vhost = rand_ip clone.vhost = rand_ip
break break
if not clone in self.Clone.UID_CLONE_DB:
found = True
break
def thread_create_clones_with_interval(self, number_of_clones:int, channels: list, connection_interval: float):
for i in range(number_of_clones):
nickname, username, realname = self.generate_names()
self.Base.create_thread(
self.thread_create_clones,
(nickname, username, realname, channels, 6697, True)
)
time.sleep(connection_interval)
self.Base.create_thread(
self.thread_change_hostname
)
# self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :{str(number_of_clones)} clones joined the network')
self.Base.create_thread(self.thread_clone_clean_up, (5, ), run_once=True)
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:
@@ -167,6 +219,7 @@ class Clone():
def generate_names(self) -> tuple[str, str, str]: def generate_names(self) -> tuple[str, str, str]:
try: try:
logging.getLogger('faker').setLevel(logging.CRITICAL)
fake = faker.Faker('en_GB') fake = faker.Faker('en_GB')
# nickname = fake.first_name() # nickname = fake.first_name()
# username = fake.last_name() # username = fake.last_name()
@@ -237,7 +290,7 @@ class Clone():
case 'clone': case 'clone':
if len(cmd) == 1: if len(cmd) == 1:
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect 6') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect 6 2.5')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone kill [all | nickname]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone kill [all | nickname]')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone join [all | nickname] #channel') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone join [all | nickname] #channel')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone list') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone list')
@@ -248,24 +301,18 @@ class Clone():
case 'connect': case 'connect':
try: try:
# clone connect 5
number_of_clones = int(cmd[2]) number_of_clones = int(cmd[2])
for i in range(number_of_clones): connection_interval = int(cmd[3]) if len(cmd) == 4 else 0.5
nickname, username, realname = self.generate_names()
self.Base.create_thread(
self.thread_create_clones,
(nickname, username, realname, [], 6697, True)
)
self.Base.create_thread( self.Base.create_thread(
self.thread_change_hostname self.thread_create_clones_with_interval,
) (number_of_clones, [], connection_interval)
)
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :{str(number_of_clones)} clones joined the network')
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.Logs.error(f'{err}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect [number of clone you want to connect]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect [number of clone you want to connect] [Connection Interval]')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :Exemple /msg {dnickname} clone connect 6') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :Exemple /msg {dnickname} clone connect 6 2.5')
case 'kill': case 'kill':
try: try:
@@ -313,8 +360,10 @@ class Clone():
case 'list': case 'list':
try: try:
clone_count = len(self.Clone.UID_CLONE_DB)
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :>> Number of connected clones: {clone_count}')
for clone_name in self.Clone.UID_CLONE_DB: for clone_name in self.Clone.UID_CLONE_DB:
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :>> Nickname: {clone_name.nickname} | Username: {clone_name.username}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :>> Nickname: {clone_name.nickname} | Username: {clone_name.username} | Realname: {clone_name.realname} | Vhost: {clone_name.vhost} | Init: {clone_name.init} | Live: {clone_name.alive} | Connected: {clone_name.connected}')
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.Logs.error(f'{err}')

View File

@@ -441,9 +441,9 @@ class Defender():
jailed_nickname = get_reputation.nickname jailed_nickname = get_reputation.nickname
jailed_score = get_reputation.score jailed_score = get_reputation.score
color_red = self.Config.CONFIG_COLOR['rouge'] color_red = self.Config.COLORS.red
color_black = self.Config.CONFIG_COLOR['noire'] color_black = self.Config.COLORS.black
color_bold = self.Config.CONFIG_COLOR['gras'] color_bold = self.Config.COLORS.bold
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
service_prefix = self.Config.SERVICE_PREFIX service_prefix = self.Config.SERVICE_PREFIX
reputation_ban_all_chan = self.ModConfig.reputation_ban_all_chan reputation_ban_all_chan = self.ModConfig.reputation_ban_all_chan
@@ -478,8 +478,8 @@ class Defender():
ban_all_chan = self.ModConfig.reputation_ban_all_chan ban_all_chan = self.ModConfig.reputation_ban_all_chan
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
dchanlog = self.Config.SERVICE_CHANLOG dchanlog = self.Config.SERVICE_CHANLOG
color_red = self.Config.CONFIG_COLOR['rouge'] color_red = self.Config.COLORS.red
color_black = self.Config.CONFIG_COLOR['noire'] color_black = self.Config.COLORS.black
salon_jail = self.Config.SALON_JAIL salon_jail = self.Config.SALON_JAIL
if reputation_flag == 0: if reputation_flag == 0:
@@ -559,8 +559,8 @@ class Defender():
flood_timer = self.ModConfig.flood_timer flood_timer = self.ModConfig.flood_timer
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.Config.SERVICE_NICKNAME
color_red = self.Config.CONFIG_COLOR['rouge'] color_red = self.Config.COLORS.red
color_bold = self.Config.CONFIG_COLOR['gras'] color_bold = self.Config.COLORS.bold
get_detected_uid = self.User.get_uid(detected_user) get_detected_uid = self.User.get_uid(detected_user)
get_detected_nickname = self.User.get_nickname(detected_user) get_detected_nickname = self.User.get_nickname(detected_user)
@@ -634,7 +634,7 @@ class Defender():
connection = (remote_ip, self.Base.int_if_possible(port)) connection = (remote_ip, self.Base.int_if_possible(port))
newSocket.connect(connection) newSocket.connect(connection)
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.CONFIG_COLOR['rouge']}PROXY_SCAN{self.Config.CONFIG_COLOR['noire']} ] {fullname} ({remote_ip}) : Port [{str(port)}] ouvert sur l'adresse ip [{remote_ip}]") self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.COLORS.red}PROXY_SCAN{self.Config.COLORS.black} ] {fullname} ({remote_ip}) : Port [{str(port)}] ouvert sur l'adresse ip [{remote_ip}]")
# print(f"=======> Le port {str(port)} est ouvert !!") # print(f"=======> Le port {str(port)} est ouvert !!")
self.Base.running_sockets.append(newSocket) self.Base.running_sockets.append(newSocket)
# print(newSocket) # print(newSocket)
@@ -697,7 +697,7 @@ class Defender():
self.Logs.info(f"Connexion of {fullname} ({remote_ip}) using ports : {str(matching_ports)}") self.Logs.info(f"Connexion of {fullname} ({remote_ip}) using ports : {str(matching_ports)}")
if matching_ports: if matching_ports:
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.CONFIG_COLOR['rouge']}PSUTIL_SCAN{self.Config.CONFIG_COLOR['noire']} ] {fullname} ({remote_ip}) : is using ports {matching_ports}") self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.COLORS.red}PSUTIL_SCAN{self.Config.COLORS.black} ] {fullname} ({remote_ip}) : is using ports {matching_ports}")
return matching_ports return matching_ports
@@ -777,8 +777,8 @@ class Defender():
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
service_chanlog = self.Config.SERVICE_CHANLOG service_chanlog = self.Config.SERVICE_CHANLOG
color_red = self.Config.CONFIG_COLOR['rouge'] color_red = self.Config.COLORS.red
color_black = self.Config.CONFIG_COLOR['noire'] color_black = self.Config.COLORS.black
# pseudo!ident@host # pseudo!ident@host
fullname = f'{nickname}!{username}@{hostname}' fullname = f'{nickname}!{username}@{hostname}'
@@ -845,8 +845,8 @@ class Defender():
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
service_chanlog = self.Config.SERVICE_CHANLOG service_chanlog = self.Config.SERVICE_CHANLOG
color_red = self.Config.CONFIG_COLOR['rouge'] color_red = self.Config.COLORS.red
color_black = self.Config.CONFIG_COLOR['noire'] color_black = self.Config.COLORS.black
url = f'https://freeipapi.com/api/json/{remote_ip}' url = f'https://freeipapi.com/api/json/{remote_ip}'
@@ -933,8 +933,8 @@ class Defender():
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
service_chanlog = self.Config.SERVICE_CHANLOG service_chanlog = self.Config.SERVICE_CHANLOG
color_red = self.Config.CONFIG_COLOR['rouge'] color_red = self.Config.COLORS.red
color_black = self.Config.CONFIG_COLOR['noire'] color_black = self.Config.COLORS.black
url = f"https://developers18334.cloudfilt.com/" url = f"https://developers18334.cloudfilt.com/"
@@ -1233,8 +1233,8 @@ class Defender():
self.Logs.debug(f"IP de {jailed_nickname} : {jailed_IP}") self.Logs.debug(f"IP de {jailed_nickname} : {jailed_IP}")
link = self.Config.SERVEUR_LINK link = self.Config.SERVEUR_LINK
color_green = self.Config.CONFIG_COLOR['verte'] color_green = self.Config.COLORS.green
color_black = self.Config.CONFIG_COLOR['noire'] color_black = self.Config.COLORS.black
if release_code == get_reputation.secret_code: if release_code == get_reputation.secret_code:
self.Irc.send2socket(f':{dnickname} PRIVMSG {jailed_salon} : Bon mot de passe. Allez du vent !') self.Irc.send2socket(f':{dnickname} PRIVMSG {jailed_salon} : Bon mot de passe. Allez du vent !')
@@ -1278,13 +1278,13 @@ class Defender():
if activation == 'on': if activation == 'on':
if self.ModConfig.reputation == 1: if self.ModConfig.reputation == 1:
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}REPUTATION{self.Config.CONFIG_COLOR['noire']} ] : Already activated") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}REPUTATION{self.Config.COLORS.black} ] : Already activated")
return False return False
# self.update_db_configuration('reputation', 1) # self.update_db_configuration('reputation', 1)
self.__update_configuration(key, 1) self.__update_configuration(key, 1)
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}REPUTATION{self.Config.CONFIG_COLOR['noire']} ] : Activated by {fromuser}") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}REPUTATION{self.Config.COLORS.black} ] : Activated by {fromuser}")
self.Irc.send2socket(f":{service_id} JOIN {jail_chan}") self.Irc.send2socket(f":{service_id} JOIN {jail_chan}")
self.Irc.send2socket(f":{service_id} SAMODE {jail_chan} +{dumodes} {dnickname}") self.Irc.send2socket(f":{service_id} SAMODE {jail_chan} +{dumodes} {dnickname}")
self.Irc.send2socket(f":{service_id} MODE {jail_chan} +{jail_chan_mode}") self.Irc.send2socket(f":{service_id} MODE {jail_chan} +{jail_chan_mode}")
@@ -1300,12 +1300,12 @@ class Defender():
if activation == 'off': if activation == 'off':
if self.ModConfig.reputation == 0: if self.ModConfig.reputation == 0:
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}REPUTATION{self.Config.CONFIG_COLOR['noire']} ] : Already deactivated") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}REPUTATION{self.Config.COLORS.black} ] : Already deactivated")
return False return False
self.__update_configuration(key, 0) self.__update_configuration(key, 0)
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}REPUTATION{self.Config.CONFIG_COLOR['noire']} ] : Deactivated by {fromuser}") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.red}REPUTATION{self.Config.COLORS.black} ] : Deactivated by {fromuser}")
self.Irc.send2socket(f":{service_id} SAMODE {jail_chan} -{dumodes} {dnickname}") self.Irc.send2socket(f":{service_id} SAMODE {jail_chan} -{dumodes} {dnickname}")
self.Irc.send2socket(f":{service_id} MODE {jail_chan} -sS") self.Irc.send2socket(f":{service_id} MODE {jail_chan} -sS")
self.Irc.send2socket(f":{service_id} PART {jail_chan}") self.Irc.send2socket(f":{service_id} PART {jail_chan}")
@@ -1335,23 +1335,23 @@ class Defender():
if get_value == 'on': if get_value == 'on':
if self.ModConfig.reputation_ban_all_chan == 1: if self.ModConfig.reputation_ban_all_chan == 1:
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}BAN ON ALL CHANS{self.Config.CONFIG_COLOR['noire']} ] : Already activated") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.red}BAN ON ALL CHANS{self.Config.COLORS.black} ] : Already activated")
return False return False
# self.update_db_configuration(key, 1) # self.update_db_configuration(key, 1)
self.__update_configuration(key, 1) self.__update_configuration(key, 1)
self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR["verte"]}BAN ON ALL CHANS{self.Config.CONFIG_COLOR["noire"]} ] : Activated by {fromuser}') self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}BAN ON ALL CHANS{self.Config.COLORS.black} ] : Activated by {fromuser}')
elif get_value == 'off': elif get_value == 'off':
if self.ModConfig.reputation_ban_all_chan == 0: if self.ModConfig.reputation_ban_all_chan == 0:
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}BAN ON ALL CHANS{self.Config.CONFIG_COLOR['noire']} ] : Already deactivated") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.red}BAN ON ALL CHANS{self.Config.COLORS.black} ] : Already deactivated")
return False return False
# self.update_db_configuration(key, 0) # self.update_db_configuration(key, 0)
self.__update_configuration(key, 0) self.__update_configuration(key, 0)
self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR["verte"]}BAN ON ALL CHANS{self.Config.CONFIG_COLOR["noire"]} ] : Deactivated by {fromuser}') self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}BAN ON ALL CHANS{self.Config.COLORS.black} ] : Deactivated by {fromuser}')
case 'limit': case 'limit':
reputation_seuil = int(cmd[3]) reputation_seuil = int(cmd[3])
@@ -1360,7 +1360,7 @@ class Defender():
# self.update_db_configuration(key, reputation_seuil) # self.update_db_configuration(key, reputation_seuil)
self.__update_configuration(key, reputation_seuil) self.__update_configuration(key, reputation_seuil)
self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR["verte"]}REPUTATION SEUIL{self.Config.CONFIG_COLOR["noire"]} ] : Limit set to {str(reputation_seuil)} by {fromuser}') self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}REPUTATION SEUIL{self.Config.COLORS.black} ] : Limit set to {str(reputation_seuil)} by {fromuser}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Reputation set to {reputation_seuil}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Reputation set to {reputation_seuil}')
case 'timer': case 'timer':
@@ -1368,7 +1368,7 @@ class Defender():
key = 'reputation_timer' key = 'reputation_timer'
self.__update_configuration(key, reputation_timer) self.__update_configuration(key, reputation_timer)
self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR["verte"]}REPUTATION TIMER{self.Config.CONFIG_COLOR["noire"]} ] : Timer set to {str(reputation_timer)} minute(s) by {fromuser}') self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}REPUTATION TIMER{self.Config.COLORS.black} ] : Timer set to {str(reputation_timer)} minute(s) by {fromuser}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Reputation set to {reputation_timer}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Reputation set to {reputation_timer}')
case 'score_after_release': case 'score_after_release':
@@ -1376,7 +1376,7 @@ class Defender():
key = 'reputation_score_after_release' key = 'reputation_score_after_release'
self.__update_configuration(key, reputation_score_after_release) self.__update_configuration(key, reputation_score_after_release)
self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR["verte"]}REPUTATION SCORE AFTER RELEASE{self.Config.CONFIG_COLOR["noire"]} ] : Reputation score after release set to {str(reputation_score_after_release)} by {fromuser}') self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}REPUTATION SCORE AFTER RELEASE{self.Config.COLORS.black} ] : Reputation score after release set to {str(reputation_score_after_release)} by {fromuser}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Reputation score after release set to {reputation_score_after_release}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Reputation score after release set to {reputation_score_after_release}')
case 'security_group': case 'security_group':
@@ -1384,7 +1384,7 @@ class Defender():
key = 'reputation_sg' key = 'reputation_sg'
self.__update_configuration(key, reputation_sg) self.__update_configuration(key, reputation_sg)
self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR["verte"]}REPUTATION SECURITY-GROUP{self.Config.CONFIG_COLOR["noire"]} ] : Reputation Security-group set to {str(reputation_sg)} by {fromuser}') self.Irc.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}REPUTATION SECURITY-GROUP{self.Config.COLORS.black} ] : Reputation Security-group set to {str(reputation_sg)} by {fromuser}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Reputation score after release set to {reputation_sg}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Reputation score after release set to {reputation_sg}')
case _: case _:
@@ -1414,9 +1414,9 @@ class Defender():
# .proxy_scan set psutil_scan on/off --> Active les informations de connexion a la machine locale # .proxy_scan set psutil_scan on/off --> Active les informations de connexion a la machine locale
# .proxy_scan set abuseipdb_scan on/off --> Active le scan via l'api abuseipdb # .proxy_scan set abuseipdb_scan on/off --> Active le scan via l'api abuseipdb
len_cmd = len(cmd) len_cmd = len(cmd)
color_green = self.Config.CONFIG_COLOR['verte'] color_green = self.Config.COLORS.green
color_red = self.Config.CONFIG_COLOR['rouge'] color_red = self.Config.COLORS.red
color_black = self.Config.CONFIG_COLOR['noire'] color_black = self.Config.COLORS.black
if len_cmd == 4: if len_cmd == 4:
set_key = str(cmd[1]).lower() set_key = str(cmd[1]).lower()
@@ -1548,21 +1548,21 @@ class Defender():
key = 'flood' key = 'flood'
if activation == 'on': if activation == 'on':
if self.ModConfig.flood == 1: if self.ModConfig.flood == 1:
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Already activated") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Already activated")
return False return False
self.__update_configuration(key, 1) self.__update_configuration(key, 1)
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Activated by {fromuser}") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Activated by {fromuser}")
if activation == 'off': if activation == 'off':
if self.ModConfig.flood == 0: if self.ModConfig.flood == 0:
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Already Deactivated") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.red}FLOOD{self.Config.COLORS.black} ] : Already Deactivated")
return False return False
self.__update_configuration(key, 0) self.__update_configuration(key, 0)
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Deactivated by {fromuser}") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Deactivated by {fromuser}")
if len_cmd == 4: if len_cmd == 4:
set_key = str(cmd[2]).lower() set_key = str(cmd[2]).lower()
@@ -1574,21 +1574,21 @@ class Defender():
set_value = int(cmd[3]) set_value = int(cmd[3])
self.__update_configuration(key, set_value) self.__update_configuration(key, set_value)
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Flood message set to {set_value} by {fromuser}") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Flood message set to {set_value} by {fromuser}")
case 'flood_time': case 'flood_time':
key = 'flood_time' key = 'flood_time'
set_value = int(cmd[3]) set_value = int(cmd[3])
self.__update_configuration(key, set_value) self.__update_configuration(key, set_value)
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Flood time set to {set_value} by {fromuser}") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Flood time set to {set_value} by {fromuser}")
case 'flood_timer': case 'flood_timer':
key = 'flood_timer' key = 'flood_timer'
set_value = int(cmd[3]) set_value = int(cmd[3])
self.__update_configuration(key, set_value) self.__update_configuration(key, set_value)
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Flood timer set to {set_value} by {fromuser}") self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.COLORS.green}FLOOD{self.Config.COLORS.black} ] : Flood timer set to {set_value} by {fromuser}")
case _: case _:
pass pass
@@ -1597,9 +1597,9 @@ class Defender():
self.Logs.error(f"{self.__class__.__name__} Value Error : {ve}") self.Logs.error(f"{self.__class__.__name__} Value Error : {ve}")
case 'status': case 'status':
color_green = self.Config.CONFIG_COLOR['verte'] color_green = self.Config.COLORS.green
color_red = self.Config.CONFIG_COLOR['rouge'] color_red = self.Config.COLORS.red
color_black = self.Config.CONFIG_COLOR['noire'] color_black = self.Config.COLORS.black
try: try:
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : [{color_green if self.ModConfig.reputation == 1 else color_red}Reputation{color_black}] ==> {self.ModConfig.reputation}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : [{color_green if self.ModConfig.reputation == 1 else color_red}Reputation{color_black}] ==> {self.ModConfig.reputation}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : reputation_seuil ==> {self.ModConfig.reputation_seuil}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : reputation_seuil ==> {self.ModConfig.reputation_seuil}')
@@ -1626,6 +1626,12 @@ class Defender():
UserObject = self.User.get_User(nickoruid) UserObject = self.User.get_User(nickoruid)
if not UserObject is None: if not UserObject is None:
channels: list = []
for chan in self.Channel.UID_CHANNEL_DB:
for uid_in_chan in chan.uids:
if self.Base.clean_uid(uid_in_chan) == UserObject.uid:
channels.append(chan.name)
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : UID : {UserObject.uid}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : UID : {UserObject.uid}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : NICKNAME : {UserObject.nickname}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : NICKNAME : {UserObject.nickname}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : USERNAME : {UserObject.username}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : USERNAME : {UserObject.username}')
@@ -1638,6 +1644,7 @@ class Defender():
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : WebWebsocket : {UserObject.isWebsocket}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : WebWebsocket : {UserObject.isWebsocket}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : REPUTATION : {UserObject.score_connexion}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : REPUTATION : {UserObject.score_connexion}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : MODES : {UserObject.umodes}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : MODES : {UserObject.umodes}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : CHANNELS : {channels}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : CONNECTION TIME : {UserObject.connexion_datetime}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : CONNECTION TIME : {UserObject.connexion_datetime}')
else: else:
self.Irc.send2socket(f":{dnickname} NOTICE {fromuser} : This user {nickoruid} doesn't exist") self.Irc.send2socket(f":{dnickname} NOTICE {fromuser} : This user {nickoruid} doesn't exist")

View File

@@ -229,11 +229,11 @@ class Votekick():
if chan.channel_name == channel: if chan.channel_name == channel:
target_user = self.User.get_nickname(chan.target_user) target_user = self.User.get_nickname(chan.target_user)
if chan.vote_for > chan.vote_against: if chan.vote_for > chan.vote_against:
self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} :User {self.Config.CONFIG_COLOR["gras"]}{target_user}{self.Config.CONFIG_COLOR["nogc"]} has {chan.vote_against} votes against and {chan.vote_for} votes for. For this reason, it\'ll be kicked from the channel') self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} :User {self.Config.COLORS.bold}{target_user}{self.Config.COLORS.nogc} has {chan.vote_against} votes against and {chan.vote_for} votes for. For this reason, it\'ll be kicked from the channel')
self.Irc.send2socket(f":{dnickname} KICK {channel} {target_user} Following the vote, you are not welcome in {channel}") self.Irc.send2socket(f":{dnickname} KICK {channel} {target_user} Following the vote, you are not welcome in {channel}")
self.Channel.delete_user_from_channel(channel, self.User.get_uid(target_user)) self.Channel.delete_user_from_channel(channel, self.User.get_uid(target_user))
elif chan.vote_for <= chan.vote_against: elif chan.vote_for <= chan.vote_against:
self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} :User {self.Config.CONFIG_COLOR["gras"]}{target_user}{self.Config.CONFIG_COLOR["nogc"]} has {chan.vote_against} votes against and {chan.vote_for} votes for. For this reason, it\'ll remain in the channel') self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} :User {self.Config.COLORS.bold}{target_user}{self.Config.COLORS.nogc} has {chan.vote_against} votes against and {chan.vote_for} votes for. For this reason, it\'ll remain in the channel')
# Init the system # Init the system
if self.init_vote_system(channel): if self.init_vote_system(channel):
@@ -471,10 +471,10 @@ class Votekick():
if chan.channel_name == channel: if chan.channel_name == channel:
target_user = self.User.get_nickname(chan.target_user) target_user = self.User.get_nickname(chan.target_user)
if chan.vote_for > chan.vote_against: if chan.vote_for > chan.vote_against:
self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} :User {self.Config.CONFIG_COLOR["gras"]}{target_user}{self.Config.CONFIG_COLOR["nogc"]} has {chan.vote_against} votes against and {chan.vote_for} votes for. For this reason, it\'ll be kicked from the channel') self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} :User {self.Config.COLORS.bold}{target_user}{self.Config.COLORS.nogc} has {chan.vote_against} votes against and {chan.vote_for} votes for. For this reason, it\'ll be kicked from the channel')
self.Irc.send2socket(f":{dnickname} KICK {channel} {target_user} Following the vote, you are not welcome in {channel}") self.Irc.send2socket(f":{dnickname} KICK {channel} {target_user} Following the vote, you are not welcome in {channel}")
elif chan.vote_for <= chan.vote_against: elif chan.vote_for <= chan.vote_against:
self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} :User {self.Config.CONFIG_COLOR["gras"]}{target_user}{self.Config.CONFIG_COLOR["nogc"]} has {chan.vote_against} votes against and {chan.vote_for} votes for. For this reason, it\'ll remain in the channel') self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} :User {self.Config.COLORS.bold}{target_user}{self.Config.COLORS.nogc} has {chan.vote_against} votes against and {chan.vote_for} votes for. For this reason, it\'ll remain in the channel')
# Init the system # Init the system
if self.init_vote_system(channel): if self.init_vote_system(channel):

View File

@@ -1,3 +1,3 @@
{ {
"version": "5.2.5" "version": "5.3.0"
} }