New Version

This commit is contained in:
adator
2024-08-03 17:01:19 +02:00
parent 19b7f85ec7
commit 6e6d001605
6 changed files with 334 additions and 233 deletions

View File

@@ -1,8 +1,9 @@
import time, threading, os, random, socket, hashlib, ipaddress import time, threading, os, random, socket, hashlib, ipaddress, logging, requests, json, sys
from datetime import datetime from datetime import datetime
from sqlalchemy import create_engine, Engine, Connection, CursorResult from sqlalchemy import create_engine, Engine, Connection, CursorResult
from sqlalchemy.sql import text from sqlalchemy.sql import text
from core.configuration import Config from core.configuration import Config
from core.sys_configuration import SysConfig
class Base: class Base:
@@ -19,6 +20,10 @@ class Base:
def __init__(self, Config: Config) -> None: def __init__(self, Config: Config) -> None:
self.Config = Config # Assigner l'objet de configuration self.Config = Config # Assigner l'objet de configuration
self.SysConfig = SysConfig() # Importer les information pour le systeme
self.init_log_system() # Demarrer le systeme de log
self.get_latest_defender_version()
self.running_timers:list[threading.Timer] = [] # Liste des timers en cours self.running_timers:list[threading.Timer] = [] # Liste des timers en cours
self.running_threads:list[threading.Thread] = [] # Liste des threads en cours self.running_threads:list[threading.Thread] = [] # Liste des threads en cours
@@ -32,6 +37,26 @@ class Base:
self.db_create_first_admin() # Créer un nouvel admin si la base de données est vide self.db_create_first_admin() # Créer un nouvel admin si la base de données est vide
def get_latest_defender_version(self) -> None:
try:
#token = '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'
token = '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'
json_url = f'https://github.com/adator85/IRC_DEFENDER_MODULES/blob/e27a027ae99a6c11171635b2a120803e8682aac6/version.json'
headers = {
'Authorization': f'token {token}',
'Accept': 'application/vnd.github.v3.raw' # Indique à GitHub que nous voulons le contenu brut du fichier
}
response = requests.get(json_url)
response.raise_for_status() # Vérifie si la requête a réussi
json_response:dict = response.json()
self.SysConfig.LATEST_DEFENDER_VERSION = json_response["version"]
return None
except requests.HTTPError as err:
self.logs.error(f'Github not available to fetch latest version: {err}')
except:
self.logs.warning(f'Github not available to fetch latest version')
def get_unixtime(self) -> int: def get_unixtime(self) -> int:
""" """
Cette fonction retourne un UNIXTIME de type 12365456 Cette fonction retourne un UNIXTIME de type 12365456
@@ -62,12 +87,36 @@ class Base:
return None return None
def init_log_system(self) -> None:
# Create folder if not available
logs_directory = f'logs{os.sep}'
if not os.path.exists(f'{logs_directory}'):
os.makedirs(logs_directory)
# Init logs object
self.logs = logging
self.logs.basicConfig(level=self.Config.DEBUG_LEVEL,
filename='logs/defender.log',
encoding='UTF-8',
format='%(asctime)s - %(levelname)s - %(filename)s - %(lineno)d - %(funcName)s - %(message)s')
self.logs.info('#################### STARTING INTERCEPTOR HQ ####################')
return None
def log_cmd(self, user_cmd:str, cmd:str) -> None: def log_cmd(self, user_cmd:str, cmd:str) -> None:
"""Enregistre les commandes envoyées par les utilisateurs """Enregistre les commandes envoyées par les utilisateurs
Args: Args:
cmd (str): la commande a enregistrer cmd (str): la commande a enregistrer
""" """
cmd_list = cmd.split()
if len(cmd_list) == 3:
if cmd_list[0].replace('.', '') == 'auth':
cmd_list[1] = '*******'
cmd_list[2] = '*******'
cmd = ' '.join(cmd_list)
insert_cmd_query = f"INSERT INTO {self.DB_SCHEMA['commandes']} (datetime, user, commande) VALUES (:datetime, :user, :commande)" insert_cmd_query = f"INSERT INTO {self.DB_SCHEMA['commandes']} (datetime, user, commande) VALUES (:datetime, :user, :commande)"
mes_donnees = {'datetime': self.get_datetime(), 'user': user_cmd, 'commande': cmd} mes_donnees = {'datetime': self.get_datetime(), 'user': user_cmd, 'commande': cmd}
self.db_execute_query(insert_cmd_query, mes_donnees) self.db_execute_query(insert_cmd_query, mes_donnees)
@@ -100,13 +149,13 @@ class Base:
""" """
if not self.db_isModuleExist(module_name): if not self.db_isModuleExist(module_name):
self.__debug(f"Le module {module_name} n'existe pas alors ont le créer") self.logs.debug(f"Le module {module_name} n'existe pas alors ont le créer")
insert_cmd_query = f"INSERT INTO {self.DB_SCHEMA['modules']} (datetime, user, module) VALUES (:datetime, :user, :module)" insert_cmd_query = f"INSERT INTO {self.DB_SCHEMA['modules']} (datetime, user, module) VALUES (:datetime, :user, :module)"
mes_donnees = {'datetime': self.get_datetime(), 'user': user_cmd, 'module': module_name} mes_donnees = {'datetime': self.get_datetime(), 'user': user_cmd, 'module': module_name}
self.db_execute_query(insert_cmd_query, mes_donnees) self.db_execute_query(insert_cmd_query, mes_donnees)
# self.db_close_session(self.session) # self.db_close_session(self.session)
else: else:
self.__debug(f"Le module {module_name} existe déja dans la base de données") self.logs.debug(f"Le module {module_name} existe déja dans la base de données")
return False return False
@@ -148,10 +197,10 @@ class Base:
self.running_timers.append(t) self.running_timers.append(t)
self.__debug(f"Timer ID : {str(t.ident)} | Running Threads : {len(threading.enumerate())}") self.logs.debug(f"Timer ID : {str(t.ident)} | Running Threads : {len(threading.enumerate())}")
except AssertionError as ae: except AssertionError as ae:
self.__debug(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) -> None:
try: try:
@@ -170,98 +219,95 @@ class Base:
th.start() th.start()
self.running_threads.append(th) self.running_threads.append(th)
self.__debug(f"Thread ID : {str(th.ident)} | Thread name : {th.getName()} | Running Threads : {len(threading.enumerate())}") self.logs.debug(f"Thread ID : {str(th.ident)} | Thread name : {th.getName()} | Running Threads : {len(threading.enumerate())}")
except AssertionError as ae: except AssertionError as ae:
self.__debug(f'Assertion Error -> {ae}') self.logs.error(f'{ae}')
def garbage_collector_timer(self) -> None: def garbage_collector_timer(self) -> None:
"""Methode qui supprime les timers qui ont finis leurs job """Methode qui supprime les timers qui ont finis leurs job
""" """
try: try:
# self.__debug(f"=======> Checking for Timers to stop")
# print(f"{self.running_timers}")
for timer in self.running_timers: for timer in self.running_timers:
if not timer.is_alive(): if not timer.is_alive():
timer.cancel() timer.cancel()
self.running_timers.remove(timer) self.running_timers.remove(timer)
self.__debug(f"Timer {str(timer)} removed") self.logs.info(f"Timer {str(timer)} removed")
else: else:
self.__debug(f"===> Timer {str(timer)} Still running ...") self.logs.debug(f"===> Timer {str(timer)} Still running ...")
except AssertionError as ae: except AssertionError as ae:
print(f'Assertion Error -> {ae}') self.logs.error(f'Assertion Error -> {ae}')
def garbage_collector_thread(self) -> None: def garbage_collector_thread(self) -> None:
"""Methode qui supprime les threads qui ont finis leurs job """Methode qui supprime les threads qui ont finis leurs job
""" """
try: try:
# self.__debug(f"=======> Checking for Threads to stop")
for thread in self.running_threads: for thread in self.running_threads:
if thread.getName() != 'heartbeat': if thread.getName() != 'heartbeat':
if not thread.is_alive(): if not thread.is_alive():
self.running_threads.remove(thread) self.running_threads.remove(thread)
self.__debug(f"Thread {str(thread.getName())} {str(thread.native_id)} removed") self.logs.debug(f"Thread {str(thread.getName())} {str(thread.native_id)} removed")
# print(threading.enumerate()) # print(threading.enumerate())
except AssertionError as ae: except AssertionError as ae:
self.__debug(f'Assertion Error -> {ae}') self.logs.error(f'Assertion Error -> {ae}')
def garbage_collector_sockets(self) -> None: def garbage_collector_sockets(self) -> None:
# self.__debug(f"=======> Checking for Sockets to stop")
for soc in self.running_sockets: for soc in self.running_sockets:
while soc.fileno() != -1: while soc.fileno() != -1:
self.__debug(soc.fileno()) self.logs.debug(soc.fileno())
soc.close() soc.close()
soc.close() soc.close()
self.running_sockets.remove(soc) self.running_sockets.remove(soc)
self.__debug(f"Socket ==> closed {str(soc.fileno())}") self.logs.debug(f"Socket ==> closed {str(soc.fileno())}")
def shutdown(self) -> None: def shutdown(self) -> None:
"""Methode qui va préparer l'arrêt complêt du service """Methode qui va préparer l'arrêt complêt du service
""" """
# Nettoyage des timers # Nettoyage des timers
print(f"=======> Checking for Timers to stop") self.logs.debug(f"=======> Checking for Timers to stop")
for timer in self.running_timers: for timer in self.running_timers:
while timer.is_alive(): while timer.is_alive():
print(f"> waiting for {timer.getName()} to close") self.logs.debug(f"> waiting for {timer.getName()} to close")
timer.cancel() timer.cancel()
time.sleep(0.2) time.sleep(0.2)
self.running_timers.remove(timer) self.running_timers.remove(timer)
print(f"> Cancelling {timer.getName()} {timer.native_id}") self.logs.debug(f"> Cancelling {timer.getName()} {timer.native_id}")
print(f"=======> Checking for Threads to stop") self.logs.debug(f"=======> Checking for Threads to stop")
for thread in self.running_threads: for thread in self.running_threads:
if thread.getName() == 'heartbeat' and thread.is_alive(): if thread.getName() == 'heartbeat' and thread.is_alive():
self.execute_periodic_action() self.execute_periodic_action()
print(f"> Running the last periodic action") self.logs.debug(f"> Running the last periodic action")
self.running_threads.remove(thread) self.running_threads.remove(thread)
print(f"> Cancelling {thread.getName()} {thread.native_id}") self.logs.debug(f"> Cancelling {thread.getName()} {thread.native_id}")
print(f"=======> Checking for Sockets to stop") self.logs.debug(f"=======> Checking for Sockets to stop")
for soc in self.running_sockets: for soc in self.running_sockets:
soc.close() soc.close()
while soc.fileno() != -1: while soc.fileno() != -1:
soc.close() soc.close()
self.running_sockets.remove(soc) self.running_sockets.remove(soc)
print(f"> Socket ==> closed {str(soc.fileno())}") self.logs.debug(f"> Socket ==> closed {str(soc.fileno())}")
return None return None
def db_init(self) -> tuple[Engine, Connection]: def db_init(self) -> tuple[Engine, Connection]:
db_directory = self.Config.DEFENDER_DB_PATH db_directory = self.SysConfig.DEFENDER_DB_PATH
full_path_db = self.Config.DEFENDER_DB_PATH + self.Config.DEFENDER_DB_NAME full_path_db = self.SysConfig.DEFENDER_DB_PATH + self.SysConfig.DEFENDER_DB_NAME
if not os.path.exists(db_directory): if not os.path.exists(db_directory):
os.makedirs(db_directory) os.makedirs(db_directory)
engine = create_engine(f'sqlite:///{full_path_db}.db', echo=False) engine = create_engine(f'sqlite:///{full_path_db}.db', echo=False)
cursor = engine.connect() cursor = engine.connect()
self.logs.info("database connexion has been initiated")
return engine, cursor return engine, cursor
def __create_db(self) -> None: def __create_db(self) -> None:
@@ -325,7 +371,7 @@ class Base:
try: try:
self.cursor.close() self.cursor.close()
except AttributeError as ae: except AttributeError as ae:
self.__debug(f"Attribute Error : {ae}") self.logs.error(f"Attribute Error : {ae}")
def crypt_password(self, password:str) -> str: def crypt_password(self, password:str) -> str:
"""Retourne un mot de passe chiffré en MD5 """Retourne un mot de passe chiffré en MD5
@@ -396,10 +442,3 @@ class Base:
# Vider le dictionnaire de fonction # Vider le dictionnaire de fonction
self.periodic_func.clear() self.periodic_func.clear()
def __debug(self, debug_msg:str) -> None:
if self.Config.DEBUG == 1:
print(f"[{self.get_datetime()}] - {debug_msg}")
return None

View File

@@ -1,5 +1,3 @@
import os
from typing import Literal, Dict, List
########################################## ##########################################
# CONFIGURATION FILE : # # CONFIGURATION FILE : #
# Rename file to : configuration.py # # Rename file to : configuration.py #
@@ -7,19 +5,15 @@ from typing import Literal, Dict, List
class Config: class Config:
DEFENDER_VERSION = '3.3.2' # MAJOR.MINOR.BATCH SERVEUR_IP = '0.0.0.0' # IP ou host du serveur à rejoindre
DEFENDER_DB_PATH = 'db' + os.sep # Séparateur en fonction de l'OS
DEFENDER_DB_NAME = 'defender' # Le nom de la base de données principale
SERVICE_NAME = 'defender' # Le nom du service
SERVEUR_IP = '8.8.8.8' # IP ou host du serveur à rejoindre
SERVEUR_HOSTNAME = 'your hostname' # Le hostname du serveur IRC SERVEUR_HOSTNAME = 'your hostname' # Le hostname du serveur IRC
SERVEUR_LINK = 'your link' # Host attendu par votre IRCd (ex. dans votre link block pour Unrealircd) SERVEUR_LINK = 'your link' # Host attendu par votre IRCd (ex. dans votre link block pour Unrealircd)
SERVEUR_PORT = 6666 # Port du link SERVEUR_PORT = 6666 # Port du link
SERVEUR_PASSWORD = 'your link password' # Mot de passe du link (Privilégiez argon2 sur Unrealircd) SERVEUR_PASSWORD = 'your link password' # Mot de passe du link (Privilégiez argon2 sur Unrealircd)
SERVEUR_ID = '002' # SID (identification) du bot en tant que Services SERVEUR_ID = '002' # SID (identification) du bot en tant que Services
SERVEUR_SSL = False # Activer / Desactiver la connexion SSL SERVEUR_SSL = True # Activer / Desactiver la connexion SSL
SERVICE_NAME = 'defender' # Le nom du service
SERVICE_NICKNAME = 'BotName' # Nick du bot sur IRC SERVICE_NICKNAME = 'BotName' # Nick du bot sur IRC
SERVICE_REALNAME = 'BotRealname' # Realname du bot SERVICE_REALNAME = 'BotRealname' # Realname du bot
SERVICE_USERNAME = 'BotIdent' # Ident du bot SERVICE_USERNAME = 'BotIdent' # Ident du bot
@@ -45,7 +39,7 @@ class Config:
WHITELISTED_IP = ['127.0.0.1'] # IP a ne pas scanner WHITELISTED_IP = ['127.0.0.1'] # IP a ne pas scanner
GLINE_DURATION = '1d' # La durée du gline GLINE_DURATION = '1d' # La durée du gline
DEBUG = 0 # Afficher l'ensemble des messages du serveurs dans la console DEBUG_LEVEL = 10 # Le niveau des logs DEBUG 10 | INFO 20 | WARNING 30 | ERROR 40 | CRITICAL 50
CONFIG_COLOR = { CONFIG_COLOR = {
'blanche': '\x0300', # Couleur blanche 'blanche': '\x0300', # Couleur blanche

View File

@@ -1,7 +1,9 @@
import ssl, re, importlib, sys, time, threading, socket import ssl, re, importlib, sys, time, threading, socket
from ssl import SSLSocket
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Union from typing import Union
from core.configuration import Config from core.configuration import Config
from core.sys_configuration import SysConfig
from core.base import Base from core.base import Base
class Irc: class Irc:
@@ -16,6 +18,7 @@ class Irc:
self.beat = 30 # Lancer toutes les 30 secondes des actions de nettoyages self.beat = 30 # Lancer toutes les 30 secondes des actions de nettoyages
self.hb_active = True # Heartbeat active self.hb_active = True # Heartbeat active
self.HSID = '' # ID du serveur qui accueil le service ( Host Serveur Id ) self.HSID = '' # ID du serveur qui accueil le service ( Host Serveur Id )
self.IrcSocket:Union[socket.socket, SSLSocket] = None
self.INIT = 1 # Variable d'intialisation | 1 -> indique si le programme est en cours d'initialisation self.INIT = 1 # Variable d'intialisation | 1 -> indique si le programme est en cours d'initialisation
self.RESTART = 0 # Variable pour le redemarrage du bot | 0 -> indique que le programme n'es pas en cours de redemarrage self.RESTART = 0 # Variable pour le redemarrage du bot | 0 -> indique que le programme n'es pas en cours de redemarrage
@@ -23,6 +26,7 @@ class Irc:
self.SSL_VERSION = None # Version SSL self.SSL_VERSION = None # Version SSL
self.Config = Config() self.Config = Config()
self.SysConfig = SysConfig()
# Liste des commandes internes du bot # Liste des commandes internes du bot
self.commands_level = { self.commands_level = {
@@ -49,7 +53,7 @@ class Irc:
self.__create_socket() self.__create_socket()
self.__connect_to_irc(ircInstance) self.__connect_to_irc(ircInstance)
except AssertionError as ae: except AssertionError as ae:
self.debug(f'Assertion error : {ae}') self.Base.logs.critical(f'Assertion error: {ae}')
def __create_socket(self) -> None: def __create_socket(self) -> None:
@@ -59,32 +63,36 @@ class Irc:
if self.Config.SERVEUR_SSL: if self.Config.SERVEUR_SSL:
# Créer un object ssl # Créer un object ssl
ssl_context = self.__ssl_context() ssl_context = self.__ssl_context()
ssl_connexion = ssl_context.wrap_socket(soc, server_hostname=self.Config.SERVEUR_HOSTNAME) ssl_connexion = ssl_context.wrap_socket(soc, server_hostname=self.Config.SERVEUR_HOSTNAME)
ssl_connexion.connect(connexion_information) ssl_connexion.connect(connexion_information)
self.IrcSocket:ssl.SSLSocket = ssl_connexion self.IrcSocket:SSLSocket = ssl_connexion
self.debug(f"Connexion en mode SSL : Version = {self.IrcSocket.version()}")
self.Base.logs.info(f"Connexion en mode SSL : Version = {self.IrcSocket.version()}")
self.SSL_VERSION = self.IrcSocket.version() self.SSL_VERSION = self.IrcSocket.version()
else: else:
soc.connect(connexion_information) soc.connect(connexion_information)
self.IrcSocket:socket = soc self.IrcSocket:socket.socket = soc
self.debug("Connexion en mode normal") self.Base.logs.info("Connexion en mode normal")
return None return None
except ssl.SSLEOFError as soe: except ssl.SSLEOFError as soe:
self.debug(f"SSLEOFError __create_socket: {soe} - {self.IrcSocket.fileno()}") self.Base.logs.critical(f"SSLEOFError __create_socket: {soe} - {soc.fileno()}")
except ssl.SSLError as se: except ssl.SSLError as se:
self.debug(f"SSLError __create_socket: {se} - {self.IrcSocket.fileno()}") self.Base.logs.critical(f"SSLError __create_socket: {se} - {soc.fileno()}")
except OSError as oe: except OSError as oe:
self.debug(f"OSError __create_socket: {oe} - {self.IrcSocket.fileno()}") self.Base.logs.critical(f"OSError __create_socket: {oe} - {soc.fileno()}")
except AttributeError as ae:
self.Base.logs.critical(f"OSError __create_socket: {oe} - {soc.fileno()}")
def __ssl_context(self) -> ssl.SSLContext: def __ssl_context(self) -> ssl.SSLContext:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.check_hostname = False ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE ctx.verify_mode = ssl.CERT_NONE
self.Base.logs.debug(f'SSLContext initiated with verified mode {ctx.verify_mode}')
return ctx return ctx
def __connect_to_irc(self, ircInstance: 'Irc') -> None: def __connect_to_irc(self, ircInstance: 'Irc') -> None:
@@ -97,23 +105,23 @@ class Irc:
while self.signal: while self.signal:
try: try:
if self.RESTART == 1: if self.RESTART == 1:
self.Base.logs.debug('Restarting Defender ...')
self.IrcSocket.shutdown(socket.SHUT_RDWR) self.IrcSocket.shutdown(socket.SHUT_RDWR)
self.IrcSocket.close() self.IrcSocket.close()
while self.IrcSocket.fileno() != -1: while self.IrcSocket.fileno() != -1:
time.sleep(0.5) time.sleep(0.5)
self.debug("--> En attente de la fermeture du socket ...") self.Base.logs.warning('--> Waiting for socket to close ...')
self.__create_socket() self.__create_socket()
self.__link(self.IrcSocket) self.__link(self.IrcSocket)
self.load_existing_modules() self.load_existing_modules()
self.RESTART = 0 self.RESTART = 0
# 4072 max what the socket can grab # 4072 max what the socket can grab
buffer_size = self.IrcSocket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF) buffer_size = self.IrcSocket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)
# data = self.IrcSocket.recv(buffer_size).splitlines(True)
data_in_bytes = self.IrcSocket.recv(buffer_size) data_in_bytes = self.IrcSocket.recv(buffer_size)
data = data_in_bytes.splitlines(True)
count_bytes = len(data_in_bytes) count_bytes = len(data_in_bytes)
while count_bytes > 4070: while count_bytes > 4070:
@@ -121,10 +129,8 @@ class Irc:
new_data = self.IrcSocket.recv(buffer_size) new_data = self.IrcSocket.recv(buffer_size)
data_in_bytes += new_data data_in_bytes += new_data
count_bytes = len(new_data) count_bytes = len(new_data)
# print("========================================================")
data = data_in_bytes.splitlines() data = data_in_bytes.splitlines(True)
# print(f"{str(buffer_size)} - {str(len(data_in_bytes))}")
if not data: if not data:
break break
@@ -132,24 +138,24 @@ class Irc:
self.send_response(data) self.send_response(data)
except ssl.SSLEOFError as soe: except ssl.SSLEOFError as soe:
self.debug(f"SSLEOFError __connect_to_irc: {soe} - {data}") self.Base.logs.error(f"SSLEOFError __connect_to_irc: {soe} - {data}")
except ssl.SSLError as se: except ssl.SSLError as se:
self.debug(f"SSLError __connect_to_irc: {se} - {data}") self.Base.logs.error(f"SSLError __connect_to_irc: {se} - {data}")
except OSError as oe: except OSError as oe:
self.debug(f"SSLError __connect_to_irc: {oe} - {data}") self.Base.logs.error(f"SSLError __connect_to_irc: {oe} - {data}")
# except Exception as e:
# self.debug(f"Exception __connect_to_irc: {e} - {data}")
self.IrcSocket.shutdown(socket.SHUT_RDWR) self.IrcSocket.shutdown(socket.SHUT_RDWR)
self.IrcSocket.close() self.IrcSocket.close()
self.debug("--> Fermeture de Defender ...") self.Base.logs.info("--> Fermeture de Defender ...")
except AssertionError as ae: except AssertionError as ae:
self.debug(f'Assertion error : {ae}') self.Base.logs.error(f'Assertion error : {ae}')
except ValueError as ve: except ValueError as ve:
self.debug(f'Value Error : {ve}') self.Base.logs.error(f'Value Error : {ve}')
except ssl.SSLEOFError as soe: except ssl.SSLEOFError as soe:
self.debug(f"OS Error __connect_to_irc: {soe}") self.Base.logs.error(f"OS Error __connect_to_irc: {soe}")
except AttributeError as atte:
self.Base.logs.critical(f"{atte}")
# except Exception as e: # except Exception as e:
# self.debug(f"Exception: {e}") # self.debug(f"Exception: {e}")
@@ -160,38 +166,43 @@ class Irc:
Args: Args:
writer (StreamWriter): permet l'envoi des informations au serveur. writer (StreamWriter): permet l'envoi des informations au serveur.
""" """
nickname = self.Config.SERVICE_NICKNAME try:
username = self.Config.SERVICE_USERNAME nickname = self.Config.SERVICE_NICKNAME
realname = self.Config.SERVICE_REALNAME username = self.Config.SERVICE_USERNAME
chan = self.Config.SERVICE_CHANLOG realname = self.Config.SERVICE_REALNAME
info = self.Config.SERVICE_INFO chan = self.Config.SERVICE_CHANLOG
smodes = self.Config.SERVICE_SMODES info = self.Config.SERVICE_INFO
cmodes = self.Config.SERVICE_CMODES smodes = self.Config.SERVICE_SMODES
umodes = self.Config.SERVICE_UMODES cmodes = self.Config.SERVICE_CMODES
host = self.Config.SERVICE_HOST umodes = self.Config.SERVICE_UMODES
service_name = self.Config.SERVICE_NAME host = self.Config.SERVICE_HOST
service_name = self.Config.SERVICE_NAME
password = self.Config.SERVEUR_PASSWORD password = self.Config.SERVEUR_PASSWORD
link = self.Config.SERVEUR_LINK link = self.Config.SERVEUR_LINK
sid = self.Config.SERVEUR_ID sid = self.Config.SERVEUR_ID
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
version = self.Config.DEFENDER_VERSION version = self.SysConfig.DEFENDER_VERSION
unixtime = self.Base.get_unixtime() unixtime = self.Base.get_unixtime()
# Envoyer un message d'identification # Envoyer un message d'identification
writer.send(f":{sid} PASS :{password}\r\n".encode('utf-8')) writer.send(f":{sid} PASS :{password}\r\n".encode('utf-8'))
writer.send(f":{sid} PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT MLOCK SID MTAGS\r\n".encode('utf-8')) writer.send(f":{sid} PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT MLOCK SID MTAGS\r\n".encode('utf-8'))
writer.send(f":{sid} PROTOCTL EAUTH={link},,,{service_name}-v{version}\r\n".encode('utf-8')) writer.send(f":{sid} PROTOCTL EAUTH={link},,,{service_name}-v{version}\r\n".encode('utf-8'))
writer.send(f":{sid} PROTOCTL SID={sid}\r\n".encode('utf-8')) writer.send(f":{sid} PROTOCTL SID={sid}\r\n".encode('utf-8'))
writer.send(f":{sid} SERVER {link} 1 :{info}\r\n".encode('utf-8')) writer.send(f":{sid} SERVER {link} 1 :{info}\r\n".encode('utf-8'))
writer.send(f":{sid} {nickname} :Reserved for services\r\n".encode('utf-8')) writer.send(f":{sid} {nickname} :Reserved for services\r\n".encode('utf-8'))
writer.send(f":{sid} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * * :{realname}\r\n".encode('utf-8')) writer.send(f":{sid} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * * :{realname}\r\n".encode('utf-8'))
writer.send(f":{sid} SJOIN {unixtime} {chan} + :{service_id}\r\n".encode('utf-8')) writer.send(f":{sid} SJOIN {unixtime} {chan} + :{service_id}\r\n".encode('utf-8'))
writer.send(f":{sid} MODE {chan} +{cmodes}\r\n".encode('utf-8')) writer.send(f":{sid} MODE {chan} +{cmodes}\r\n".encode('utf-8'))
writer.send(f":{service_id} SAMODE {chan} +{umodes} {nickname}\r\n".encode('utf-8')) writer.send(f":{service_id} SAMODE {chan} +{umodes} {nickname}\r\n".encode('utf-8'))
return None self.Base.logs.debug('Link information sent to the server')
return None
except AttributeError as ae:
self.Base.logs.critical(f'{ae}')
def send2socket(self, send_message:str) -> None: def send2socket(self, send_message:str) -> None:
"""Envoit les commandes à envoyer au serveur. """Envoit les commandes à envoyer au serveur.
@@ -203,21 +214,22 @@ class Irc:
with self.Base.lock: with self.Base.lock:
# print(f">{str(send_message)}") # 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}')
except UnicodeDecodeError: except UnicodeDecodeError:
self.debug('Write Decode impossible try iso-8859-1') self.Base.logs.error(f'Decode Error try iso-8859-1 - message: {send_message}')
self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0],'replace')) self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0],'replace'))
except UnicodeEncodeError: except UnicodeEncodeError:
self.debug('Write Encode impossible ... try iso-8859-1') self.Base.logs.error(f'Encode Error try iso-8859-1 - message: {send_message}')
self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0],'replace')) self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0],'replace'))
except AssertionError as ae: except AssertionError as ae:
self.debug(f"Assertion error : {ae}") self.Base.logs.warning(f'Assertion Error {ae} - message: {send_message}')
except ssl.SSLEOFError as soe: except ssl.SSLEOFError as soe:
self.debug(f"SSLEOFError send2socket: {soe} - {send_message}") self.Base.logs.error(f"SSLEOFError: {soe} - {send_message}")
except ssl.SSLError as se: except ssl.SSLError as se:
self.debug(f"SSLError send2socket: {se} - {send_message}") self.Base.logs.error(f"SSLError: {se} - {send_message}")
except OSError as oe: except OSError as oe:
self.debug(f"OSError send2socket: {oe} - {send_message}") self.Base.logs.error(f"OSError: {oe} - {send_message}")
def send_response(self, responses:list[bytes]) -> None: def send_response(self, responses:list[bytes]) -> None:
try: try:
@@ -225,6 +237,7 @@ class Irc:
for data in responses: for data in responses:
response = data.decode(self.CHARSET[0]).split() response = data.decode(self.CHARSET[0]).split()
self.cmd(response) self.cmd(response)
except UnicodeEncodeError: except UnicodeEncodeError:
for data in responses: for data in responses:
response = data.decode(self.CHARSET[1],'replace').split() response = data.decode(self.CHARSET[1],'replace').split()
@@ -234,7 +247,8 @@ class Irc:
response = data.decode(self.CHARSET[1],'replace').split() response = data.decode(self.CHARSET[1],'replace').split()
self.cmd(response) self.cmd(response)
except AssertionError as ae: except AssertionError as ae:
self.debug(f"Assertion error : {ae}") self.Base.logs.error(f"Assertion error : {ae}")
############################################## ##############################################
# FIN CONNEXION IRC # # FIN CONNEXION IRC #
############################################## ##############################################
@@ -284,7 +298,7 @@ class Irc:
# 2. Executer la fonction # 2. Executer la fonction
try: try:
if not class_name in self.loaded_classes: if not class_name in self.loaded_classes:
self.debug(f"La class [{class_name} n'existe pas !!]") self.Base.logs.error(f"La class [{class_name} n'existe pas !!]")
return False return False
class_instance = self.loaded_classes[class_name] class_instance = self.loaded_classes[class_name]
@@ -294,12 +308,12 @@ class Irc:
self.Base.running_timers.append(t) self.Base.running_timers.append(t)
self.debug(f"Timer ID : {str(t.ident)} | Running Threads : {len(threading.enumerate())}") self.Base.logs.debug(f"Timer ID : {str(t.ident)} | Running Threads : {len(threading.enumerate())}")
except AssertionError as ae: except AssertionError as ae:
self.debug(f'Assertion Error -> {ae}') self.Base.logs.error(f'Assertion Error -> {ae}')
except TypeError as te: except TypeError as te:
self.debug(f"Type error -> {te}") self.Base.logs.error(f"Type error -> {te}")
def __create_tasks(self, obj: object, method_name: str, param:list) -> None: def __create_tasks(self, obj: object, method_name: str, param:list) -> None:
"""#### Ajouter les méthodes a éxecuter dans un dictionnaire """#### Ajouter les méthodes a éxecuter dans un dictionnaire
@@ -318,7 +332,7 @@ class Irc:
'param': param 'param': param
} }
self.debug(f'Function to execute : {str(self.Base.periodic_func)}') self.Base.logs.debug(f'Function to execute : {str(self.Base.periodic_func)}')
self.send_ping_to_sereur() self.send_ping_to_sereur()
return None return None
@@ -332,7 +346,6 @@ class Irc:
return None return None
def load_module(self, fromuser:str, module_name:str, init:bool = False) -> bool: def load_module(self, fromuser:str, module_name:str, init:bool = False) -> bool:
try: try:
# module_name : mod_voice # module_name : mod_voice
module_name = module_name.lower() module_name = module_name.lower()
@@ -342,8 +355,8 @@ class Irc:
# Si le module est déja chargé # Si le module est déja chargé
if 'mods.' + module_name in sys.modules: if 'mods.' + module_name in sys.modules:
self.debug("Module déja chargé ...") self.Base.logs.info("Module déja chargé ...")
self.debug('module name = ' + module_name) self.Base.logs.info('module name = ' + module_name)
if class_name in self.loaded_classes: if class_name in self.loaded_classes:
# Si le module existe dans la variable globale retourne False # Si le module existe dans la variable globale retourne False
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Le module {module_name} est déja chargé ! si vous souhaiter le recharge tapez {self.Config.SERVICE_PREFIX}reload {module_name}") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Le module {module_name} est déja chargé ! si vous souhaiter le recharge tapez {self.Config.SERVICE_PREFIX}reload {module_name}")
@@ -374,14 +387,14 @@ class Irc:
self.Base.db_record_module(fromuser, module_name) self.Base.db_record_module(fromuser, module_name)
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} chargé") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} chargé")
self.debug(self.loaded_classes) self.Base.logs.info(self.loaded_classes)
return True return True
except ModuleNotFoundError as moduleNotFound: except ModuleNotFoundError as moduleNotFound:
self.debug(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.CONFIG_COLOR['rouge']}MODULE_NOT_FOUND{self.Config.CONFIG_COLOR['noire']} ]: {moduleNotFound}")
except Exception as e: except Exception as e:
self.debug(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}")
def insert_db_uid(self, uid:str, nickname:str, username:str, hostname:str, umodes:str, vhost:str, isWebirc: bool) -> None: def insert_db_uid(self, uid:str, nickname:str, username:str, hostname:str, umodes:str, vhost:str, isWebirc: bool) -> None:
@@ -431,10 +444,10 @@ class Irc:
if oldnickname in self.db_uid: if oldnickname in self.db_uid:
del self.db_uid[oldnickname] del self.db_uid[oldnickname]
else: else:
self.debug(f"L'ancien nickname {oldnickname} n'existe pas dans UID_DB") self.Base.logs.debug(f"L'ancien nickname {oldnickname} n'existe pas dans UID_DB")
response = False response = False
self.debug(f"{oldnickname} changed to {newnickname}") self.Base.logs.debug(f"{oldnickname} changed to {newnickname}")
return None return None
@@ -519,7 +532,7 @@ class Irc:
# Supprimer les doublons de la liste # Supprimer les doublons de la liste
self.db_chan = list(set(self.db_chan)) self.db_chan = list(set(self.db_chan))
self.debug(f"Le salon {channel} a été ajouté à la liste CHAN_DB") self.Base.logs.debug(f"Le salon {channel} a été ajouté à la liste CHAN_DB")
return response return response
@@ -530,13 +543,13 @@ class Irc:
if level > 4: if level > 4:
response = "Impossible d'ajouter un niveau > 4" response = "Impossible d'ajouter un niveau > 4"
self.debug(response) self.Base.logs.warning(response)
return response return response
# Verification si le user existe dans notre UID_DB # Verification si le user existe dans notre UID_DB
if not nickname in self.db_uid: if not nickname in self.db_uid:
response = f"{nickname} n'est pas connecté, impossible de l'enregistrer pour le moment" response = f"{nickname} n'est pas connecté, impossible de l'enregistrer pour le moment"
self.debug(response) self.Base.logs.warning(response)
return response return response
hostname = self.db_uid[nickname]['hostname'] hostname = self.db_uid[nickname]['hostname']
@@ -557,12 +570,12 @@ class Irc:
''', mes_donnees) ''', mes_donnees)
response = f"{nickname} ajouté en tant qu'administrateur de niveau {level}" response = f"{nickname} ajouté en tant qu'administrateur de niveau {level}"
self.send2socket(f':{self.Config.SERVICE_NICKNAME} NOTICE {nickname} : {response}') self.send2socket(f':{self.Config.SERVICE_NICKNAME} NOTICE {nickname} : {response}')
self.debug(response) self.Base.logs.info(response)
return response return response
else: else:
response = f'{nickname} Existe déjà dans les users enregistrés' response = f'{nickname} Existe déjà dans les users enregistrés'
self.send2socket(f':{self.Config.SERVICE_NICKNAME} NOTICE {nickname} : {response}') self.send2socket(f':{self.Config.SERVICE_NICKNAME} NOTICE {nickname} : {response}')
self.debug(response) self.Base.logs.info(response)
return response return response
def get_uid(self, uidornickname:str) -> Union[str, None]: def get_uid(self, uidornickname:str) -> Union[str, None]:
@@ -636,6 +649,7 @@ class Irc:
def cmd(self, data:list) -> None: def cmd(self, data:list) -> None:
try: try:
cmd_to_send:list[str] = data.copy() cmd_to_send:list[str] = data.copy()
cmd = data.copy() cmd = data.copy()
@@ -643,9 +657,19 @@ class Irc:
cmd_to_debug.pop(0) cmd_to_debug.pop(0)
if len(cmd) == 0 or len(cmd) == 1: if len(cmd) == 0 or len(cmd) == 1:
self.Base.logs.warning(f'Size ({str(len(cmd))}) - {cmd}')
return False return False
self.debug(cmd_to_debug) # self.debug(cmd_to_debug)
if len(data) == 7:
if data[2] == 'PRIVMSG' and data[4] == ':auth':
data_copy = data.copy()
data_copy[6] = '**********'
self.Base.logs.debug(data_copy)
else:
self.Base.logs.debug(data)
else:
self.Base.logs.debug(data)
match cmd[0]: match cmd[0]:
@@ -687,8 +711,8 @@ class Irc:
# self.Base.create_thread(self.abuseipdb_scan, (cmd[2], )) # self.Base.create_thread(self.abuseipdb_scan, (cmd[2], ))
pass pass
# Possibilité de déclancher les bans a ce niveau. # Possibilité de déclancher les bans a ce niveau.
except IndexError: except IndexError as ie:
self.debug(f'cmd reputation: index error') self.Base.logs.error(f'{ie}')
case '320': case '320':
#:irc.deb.biz.st 320 PyDefender IRCParis07 :is in security-groups: known-users,webirc-users,tls-and-known-users,tls-users #:irc.deb.biz.st 320 PyDefender IRCParis07 :is in security-groups: known-users,webirc-users,tls-and-known-users,tls-users
@@ -717,9 +741,20 @@ class Irc:
print(f"# SSL VER : {self.SSL_VERSION} ") print(f"# SSL VER : {self.SSL_VERSION} ")
print(f"# NICKNAME : {self.Config.SERVICE_NICKNAME} ") print(f"# NICKNAME : {self.Config.SERVICE_NICKNAME} ")
print(f"# CHANNEL : {self.Config.SERVICE_CHANLOG} ") print(f"# CHANNEL : {self.Config.SERVICE_CHANLOG} ")
print(f"# VERSION : {self.Config.DEFENDER_VERSION} ") print(f"# VERSION : {self.SysConfig.DEFENDER_VERSION} ")
print(f"################################################") print(f"################################################")
self.Base.logs.info(f"################### DEFENDER ###################")
self.Base.logs.info(f"# SERVICE CONNECTE ")
self.Base.logs.info(f"# SERVEUR : {self.Config.SERVEUR_IP} ")
self.Base.logs.info(f"# PORT : {self.Config.SERVEUR_PORT} ")
self.Base.logs.info(f"# SSL : {self.Config.SERVEUR_SSL} ")
self.Base.logs.info(f"# SSL VER : {self.SSL_VERSION} ")
self.Base.logs.info(f"# NICKNAME : {self.Config.SERVICE_NICKNAME} ")
self.Base.logs.info(f"# CHANNEL : {self.Config.SERVICE_CHANLOG} ")
self.Base.logs.info(f"# VERSION : {self.SysConfig.DEFENDER_VERSION} ")
self.Base.logs.info(f"################################################")
# Initialisation terminé aprés le premier PING # Initialisation terminé aprés le premier PING
self.INIT = 0 self.INIT = 0
# self.send2socket(f':{self.Config.SERVICE_ID} PING :{hsid}') # self.send2socket(f':{self.Config.SERVICE_ID} PING :{hsid}')
@@ -785,6 +820,15 @@ class Irc:
cmd.pop(0) cmd.pop(0)
get_uid_or_nickname = str(cmd[0].replace(':','')) get_uid_or_nickname = str(cmd[0].replace(':',''))
if len(cmd) == 6:
if cmd[1] == 'PRIVMSG' and cmd[3] == ':auth':
cmd_copy = cmd.copy()
cmd_copy[5] = '**********'
self.Base.logs.debug(cmd_copy)
else:
self.Base.logs.info(cmd)
else:
self.Base.logs.info(f'{cmd}')
# user_trigger = get_user.split('!')[0] # user_trigger = get_user.split('!')[0]
user_trigger = self.get_nickname(get_uid_or_nickname) user_trigger = self.get_nickname(get_uid_or_nickname)
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.Config.SERVICE_NICKNAME
@@ -818,7 +862,7 @@ class Irc:
# Réponse a un CTCP VERSION # Réponse a un CTCP VERSION
if arg[0] == '\x01VERSION\x01': if arg[0] == '\x01VERSION\x01':
self.send2socket(f':{dnickname} NOTICE {user_trigger} :\x01VERSION Service {self.Config.SERVICE_NICKNAME} V{self.Config.DEFENDER_VERSION}\x01') self.send2socket(f':{dnickname} NOTICE {user_trigger} :\x01VERSION Service {self.Config.SERVICE_NICKNAME} V{self.SysConfig.DEFENDER_VERSION}\x01')
return False return False
# Réponse a un TIME # Réponse a un TIME
@@ -844,8 +888,8 @@ class Irc:
self._hcmds(user_trigger, arg) self._hcmds(user_trigger, arg)
except IndexError: except IndexError as io:
self.debug(f'cmd --> PRIVMSG --> List index out of range') self.Base.logs.error(f'{io}')
case _: case _:
pass pass
@@ -856,7 +900,7 @@ class Irc:
classe_object.cmd(cmd_to_send) classe_object.cmd(cmd_to_send)
except IndexError as ie: except IndexError as ie:
self.debug(f"IRC CMD -> IndexError : {ie} - {cmd} - length {str(len(cmd))}") self.Base.logs.error(f"{ie} / {cmd} / length {str(len(cmd))}")
def _hcmds(self, user: str, cmd:list) -> None: def _hcmds(self, user: str, cmd:list) -> None:
@@ -888,8 +932,8 @@ class Irc:
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.get_nickname(fromuser)}') self.send2socket(f':{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR["rouge"]}{current_command}{self.Config.CONFIG_COLOR["noire"]} ] - Accès Refusé à {self.get_nickname(fromuser)}')
self.send2socket(f':{dnickname} NOTICE {fromuser} : Accès Refusé') self.send2socket(f':{dnickname} NOTICE {fromuser} : Accès Refusé')
except IndexError: except IndexError as ie:
self.debug(f'_hcmd notallowed : Index Error') self.Base.logs.error(f'{ie}')
case 'deauth': case 'deauth':
@@ -914,6 +958,7 @@ class Irc:
uid_user = self.get_uid(user_to_log) uid_user = self.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.get_nickname(fromuser)} est désormais connecté a {dnickname}") self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}{current_command}{self.Config.CONFIG_COLOR['noire']} ] - {self.get_nickname(fromuser)} est désormais connecté a {dnickname}")
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.get_nickname(fromuser)} a tapé un mauvais mot de pass") self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}{current_command}{self.Config.CONFIG_COLOR['noire']} ] - {self.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")
@@ -930,13 +975,13 @@ class Irc:
response = self.create_defender_user(newnickname, newlevel, password) response = self.create_defender_user(newnickname, newlevel, password)
self.send2socket(f':{dnickname} NOTICE {fromuser} : {response}') self.send2socket(f':{dnickname} NOTICE {fromuser} : {response}')
self.debug(response) self.Base.logs.info(response)
except IndexError as ie: except IndexError as ie:
self.debug(f'_hcmd addaccess: {ie}') self.Base.logs.error(f'_hcmd addaccess: {ie}')
self.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} addaccess [nickname] [level] [password]') self.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} addaccess [nickname] [level] [password]')
except TypeError as te: except TypeError as te:
self.debug(f'_hcmd addaccess: out of index : {te}') self.Base.logs.error(f'_hcmd addaccess: out of index : {te}')
self.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} addaccess [nickname] [level] [password]') self.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} addaccess [nickname] [level] [password]')
case 'editaccess': case 'editaccess':
@@ -984,9 +1029,9 @@ class Irc:
self.send2socket(f":{dnickname} NOTICE {fromuser} : Impossible de modifier l'utilisateur {str(user_new_level)}") self.send2socket(f":{dnickname} NOTICE {fromuser} : Impossible de modifier l'utilisateur {str(user_new_level)}")
except TypeError as te: except TypeError as te:
self.debug(f"Type error : {te}") self.Base.logs.error(f"Type error : {te}")
except ValueError as ve: except ValueError as ve:
self.debug(f"Value Error : {ve}") self.Base.logs.error(f"Value Error : {ve}")
self.send2socket(f':{dnickname} NOTICE {fromuser} : .editaccess [USER] [NEWPASSWORD] [NEWLEVEL]') self.send2socket(f':{dnickname} NOTICE {fromuser} : .editaccess [USER] [NEWPASSWORD] [NEWLEVEL]')
case 'delaccess': case 'delaccess':
@@ -996,9 +1041,9 @@ class Irc:
if user_to_del != user_confirmation: if user_to_del != user_confirmation:
self.send2socket(f':{dnickname} NOTICE {fromuser} : Les user ne sont pas les mêmes, tu dois confirmer le user que tu veux supprimer') self.send2socket(f':{dnickname} NOTICE {fromuser} : Les user ne sont pas les mêmes, tu dois confirmer le user que tu veux supprimer')
self.Base.logs.warning(f':{dnickname} NOTICE {fromuser} : Les user ne sont pas les mêmes, tu dois confirmer le user que tu veux supprimer')
return None return None
print(len(cmd))
if len(cmd) < 3: if len(cmd) < 3:
self.send2socket(f':{dnickname} NOTICE {fromuser} : .delaccess [USER] [CONFIRMUSER]') self.send2socket(f':{dnickname} NOTICE {fromuser} : .delaccess [USER] [CONFIRMUSER]')
return None return None
@@ -1017,6 +1062,7 @@ class Irc:
level_user_to_del = info_user[1] level_user_to_del = info_user[1]
if current_user_level <= level_user_to_del: if current_user_level <= level_user_to_del:
self.send2socket(f':{dnickname} NOTICE {fromuser} : You are not allowed to delete this access') self.send2socket(f':{dnickname} NOTICE {fromuser} : You are not allowed to delete this access')
self.Base.logs.warning(f':{dnickname} NOTICE {fromuser} : You are not allowed to delete this access')
return None return None
data_to_delete = {'user': user_to_del} data_to_delete = {'user': user_to_del}
@@ -1026,6 +1072,7 @@ class Irc:
self.send2socket(f':{dnickname} NOTICE {fromuser} : User {user_to_del} has been deleted !') self.send2socket(f':{dnickname} NOTICE {fromuser} : User {user_to_del} has been deleted !')
else: else:
self.send2socket(f":{dnickname} NOTICE {fromuser} : Impossible de supprimer l'utilisateur.") self.send2socket(f":{dnickname} NOTICE {fromuser} : Impossible de supprimer l'utilisateur.")
self.Base.logs.warning(f":{dnickname} NOTICE {fromuser} : Impossible de supprimer l'utilisateur.")
case 'help': case 'help':
@@ -1083,7 +1130,7 @@ class Irc:
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} supprimé") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} supprimé")
except: except:
self.debug(f"Something went wrong with a module you want to load") self.Base.logs.error(f"Something went wrong with a module you want to load")
case 'reload': case 'reload':
# reload mod_dktmb # reload mod_dktmb
@@ -1093,7 +1140,7 @@ class Irc:
if 'mods.' + module_name in sys.modules: if 'mods.' + module_name in sys.modules:
self.loaded_classes[class_name].unload() self.loaded_classes[class_name].unload()
self.debug('Module Already Loaded ... reload the module ...') self.Base.logs.info('Module Already Loaded ... reload the module ...')
the_module = sys.modules['mods.' + module_name] the_module = sys.modules['mods.' + module_name]
importlib.reload(the_module) importlib.reload(the_module)
@@ -1117,7 +1164,7 @@ class Irc:
else: else:
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} n'est pas chargé !") self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} n'est pas chargé !")
except: except:
self.debug(f"Something went wrong with a module you want to reload") self.Base.logs.error(f"Something went wrong with a module you want to reload")
case 'quit': case 'quit':
try: try:
@@ -1132,12 +1179,12 @@ class Irc:
self.send2socket(f':{dnickname} NOTICE {fromuser} : Arrêt du service {dnickname}') self.send2socket(f':{dnickname} NOTICE {fromuser} : Arrêt du service {dnickname}')
self.send2socket(f':{self.Config.SERVEUR_LINK} SQUIT {self.Config.SERVEUR_LINK} :{final_reason}') self.send2socket(f':{self.Config.SERVEUR_LINK} SQUIT {self.Config.SERVEUR_LINK} :{final_reason}')
self.debug(f'Arrêt du server {dnickname}') self.Base.logs.info(f'Arrêt du server {dnickname}')
self.RESTART = 0 self.RESTART = 0
self.signal = False self.signal = False
except IndexError: except IndexError as ie:
self.debug('_hcmd die: out of index') self.Base.logs.error(f'{ie}')
self.send2socket(f"QUIT Good bye") self.send2socket(f"QUIT Good bye")
@@ -1155,14 +1202,14 @@ class Irc:
self.send2socket(f':{dnickname} NOTICE {fromuser} : Redémarrage du service {dnickname}') self.send2socket(f':{dnickname} NOTICE {fromuser} : Redémarrage du service {dnickname}')
self.send2socket(f':{self.Config.SERVEUR_LINK} SQUIT {self.Config.SERVEUR_LINK} :{final_reason}') self.send2socket(f':{self.Config.SERVEUR_LINK} SQUIT {self.Config.SERVEUR_LINK} :{final_reason}')
self.debug(f'Redémarrage du server {dnickname}') self.Base.logs.info(f'Redémarrage du server {dnickname}')
self.loaded_classes.clear() self.loaded_classes.clear()
self.RESTART = 1 # Set restart status to 1 saying that the service will restart self.RESTART = 1 # Set restart status to 1 saying that the service will restart
self.INIT = 1 # set init to 1 saying that the service will be re initiated self.INIT = 1 # set init to 1 saying that the service will be re initiated
case 'show_modules': case 'show_modules':
self.debug(self.loaded_classes) self.Base.logs.debug(self.loaded_classes)
results = self.Base.db_execute_query(f'SELECT module FROM {self.Base.DB_SCHEMA["modules"]}') results = self.Base.db_execute_query(f'SELECT module FROM {self.Base.DB_SCHEMA["modules"]}')
results = results.fetchall() results = results.fetchall()
@@ -1173,13 +1220,11 @@ class Irc:
for r in results: for r in results:
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :Le module {r[0]} chargé") self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :Le module {r[0]} chargé")
self.debug(r[0])
case 'show_timers': case 'show_timers':
if self.Base.running_timers: if self.Base.running_timers:
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :{self.Base.running_timers}") self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :{self.Base.running_timers}")
self.debug(self.Base.running_timers)
else: else:
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :Aucun timers en cours d'execution") self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :Aucun timers en cours d'execution")
@@ -1196,7 +1241,7 @@ class Irc:
self.send2socket(f':{dnickname} NOTICE {fromuser} : {uptime}') self.send2socket(f':{dnickname} NOTICE {fromuser} : {uptime}')
case 'copyright': case 'copyright':
self.send2socket(f':{dnickname} NOTICE {fromuser} : # Defender V.{self.Config.DEFENDER_VERSION} Developped by adator® and dktmb® #') self.send2socket(f':{dnickname} NOTICE {fromuser} : # Defender V.{self.SysConfig.DEFENDER_VERSION} Developped by adator® and dktmb® #')
case 'sentinel': case 'sentinel':
# .sentinel on # .sentinel on

22
core/sys_configuration.py Normal file
View File

@@ -0,0 +1,22 @@
import os, json
####################################################################################################
# DO NOT TOUCH THIS FILE #
####################################################################################################
class SysConfig:
DEFENDER_VERSION = '4.0.0' # MAJOR.MINOR.BATCH
LATEST_DEFENDER_VERSION = '0.0.0' # Latest Version of Defender in git
DEFENDER_DB_PATH = 'db' + os.sep # Séparateur en fonction de l'OS
DEFENDER_DB_NAME = 'defender' # Le nom de la base de données principale
def __init__(self) -> None:
version_filename = f'.{os.sep}version.json'
with open(version_filename, 'r') as version_data:
self.global_configuration:dict[str, str] = json.load(version_data)
self.DEFENDER_VERSION = self.global_configuration["version"]
return None

View File

@@ -37,7 +37,7 @@ class Defender():
self.localscan_isRunning:bool = True self.localscan_isRunning:bool = True
self.reputationTimer_isRunning:bool = True self.reputationTimer_isRunning:bool = True
self.Irc.debug(f'Module {self.__class__.__name__} loaded ...') self.Irc.Base.logs.info(f'Module {self.__class__.__name__} loaded ...')
# Créer les nouvelles commandes du module # Créer les nouvelles commandes du module
self.commands_level = { self.commands_level = {
@@ -128,7 +128,9 @@ class Defender():
self.db_reputation = {} # Definir la variable qui contiendra la liste des user concerné par la réputation self.db_reputation = {} # Definir la variable qui contiendra la liste des user concerné par la réputation
self.flood_system = {} # Variable qui va contenir les users self.flood_system = {} # Variable qui va contenir les users
self.reputation_first_connexion = {'ip': '', 'score': -1} # Contient les premieres informations de connexion self.reputation_first_connexion = {'ip': '', 'score': -1} # Contient les premieres informations de connexion
# 13c34603fee4d2941a2c443cc5c77fd750757ca2a2c1b304bd0f418aff80c24be12651d1a3cfe674
self.abuseipdb_key = '13c34603fee4d2941a2c443cc5c77fd750757ca2a2c1b304bd0f418aff80c24be12651d1a3cfe674' # Laisser vide si aucune clé self.abuseipdb_key = '13c34603fee4d2941a2c443cc5c77fd750757ca2a2c1b304bd0f418aff80c24be12651d1a3cfe674' # Laisser vide si aucune clé
# r1gEtjtfgRQjtNBDMxsg
self.cloudfilt_key = 'r1gEtjtfgRQjtNBDMxsg' # Laisser vide si aucune clé self.cloudfilt_key = 'r1gEtjtfgRQjtNBDMxsg' # Laisser vide si aucune clé
# Rejoindre les salons # Rejoindre les salons
@@ -179,7 +181,7 @@ class Defender():
insert = self.Base.db_execute_query('INSERT INTO def_config (datetime, parameter, value) VALUES (:datetime, :parameter, :value)', mes_donnees) insert = self.Base.db_execute_query('INSERT INTO def_config (datetime, parameter, value) VALUES (:datetime, :parameter, :value)', mes_donnees)
insert_rows = insert.rowcount insert_rows = insert.rowcount
if insert_rows > 0: if insert_rows > 0:
self.Irc.debug(f'Row affected into def_config : {insert_rows}') self.Irc.Base.logs.debug(f'Row affected into def_config : {insert_rows}')
# Inserer une nouvelle configuration # Inserer une nouvelle configuration
for param, value in self.defConfig.items(): for param, value in self.defConfig.items():
@@ -193,7 +195,7 @@ class Defender():
insert = self.Base.db_execute_query('INSERT INTO def_config (datetime, parameter, value) VALUES (:datetime, :parameter, :value)', mes_donnees) insert = self.Base.db_execute_query('INSERT INTO def_config (datetime, parameter, value) VALUES (:datetime, :parameter, :value)', mes_donnees)
insert_rows = insert.rowcount insert_rows = insert.rowcount
if insert_rows > 0: if insert_rows > 0:
self.Irc.debug(f'DB_Def_config - new param included : {insert_rows}') self.Irc.Base.logs.debug(f'DB_Def_config - new param included : {insert_rows}')
# Supprimer un parameter si il n'existe plus dans la variable global # Supprimer un parameter si il n'existe plus dans la variable global
query = "SELECT parameter FROM def_config" query = "SELECT parameter FROM def_config"
@@ -206,7 +208,7 @@ class Defender():
delete = self.Base.db_execute_query('DELETE FROM def_config WHERE parameter = :parameter', mes_donnees) delete = self.Base.db_execute_query('DELETE FROM def_config WHERE parameter = :parameter', mes_donnees)
row_affected = delete.rowcount row_affected = delete.rowcount
if row_affected > 0: if row_affected > 0:
self.Irc.debug(f'DB_Def_config - param [{dbparam[0]}] has been deleted') self.Irc.Base.logs.debug(f'DB_Def_config - param [{dbparam[0]}] has been deleted')
# Synchroniser la base de données avec la variable global # Synchroniser la base de données avec la variable global
query = "SELECT parameter, value FROM def_config" query = "SELECT parameter, value FROM def_config"
@@ -216,13 +218,13 @@ class Defender():
for param, value in result: for param, value in result:
self.defConfig[param] = self.Base.int_if_possible(value) self.defConfig[param] = self.Base.int_if_possible(value)
self.Irc.debug(self.defConfig) self.Irc.Base.logs.debug(self.defConfig)
return None return None
def update_db_configuration(self, param:str, value:str) -> None: def update_db_configuration(self, param:str, value:str) -> None:
if not param in self.defConfig: if not param in self.defConfig:
self.Irc.debug(f"Le parametre {param} n'existe pas dans la variable global") self.Irc.Base.logs.error(f"Le parametre {param} n'existe pas dans la variable global")
return None return None
mes_donnees = {'parameter': param} mes_donnees = {'parameter': param}
@@ -236,9 +238,9 @@ class Defender():
updated_rows = update.rowcount updated_rows = update.rowcount
if updated_rows > 0: if updated_rows > 0:
self.defConfig[param] = self.Base.int_if_possible(value) self.defConfig[param] = self.Base.int_if_possible(value)
self.Irc.debug(f'DB_Def_config - new param updated : {param} {value}') self.Irc.Base.logs.debug(f'DB_Def_config - new param updated : {param} {value}')
self.Irc.debug(self.defConfig) self.Irc.Base.logs.debug(self.defConfig)
def add_defender_channel(self, channel:str) -> bool: def add_defender_channel(self, channel:str) -> bool:
"""Cette fonction ajoute les salons de join de Defender """Cette fonction ajoute les salons de join de Defender
@@ -305,7 +307,7 @@ class Defender():
secret_code = self.Base.get_random(8) secret_code = self.Base.get_random(8)
if not uid in self.Irc.db_uid: if not uid in self.Irc.db_uid:
self.Irc.debug(f'Etrange UID {uid}') self.Irc.Base.logs.error(f'Etrange UID {uid}')
return None return None
if uid in self.db_reputation: if uid in self.db_reputation:
@@ -313,7 +315,7 @@ class Defender():
self.db_reputation[uid]['updated_datetime'] = currentDateTime self.db_reputation[uid]['updated_datetime'] = currentDateTime
self.db_reputation[uid]['secret_code'] = secret_code self.db_reputation[uid]['secret_code'] = secret_code
else: else:
self.Irc.debug(f"L'UID {uid} n'existe pas dans REPUTATION_DB") self.Irc.Base.logs.error(f"L'UID {uid} n'existe pas dans REPUTATION_DB")
return None return None
@@ -328,7 +330,7 @@ class Defender():
if uid in self.db_reputation: if uid in self.db_reputation:
# Si le nickname existe dans le dictionnaire alors le supprimer # Si le nickname existe dans le dictionnaire alors le supprimer
del self.db_reputation[uid] del self.db_reputation[uid]
self.Irc.debug(f"Le UID {uid} a été supprimé du REPUTATION_DB") self.Irc.Base.logs.debug(f"Le UID {uid} a été supprimé du REPUTATION_DB")
def insert_db_trusted(self, uid: str, nickname:str) -> None: def insert_db_trusted(self, uid: str, nickname:str) -> None:
@@ -437,15 +439,15 @@ class Defender():
self.Irc.send2socket(f":{service_id} MODE {chan} +b {jailed_nickname}!*@*") self.Irc.send2socket(f":{service_id} MODE {chan} +b {jailed_nickname}!*@*")
self.Irc.send2socket(f":{service_id} KICK {chan} {jailed_nickname}") self.Irc.send2socket(f":{service_id} KICK {chan} {jailed_nickname}")
self.Irc.debug(f"system_reputation : {jailed_nickname} à été capturé par le système de réputation") self.Irc.Base.logs.info(f"system_reputation : {jailed_nickname} à été capturé par le système de réputation")
# self.Irc.create_ping_timer(int(self.defConfig['reputation_timer']) * 60, 'Defender', 'system_reputation_timer') # self.Irc.create_ping_timer(int(self.defConfig['reputation_timer']) * 60, 'Defender', 'system_reputation_timer')
# self.Base.create_timer(int(self.defConfig['reputation_timer']) * 60, self.system_reputation_timer) # self.Base.create_timer(int(self.defConfig['reputation_timer']) * 60, self.system_reputation_timer)
else: else:
self.Irc.debug(f"system_reputation : {jailed_nickname} à été supprimé du système de réputation car connecté via WebIrc ou il est dans la 'Trusted list'") self.Irc.Base.logs.info(f"system_reputation : {jailed_nickname} à été supprimé du système de réputation car connecté via WebIrc ou il est dans la 'Trusted list'")
self.delete_db_reputation(uid) self.delete_db_reputation(uid)
except IndexError as e: except IndexError as e:
self.Irc.debug(f"system_reputation : {str(e)}") self.Irc.Base.logs.error(f"system_reputation : {str(e)}")
def system_reputation_timer(self) -> None: def system_reputation_timer(self) -> None:
try: try:
@@ -464,7 +466,6 @@ class Defender():
elif reputation_timer == 0: elif reputation_timer == 0:
return None return None
# self.Irc.debug(self.db_reputation)
uid_to_clean = [] uid_to_clean = []
for uid in self.db_reputation: for uid in self.db_reputation:
@@ -476,9 +477,7 @@ class Defender():
# return False # return False
self.Irc.send2socket(f":{service_id} KILL {self.db_reputation[uid]['nickname']} After {str(reputation_timer)} minutes of inactivity you should reconnect and type the password code ") self.Irc.send2socket(f":{service_id} KILL {self.db_reputation[uid]['nickname']} After {str(reputation_timer)} minutes of inactivity you should reconnect and type the password code ")
self.Irc.debug('-----'*20) self.Irc.Base.logs.info(f"Nickname: {self.db_reputation[uid]['nickname']} KILLED after {str(reputation_timer)} minutes of inactivity")
self.Irc.debug(f"Nickname: {self.db_reputation[uid]['nickname']} KILLED after {str(reputation_timer)} minutes of inactivity")
self.Irc.debug('-----'*20)
uid_to_clean.append(uid) uid_to_clean.append(uid)
@@ -493,7 +492,7 @@ class Defender():
self.delete_db_reputation(uid) self.delete_db_reputation(uid)
except AssertionError as ae: except AssertionError as ae:
self.Irc.debug(f'Assertion Error -> {ae}') self.Irc.Base.logs.error(f'Assertion Error -> {ae}')
def thread_reputation_timer(self) -> None: def thread_reputation_timer(self) -> None:
try: try:
@@ -503,7 +502,7 @@ class Defender():
return None return None
except ValueError as ve: except ValueError as ve:
self.Irc.debug(f"thread_reputation_timer Error : {ve}") self.Irc.Base.logs.error(f"thread_reputation_timer Error : {ve}")
def _execute_flood_action(self, action:str, channel:str) -> None: def _execute_flood_action(self, action:str, channel:str) -> None:
"""DO NOT EXECUTE THIS FUNCTION WITHOUT THREADING """DO NOT EXECUTE THIS FUNCTION WITHOUT THREADING
@@ -563,10 +562,10 @@ class Defender():
get_diff_secondes = unixtime - self.flood_system[get_detected_uid]['first_msg_time'] get_diff_secondes = unixtime - self.flood_system[get_detected_uid]['first_msg_time']
elif self.flood_system[get_detected_uid]['nbr_msg'] > flood_message: elif self.flood_system[get_detected_uid]['nbr_msg'] > flood_message:
self.Irc.debug('system de flood detecté') self.Irc.Base.logs.info('system de flood detecté')
self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} : {color_red} {color_bold} Flood detected. Apply the +m mode (Ô_o)') self.Irc.send2socket(f':{dnickname} PRIVMSG {channel} : {color_red} {color_bold} Flood detected. Apply the +m mode (Ô_o)')
self.Irc.send2socket(f":{service_id} MODE {channel} +m") self.Irc.send2socket(f":{service_id} MODE {channel} +m")
self.Irc.debug(f'FLOOD Détecté sur {get_detected_nickname} mode +m appliqué sur le salon {channel}') self.Irc.Base.logs.info(f'FLOOD Détecté sur {get_detected_nickname} mode +m appliqué sur le salon {channel}')
self.flood_system[get_detected_uid]['nbr_msg'] = 0 self.flood_system[get_detected_uid]['nbr_msg'] = 0
self.flood_system[get_detected_uid]['first_msg_time'] = unixtime self.flood_system[get_detected_uid]['first_msg_time'] = unixtime
@@ -613,15 +612,15 @@ class Defender():
newSocket.shutdown(socket.SHUT_RDWR) newSocket.shutdown(socket.SHUT_RDWR)
newSocket.close() newSocket.close()
except (socket.timeout, ConnectionRefusedError): except (socket.timeout, ConnectionRefusedError):
self.Irc.debug(f"Le port {remote_ip}:{str(port)} est fermé") self.Base.logs.info(f"Le port {remote_ip}:{str(port)} est fermé")
except AttributeError as ae: except AttributeError as ae:
self.Irc.debug(f"AttributeError ({remote_ip}): {ae}") self.Base.logs.warning(f"AttributeError ({remote_ip}): {ae}")
except socket.gaierror as err: except socket.gaierror as err:
self.Irc.debug(f"Address Info Error ({remote_ip}): {err}") self.Base.logs.warning(f"Address Info Error ({remote_ip}): {err}")
finally: finally:
# newSocket.shutdown(socket.SHUT_RDWR) # newSocket.shutdown(socket.SHUT_RDWR)
newSocket.close() newSocket.close()
self.Irc.debug('=======> Fermeture de la socket') self.Base.logs.info('=======> Fermeture de la socket')
pass pass
@@ -642,7 +641,7 @@ class Defender():
return None return None
except ValueError as ve: except ValueError as ve:
self.Irc.debug(f"thread_local_scan Error : {ve}") self.Base.logs.warning(f"thread_local_scan Error : {ve}")
def get_ports_connexion(self, remote_ip: str) -> list[int]: def get_ports_connexion(self, remote_ip: str) -> list[int]:
"""psutil_scan """psutil_scan
@@ -659,7 +658,7 @@ class Defender():
connections = psutil.net_connections(kind='inet') connections = psutil.net_connections(kind='inet')
matching_ports = [conn.raddr.port for conn in connections if conn.raddr and conn.raddr.ip == remote_ip] matching_ports = [conn.raddr.port for conn in connections if conn.raddr and conn.raddr.ip == remote_ip]
self.Irc.debug(f"Connexion of {remote_ip} using ports : {str(matching_ports)}") self.Base.logs.info(f"Connexion of {remote_ip} using ports : {str(matching_ports)}")
return matching_ports return matching_ports
@@ -680,7 +679,7 @@ class Defender():
return None return None
except ValueError as ve: except ValueError as ve:
self.Irc.debug(f"thread_psutil_scan Error : {ve}") self.Base.logs.warning(f"thread_psutil_scan Error : {ve}")
def abuseipdb_scan(self, remote_ip:str) -> Union[dict[str, any], None]: def abuseipdb_scan(self, remote_ip:str) -> Union[dict[str, any], None]:
"""Analyse l'ip avec AbuseIpDB """Analyse l'ip avec AbuseIpDB
@@ -742,11 +741,11 @@ class Defender():
return result return result
except KeyError as ke: except KeyError as ke:
self.Irc.debug(f"AbuseIpDb KeyError : {ke}") self.Base.logs.error(f"AbuseIpDb KeyError : {ke}")
except requests.ReadTimeout as rt: except requests.ReadTimeout as rt:
self.Irc.debug(f"AbuseIpDb Timeout : {rt}") self.Base.logs.error(f"AbuseIpDb Timeout : {rt}")
except requests.ConnectionError as ce: except requests.ConnectionError as ce:
self.Irc.debug(f"AbuseIpDb Connection Error : {ce}") self.Base.logs.error(f"AbuseIpDb Connection Error : {ce}")
def thread_abuseipdb_scan(self) -> None: def thread_abuseipdb_scan(self) -> None:
try: try:
@@ -765,7 +764,7 @@ class Defender():
return None return None
except ValueError as ve: except ValueError as ve:
self.Irc.debug(f"thread_abuseipdb_scan Error : {ve}") self.Base.logs.error(f"thread_abuseipdb_scan Error : {ve}")
def freeipapi_scan(self, remote_ip:str) -> Union[dict[str, any], None]: def freeipapi_scan(self, remote_ip:str) -> Union[dict[str, any], None]:
"""Analyse l'ip avec Freeipapi """Analyse l'ip avec Freeipapi
@@ -800,10 +799,10 @@ class Defender():
try: try:
status_code = response.status_code status_code = response.status_code
if status_code == 429: if status_code == 429:
self.Irc.debug(f'Too Many Requests - The rate limit for the API has been exceeded.') self.Base.logs.warning(f'Too Many Requests - The rate limit for the API has been exceeded.')
return None return None
elif status_code != 200: elif status_code != 200:
print("salut salut") self.Base.logs.warning(f'status code = {str(status_code)}')
return None return None
result = { result = {
@@ -819,7 +818,7 @@ class Defender():
return result return result
except KeyError as ke: except KeyError as ke:
self.Irc.debug(f"FREEIPAPI_SCAN KeyError : {ke}") self.Base.logs.error(f"FREEIPAPI_SCAN KeyError : {ke}")
def thread_freeipapi_scan(self) -> None: def thread_freeipapi_scan(self) -> None:
try: try:
@@ -838,7 +837,7 @@ class Defender():
return None return None
except ValueError as ve: except ValueError as ve:
self.Irc.debug(f"thread_freeipapi_scan Error : {ve}") self.Base.logs.error(f"thread_freeipapi_scan Error : {ve}")
def cloudfilt_scan(self, remote_ip:str) -> Union[dict[str, any], None]: def cloudfilt_scan(self, remote_ip:str) -> Union[dict[str, any], None]:
"""Analyse l'ip avec cloudfilt """Analyse l'ip avec cloudfilt
@@ -876,7 +875,7 @@ class Defender():
try: try:
status_code = response.status_code status_code = response.status_code
if status_code != 200: if status_code != 200:
self.Irc.debug(f'Error connecting to cloudfilt API | Code: {str(status_code)}') self.Base.logs.warning(f'Error connecting to cloudfilt API | Code: {str(status_code)}')
return None return None
result = { result = {
@@ -895,7 +894,7 @@ class Defender():
return result return result
except KeyError as ke: except KeyError as ke:
self.Irc.debug(f"CLOUDFILT_SCAN KeyError : {ke}") self.Base.logs.error(f"CLOUDFILT_SCAN KeyError : {ke}")
return None return None
def thread_cloudfilt_scan(self) -> None: def thread_cloudfilt_scan(self) -> None:
@@ -915,7 +914,7 @@ class Defender():
return None return None
except ValueError as ve: except ValueError as ve:
self.Irc.debug(f"Thread_cloudfilt_scan Error : {ve}") self.Base.logs.error(f"Thread_cloudfilt_scan Error : {ve}")
def cmd(self, data:list) -> None: def cmd(self, data:list) -> None:
@@ -954,7 +953,7 @@ class Defender():
# Possibilité de déclancher les bans a ce niveau. # Possibilité de déclancher les bans a ce niveau.
except IndexError: except IndexError:
self.Irc.debug(f'cmd reputation: index error') self.Irc.Base.logs.error(f'cmd reputation: index error')
match cmd[2]: match cmd[2]:
@@ -1007,7 +1006,7 @@ class Defender():
if uid in self.db_reputation: if uid in self.db_reputation:
if reputation_flag == 1 and int(client_score) <= int(reputation_seuil): if reputation_flag == 1 and int(client_score) <= int(reputation_seuil):
self.system_reputation(uid) self.system_reputation(uid)
self.Irc.debug('Démarrer le systeme de reputation') self.Base.logs.info('Démarrer le systeme de reputation')
case 'SJOIN': case 'SJOIN':
# ['@msgid=F9B7JeHL5pj9nN57cJ5pEr;time=2023-12-28T20:47:24.305Z', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL'] # ['@msgid=F9B7JeHL5pj9nN57cJ5pEr;time=2023-12-28T20:47:24.305Z', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL']
@@ -1028,9 +1027,9 @@ class Defender():
self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +b {self.db_reputation[parsed_UID]['nickname']}!*@*") self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +b {self.db_reputation[parsed_UID]['nickname']}!*@*")
self.Irc.send2socket(f":{service_id} KICK {parsed_chan} {self.db_reputation[parsed_UID]['nickname']}") self.Irc.send2socket(f":{service_id} KICK {parsed_chan} {self.db_reputation[parsed_UID]['nickname']}")
self.Irc.debug(f'SJOIN parsed_uid : {parsed_UID}') self.Base.logs.debug(f'SJOIN parsed_uid : {parsed_UID}')
except KeyError as ke: except KeyError as ke:
self.Irc.debug(f"key error SJOIN : {ke}") self.Base.logs.error(f"key error SJOIN : {ke}")
case 'SLOG': case 'SLOG':
# self.Base.scan_ports(cmd[7]) # self.Base.scan_ports(cmd[7])
@@ -1074,7 +1073,7 @@ class Defender():
self.Irc.send2socket(f":{service_id} MODE {chan} -b {oldnick}!*@*") self.Irc.send2socket(f":{service_id} MODE {chan} -b {oldnick}!*@*")
self.Irc.send2socket(f":{service_id} MODE {chan} +b {newnickname}!*@*") self.Irc.send2socket(f":{service_id} MODE {chan} +b {newnickname}!*@*")
except KeyError as ke: except KeyError as ke:
self.Irc.debug(f'cmd - NICK - KeyError: {ke}') self.Base.logs.error(f'cmd - NICK - KeyError: {ke}')
case 'QUIT': case 'QUIT':
# :001N1WD7L QUIT :Quit: free_znc_1 # :001N1WD7L QUIT :Quit: free_znc_1
@@ -1116,9 +1115,9 @@ class Defender():
# self.Base.create_timer(timer_sent, self.Base.garbage_collector_sockets) # self.Base.create_timer(timer_sent, self.Base.garbage_collector_sockets)
except TypeError as te: except TypeError as te:
self.Irc.debug(f"Type Error -> {te}") self.Base.logs.error(f"Type Error -> {te}")
except ValueError as ve: except ValueError as ve:
self.Irc.debug(f"Value Error -> {ve}") self.Base.logs.error(f"Value Error -> {ve}")
case 'show_reputation': case 'show_reputation':
@@ -1142,12 +1141,11 @@ class Defender():
reputation_seuil = self.defConfig['reputation_seuil'] reputation_seuil = self.defConfig['reputation_seuil']
welcome_salon = self.Config.SALON_LIBERER welcome_salon = self.Config.SALON_LIBERER
self.Irc.debug(f"IP de {jailed_nickname} : {jailed_IP}") self.Base.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.CONFIG_COLOR['verte']
color_black = self.Config.CONFIG_COLOR['noire'] color_black = self.Config.CONFIG_COLOR['noire']
if jailed_UID in self.db_reputation: if jailed_UID in self.db_reputation:
if release_code == self.db_reputation[jailed_UID]['secret_code']: if release_code == self.db_reputation[jailed_UID]['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 !')
@@ -1158,7 +1156,7 @@ class Defender():
self.Irc.send2socket(f":{service_id} MODE {chan} -b {jailed_nickname}!*@*") self.Irc.send2socket(f":{service_id} MODE {chan} -b {jailed_nickname}!*@*")
del self.db_reputation[jailed_UID] del self.db_reputation[jailed_UID]
self.Irc.debug(f'{jailed_UID} - {jailed_nickname} removed from REPUTATION_DB') self.Base.logs.debug(f'{jailed_UID} - {jailed_nickname} removed from REPUTATION_DB')
self.Irc.send2socket(f":{service_id} SAPART {jailed_nickname} {jailed_salon}") self.Irc.send2socket(f":{service_id} SAPART {jailed_nickname} {jailed_salon}")
self.Irc.send2socket(f":{service_id} SAJOIN {jailed_nickname} {welcome_salon}") self.Irc.send2socket(f":{service_id} SAJOIN {jailed_nickname} {welcome_salon}")
self.Irc.send2socket(f":{link} REPUTATION {jailed_IP} {int(reputation_seuil) + 1}") self.Irc.send2socket(f":{link} REPUTATION {jailed_IP} {int(reputation_seuil) + 1}")
@@ -1171,10 +1169,10 @@ class Defender():
self.Irc.send2socket(f":{dnickname} PRIVMSG {jailed_salon} : Ce n'est pas à toi de taper le mot de passe !") self.Irc.send2socket(f":{dnickname} PRIVMSG {jailed_salon} : Ce n'est pas à toi de taper le mot de passe !")
except IndexError: except IndexError:
self.Irc.debug('_hcmd code: out of index') self.Base.logs.error('_hcmd code: out of index')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} code [code]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} code [code]')
except KeyError as ke: except KeyError as ke:
self.Irc.debug(f'_hcmd code: KeyError {ke}') self.Base.logs.error(f'_hcmd code: KeyError {ke}')
# self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} code [code]') # self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} code [code]')
pass pass
@@ -1238,7 +1236,6 @@ class Defender():
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.CONFIG_COLOR["verte"]}BAN ON ALL CHANS{self.Config.CONFIG_COLOR["noire"]} ] : Activated by {fromuser}')
elif get_value == 'off': elif get_value == 'off':
print(get_value)
if self.defConfig[key] == 0: if self.defConfig[key] == 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.CONFIG_COLOR['rouge']}BAN ON ALL CHANS{self.Config.CONFIG_COLOR['noire']} ] : Already deactivated")
return False return False
@@ -1263,15 +1260,16 @@ class Defender():
case _: case _:
pass pass
except IndexError: except IndexError as ie:
self.Irc.debug('_hcmd reputation: out of index') self.Base.logs.warning(f'{ie}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation [ON/OFF]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation [ON/OFF]')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation set banallchan [ON/OFF]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation set banallchan [ON/OFF]')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation set limit [1234]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation set limit [1234]')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation set timer [1234]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation set timer [1234]')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation set action [kill|None]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} reputation set action [kill|None]')
except ValueError: except ValueError as ve:
self.Base.logs.warning(f'{ie}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : La valeur devrait etre un entier >= 0') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : La valeur devrait etre un entier >= 0')
case 'proxy_scan': case 'proxy_scan':
@@ -1439,7 +1437,7 @@ class Defender():
pass pass
except ValueError as ve: except ValueError as ve:
self.Irc.debug(f"{self.__class__.__name__} Value Error : {ve}") self.Base.logs.error(f"{self.__class__.__name__} Value Error : {ve}")
case 'status': case 'status':
color_green = self.Config.CONFIG_COLOR['verte'] color_green = self.Config.CONFIG_COLOR['verte']
@@ -1462,7 +1460,7 @@ class Defender():
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_time ==> {self.defConfig["flood_time"]}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_time ==> {self.defConfig["flood_time"]}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_timer ==> {self.defConfig["flood_timer"]}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_timer ==> {self.defConfig["flood_timer"]}')
except KeyError as ke: except KeyError as ke:
self.Irc.debug(f"Key Error : {ke}") self.Base.logs.error(f"Key Error : {ke}")
case 'join': case 'join':
@@ -1471,8 +1469,8 @@ class Defender():
self.Irc.send2socket(f':{service_id} JOIN {channel}') self.Irc.send2socket(f':{service_id} JOIN {channel}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : {dnickname} JOINED {channel}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : {dnickname} JOINED {channel}')
self.add_defender_channel(channel) self.add_defender_channel(channel)
except IndexError: except IndexError as ie:
self.Irc.debug('_hcmd join: out of index') self.Base.logs.error(f'{ie}')
case 'part': case 'part':
@@ -1485,8 +1483,8 @@ class Defender():
self.Irc.send2socket(f':{service_id} PART {channel}') self.Irc.send2socket(f':{service_id} PART {channel}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : {dnickname} LEFT {channel}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : {dnickname} LEFT {channel}')
self.delete_defender_channel(channel) self.delete_defender_channel(channel)
except IndexError: except IndexError as ie:
self.Irc.debug('_hcmd part: out of index') self.Base.logs.error(f'{ie}')
case 'op' | 'o': case 'op' | 'o':
# /mode #channel +o user # /mode #channel +o user
@@ -1498,7 +1496,7 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} +o {nickname}") self.Irc.send2socket(f":{service_id} MODE {channel} +o {nickname}")
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd OP: {str(e)}') self.Base.logs.warning(f'_hcmd OP: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} op [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} op [#SALON] [NICKNAME]')
case 'deop' | 'do': case 'deop' | 'do':
@@ -1509,7 +1507,7 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} -o {nickname}") self.Irc.send2socket(f":{service_id} MODE {channel} -o {nickname}")
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd DEOP: {str(e)}') self.Base.logs.warning(f'_hcmd DEOP: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} deop [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} deop [#SALON] [NICKNAME]')
case 'owner' | 'q': case 'owner' | 'q':
@@ -1520,7 +1518,7 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} +q {nickname}") self.Irc.send2socket(f":{service_id} MODE {channel} +q {nickname}")
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd OWNER: {str(e)}') self.Base.logs.warning(f'_hcmd OWNER: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} owner [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} owner [#SALON] [NICKNAME]')
case 'deowner' | 'dq': case 'deowner' | 'dq':
@@ -1531,7 +1529,7 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} -q {nickname}") self.Irc.send2socket(f":{service_id} MODE {channel} -q {nickname}")
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd DEOWNER: {str(e)}') self.Base.logs.warning(f'_hcmd DEOWNER: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} deowner [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} deowner [#SALON] [NICKNAME]')
case 'halfop' | 'h': case 'halfop' | 'h':
@@ -1542,7 +1540,7 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} +h {nickname}") self.Irc.send2socket(f":{service_id} MODE {channel} +h {nickname}")
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd halfop: {str(e)}') self.Base.logs.warning(f'_hcmd halfop: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} halfop [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} halfop [#SALON] [NICKNAME]')
case 'dehalfop' | 'dh': case 'dehalfop' | 'dh':
@@ -1553,7 +1551,7 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} -h {nickname}") self.Irc.send2socket(f":{service_id} MODE {channel} -h {nickname}")
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd DEHALFOP: {str(e)}') self.Base.logs.warning(f'_hcmd DEHALFOP: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} dehalfop [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} dehalfop [#SALON] [NICKNAME]')
case 'voice' | 'v': case 'voice' | 'v':
@@ -1564,7 +1562,7 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} +v {nickname}") self.Irc.send2socket(f":{service_id} MODE {channel} +v {nickname}")
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd VOICE: {str(e)}') self.Base.logs.warning(f'_hcmd VOICE: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} voice [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} voice [#SALON] [NICKNAME]')
case 'devoice' | 'dv': case 'devoice' | 'dv':
@@ -1575,7 +1573,7 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} -v {nickname}") self.Irc.send2socket(f":{service_id} MODE {channel} -v {nickname}")
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd DEVOICE: {str(e)}') self.Base.logs.warning(f'_hcmd DEVOICE: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} devoice [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} devoice [#SALON] [NICKNAME]')
case 'ban' | 'b': case 'ban' | 'b':
@@ -1585,9 +1583,9 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} +b {nickname}!*@*") self.Irc.send2socket(f":{service_id} MODE {channel} +b {nickname}!*@*")
self.Irc.debug(f'{fromuser} has banned {nickname} from {channel}') self.Base.logs.debug(f'{fromuser} has banned {nickname} from {channel}')
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd BAN: {str(e)}') self.Base.logs.warning(f'_hcmd BAN: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} ban [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} ban [#SALON] [NICKNAME]')
case 'unban' | 'ub': case 'unban' | 'ub':
@@ -1597,9 +1595,9 @@ class Defender():
nickname = cmd[2] nickname = cmd[2]
self.Irc.send2socket(f":{service_id} MODE {channel} -b {nickname}!*@*") self.Irc.send2socket(f":{service_id} MODE {channel} -b {nickname}!*@*")
self.Irc.debug(f'{fromuser} has unbanned {nickname} from {channel}') self.Base.logs.debug(f'{fromuser} has unbanned {nickname} from {channel}')
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd UNBAN: {str(e)}') self.Base.logs.warning(f'_hcmd UNBAN: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} unban [#SALON] [NICKNAME]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} unban [#SALON] [NICKNAME]')
case 'kick' | 'k': case 'kick' | 'k':
@@ -1615,9 +1613,9 @@ class Defender():
final_reason = ' '.join(reason) final_reason = ' '.join(reason)
self.Irc.send2socket(f":{service_id} KICK {channel} {nickname} {final_reason}") self.Irc.send2socket(f":{service_id} KICK {channel} {nickname} {final_reason}")
self.Irc.debug(f'{fromuser} has kicked {nickname} from {channel} : {final_reason}') self.Base.logs.debug(f'{fromuser} has kicked {nickname} from {channel} : {final_reason}')
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd KICK: {str(e)}') self.Base.logs.warning(f'_hcmd KICK: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} kick [#SALON] [NICKNAME] [REASON]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} kick [#SALON] [NICKNAME] [REASON]')
case 'kickban' | 'kb': case 'kickban' | 'kb':
@@ -1634,9 +1632,9 @@ class Defender():
self.Irc.send2socket(f":{service_id} KICK {channel} {nickname} {final_reason}") self.Irc.send2socket(f":{service_id} KICK {channel} {nickname} {final_reason}")
self.Irc.send2socket(f":{service_id} MODE {channel} +b {nickname}!*@*") self.Irc.send2socket(f":{service_id} MODE {channel} +b {nickname}!*@*")
self.Irc.debug(f'{fromuser} has kicked and banned {nickname} from {channel} : {final_reason}') self.Base.logs.debug(f'{fromuser} has kicked and banned {nickname} from {channel} : {final_reason}')
except IndexError as e: except IndexError as e:
self.Irc.debug(f'_hcmd KICKBAN: {str(e)}') self.Base.logs.warning(f'_hcmd KICKBAN: {str(e)}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} kickban [#SALON] [NICKNAME] [REASON]') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} kickban [#SALON] [NICKNAME] [REASON]')
case 'info': case 'info':
@@ -1662,7 +1660,7 @@ class Defender():
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : MODES : {self.Irc.db_uid[uid_query]["umodes"]}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : MODES : {self.Irc.db_uid[uid_query]["umodes"]}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : CONNECTION TIME : {self.Irc.db_uid[uid_query]["datetime"]}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : CONNECTION TIME : {self.Irc.db_uid[uid_query]["datetime"]}')
except KeyError as ke: except KeyError as ke:
self.Irc.debug(f"Key error info user : {ke}") self.Base.logs.warning(f"Key error info user : {ke}")
case 'show_users': case 'show_users':
for uid, infousers in self.Irc.db_uid.items(): for uid, infousers in self.Irc.db_uid.items():

3
version.json Normal file
View File

@@ -0,0 +1,3 @@
{
"version": "4.0.0"
}