mirror of
https://github.com/iio612/DEFENDER.git
synced 2026-02-13 11:14:23 +00:00
Moving modules in separate folders
This commit is contained in:
@@ -391,7 +391,7 @@ class Base:
|
|||||||
result = response.fetchall()
|
result = response.fetchall()
|
||||||
|
|
||||||
for param, value in result:
|
for param, value in result:
|
||||||
if type(getattr(dataclassObj, param)) == list:
|
if isinstance(getattr(dataclassObj, param), list):
|
||||||
value = ast.literal_eval(value)
|
value = ast.literal_eval(value)
|
||||||
|
|
||||||
setattr(dataclassObj, param, self.int_if_possible(value))
|
setattr(dataclassObj, param, self.int_if_possible(value))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from re import match, findall, search
|
from re import match, findall, search
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import TYPE_CHECKING, Union
|
from typing import TYPE_CHECKING, Optional, Union
|
||||||
from ssl import SSLEOFError, SSLError
|
from ssl import SSLEOFError, SSLError
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -17,14 +17,21 @@ class Unrealircd6:
|
|||||||
self.__Base = ircInstance.Base
|
self.__Base = ircInstance.Base
|
||||||
self.__Settings = ircInstance.Base.Settings
|
self.__Settings = ircInstance.Base.Settings
|
||||||
|
|
||||||
self.known_protocol = ['SJOIN', 'UID', 'MD', 'QUIT', 'SQUIT',
|
self.known_protocol: set[str] = {'SJOIN', 'UID', 'MD', 'QUIT', 'SQUIT',
|
||||||
'EOS', 'PRIVMSG', 'MODE', 'UMODE2',
|
'EOS', 'PRIVMSG', 'MODE', 'UMODE2',
|
||||||
'VERSION', 'REPUTATION', 'SVS2MODE',
|
'VERSION', 'REPUTATION', 'SVS2MODE',
|
||||||
'SLOG', 'NICK', 'PART', 'PONG'
|
'SLOG', 'NICK', 'PART', 'PONG'}
|
||||||
]
|
|
||||||
|
|
||||||
self.__Base.logs.info(f"** Loading protocol [{__name__}]")
|
self.__Base.logs.info(f"** Loading protocol [{__name__}]")
|
||||||
|
|
||||||
|
def get_ircd_protocol_poisition(self, cmd: list[str]) -> tuple[int, Optional[str]]:
|
||||||
|
|
||||||
|
for index, token in enumerate(cmd):
|
||||||
|
if token.upper() in self.known_protocol:
|
||||||
|
return index, token.upper()
|
||||||
|
|
||||||
|
return (-1, None)
|
||||||
|
|
||||||
def send2socket(self, message: str, print_log: bool = True) -> None:
|
def send2socket(self, message: str, print_log: bool = True) -> None:
|
||||||
"""Envoit les commandes à envoyer au serveur.
|
"""Envoit les commandes à envoyer au serveur.
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,26 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from dataclasses import dataclass, field
|
from json import dumps
|
||||||
from typing import Literal
|
from dataclasses import dataclass, field, asdict, fields
|
||||||
|
from typing import Literal, Any
|
||||||
from os import sep
|
from os import sep
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MClient:
|
class MainModel:
|
||||||
|
"""Parent Model contains important methods"""
|
||||||
|
def to_dict(self) -> dict[str, Any]:
|
||||||
|
"""Return the fields of a dataclass instance as a new dictionary mapping field names to field values."""
|
||||||
|
return asdict(self)
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
"""Return the object of a dataclass a json str."""
|
||||||
|
return dumps(self.to_dict())
|
||||||
|
|
||||||
|
def get_attributes(self) -> list[str]:
|
||||||
|
"""Return a list of attributes name"""
|
||||||
|
return [f.name for f in fields(self)]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class MClient(MainModel):
|
||||||
"""Model Client for registred nickname"""
|
"""Model Client for registred nickname"""
|
||||||
uid: str = None
|
uid: str = None
|
||||||
account: str = None
|
account: str = None
|
||||||
@@ -22,7 +38,7 @@ class MClient:
|
|||||||
connexion_datetime: datetime = field(default=datetime.now())
|
connexion_datetime: datetime = field(default=datetime.now())
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MUser:
|
class MUser(MainModel):
|
||||||
"""Model User"""
|
"""Model User"""
|
||||||
|
|
||||||
uid: str = None
|
uid: str = None
|
||||||
@@ -40,7 +56,7 @@ class MUser:
|
|||||||
connexion_datetime: datetime = field(default=datetime.now())
|
connexion_datetime: datetime = field(default=datetime.now())
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MAdmin:
|
class MAdmin(MainModel):
|
||||||
"""Model Admin"""
|
"""Model Admin"""
|
||||||
|
|
||||||
uid: str = None
|
uid: str = None
|
||||||
@@ -59,7 +75,7 @@ class MAdmin:
|
|||||||
level: int = 0
|
level: int = 0
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MReputation:
|
class MReputation(MainModel):
|
||||||
"""Model Reputation"""
|
"""Model Reputation"""
|
||||||
uid: str = None
|
uid: str = None
|
||||||
nickname: str = None
|
nickname: str = None
|
||||||
@@ -77,7 +93,7 @@ class MReputation:
|
|||||||
secret_code: str = None
|
secret_code: str = None
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MChannel:
|
class MChannel(MainModel):
|
||||||
"""Model Channel"""
|
"""Model Channel"""
|
||||||
|
|
||||||
name: str = None
|
name: str = None
|
||||||
@@ -92,7 +108,7 @@ class MChannel:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ColorModel:
|
class ColorModel(MainModel):
|
||||||
white: str = "\x0300"
|
white: str = "\x0300"
|
||||||
black: str = "\x0301"
|
black: str = "\x0301"
|
||||||
blue: str = "\x0302"
|
blue: str = "\x0302"
|
||||||
@@ -104,7 +120,7 @@ class ColorModel:
|
|||||||
underline: str = "\x1F"
|
underline: str = "\x1F"
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MConfig:
|
class MConfig(MainModel):
|
||||||
"""Model Configuration"""
|
"""Model Configuration"""
|
||||||
|
|
||||||
SERVEUR_IP: str = "127.0.0.1"
|
SERVEUR_IP: str = "127.0.0.1"
|
||||||
@@ -305,7 +321,7 @@ class MConfig:
|
|||||||
"""0: utf-8 | 1: iso-8859-1"""
|
"""0: utf-8 | 1: iso-8859-1"""
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class MClone:
|
class MClone(MainModel):
|
||||||
"""Model Clone"""
|
"""Model Clone"""
|
||||||
connected: bool = False
|
connected: bool = False
|
||||||
uid: str = None
|
uid: str = None
|
||||||
|
|||||||
10
core/irc.py
10
core/irc.py
@@ -494,7 +494,8 @@ class Irc:
|
|||||||
try:
|
try:
|
||||||
# module_name : mod_voice
|
# module_name : mod_voice
|
||||||
module_name = module_name.lower()
|
module_name = module_name.lower()
|
||||||
class_name = module_name.split('_')[1].capitalize() # ==> Voice
|
module_folder = module_name.split('_')[1].lower() # ==> voice
|
||||||
|
class_name = module_name.split('_')[1].capitalize() # ==> Voice
|
||||||
|
|
||||||
# print(self.loaded_classes)
|
# print(self.loaded_classes)
|
||||||
|
|
||||||
@@ -511,7 +512,7 @@ class Irc:
|
|||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
the_module = sys.modules['mods.' + module_name]
|
the_module = sys.modules[f'mods.{module_folder}.{module_name}']
|
||||||
importlib.reload(the_module)
|
importlib.reload(the_module)
|
||||||
my_class = getattr(the_module, class_name, None)
|
my_class = getattr(the_module, class_name, None)
|
||||||
new_instance = my_class(self.ircObject)
|
new_instance = my_class(self.ircObject)
|
||||||
@@ -529,7 +530,7 @@ class Irc:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# Charger le module
|
# Charger le module
|
||||||
loaded_module = importlib.import_module(f"mods.{module_name}")
|
loaded_module = importlib.import_module(f'mods.{module_folder}.{module_name}')
|
||||||
|
|
||||||
my_class = getattr(loaded_module, class_name, None) # Récuperer le nom de classe
|
my_class = getattr(loaded_module, class_name, None) # Récuperer le nom de classe
|
||||||
create_instance_of_the_class = my_class(self.ircObject) # Créer une nouvelle instance de la classe
|
create_instance_of_the_class = my_class(self.ircObject) # Créer une nouvelle instance de la classe
|
||||||
@@ -612,13 +613,14 @@ class Irc:
|
|||||||
def reload_module(self, from_user: str, mod_name: str) -> bool:
|
def reload_module(self, from_user: str, mod_name: str) -> bool:
|
||||||
try:
|
try:
|
||||||
module_name = mod_name.lower() # ==> mod_defender
|
module_name = mod_name.lower() # ==> mod_defender
|
||||||
|
module_folder = module_name.split('_')[1].lower() # ==> defender
|
||||||
class_name = module_name.split('_')[1].capitalize() # ==> Defender
|
class_name = module_name.split('_')[1].capitalize() # ==> Defender
|
||||||
|
|
||||||
if 'mods.' + module_name in sys.modules:
|
if 'mods.' + module_name in sys.modules:
|
||||||
self.Logs.info('Unload the module ...')
|
self.Logs.info('Unload the module ...')
|
||||||
self.loaded_classes[class_name].unload()
|
self.loaded_classes[class_name].unload()
|
||||||
self.Logs.info('Module Already Loaded ... reloading the module ...')
|
self.Logs.info('Module Already Loaded ... reloading the module ...')
|
||||||
the_module = sys.modules['mods.' + module_name]
|
the_module = sys.modules[f'mods.{module_folder}.{module_name}']
|
||||||
importlib.reload(the_module)
|
importlib.reload(the_module)
|
||||||
|
|
||||||
# Supprimer la class déja instancier
|
# Supprimer la class déja instancier
|
||||||
|
|||||||
@@ -2,53 +2,19 @@ import socket
|
|||||||
import json
|
import json
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
from webbrowser import get
|
|
||||||
import psutil
|
import psutil
|
||||||
import requests
|
import requests
|
||||||
from dataclasses import dataclass
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Union, TYPE_CHECKING
|
from typing import Union, TYPE_CHECKING
|
||||||
import core.definition as df
|
|
||||||
|
|
||||||
# Le module crée devra réspecter quelques conditions
|
import core.definition as df
|
||||||
# 1. Le nom de la classe devra toujours s'appeler comme le module. Exemple => nom de class Defender | nom du module mod_defender
|
import mods.defender.schemas as schemas
|
||||||
# 2. la methode __init__ devra toujours avoir les parametres suivant (self, irc:object)
|
|
||||||
# 1 . Créer la variable Irc dans le module
|
|
||||||
# 2 . Récuperer la configuration dans une variable
|
|
||||||
# 3 . Définir et enregistrer les nouvelles commandes
|
|
||||||
# 4 . Créer vos tables, en utilisant toujours le nom des votre classe en minuscule ==> defender_votre-table
|
|
||||||
# 3. Methode suivantes:
|
|
||||||
# cmd(self, data:list)
|
|
||||||
# hcmds(self, user:str, cmd: list)
|
|
||||||
# unload(self)
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from core.irc import Irc
|
from core.irc import Irc
|
||||||
|
|
||||||
|
|
||||||
class Defender():
|
class Defender():
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ModConfModel:
|
|
||||||
reputation: int
|
|
||||||
reputation_timer: int
|
|
||||||
reputation_seuil: int
|
|
||||||
reputation_score_after_release: int
|
|
||||||
reputation_ban_all_chan: int
|
|
||||||
reputation_sg: int
|
|
||||||
local_scan: int
|
|
||||||
psutil_scan: int
|
|
||||||
abuseipdb_scan: int
|
|
||||||
freeipapi_scan: int
|
|
||||||
cloudfilt_scan: int
|
|
||||||
flood: int
|
|
||||||
flood_message: int
|
|
||||||
flood_time: int
|
|
||||||
flood_timer: int
|
|
||||||
autolimit: int
|
|
||||||
autolimit_amount: int
|
|
||||||
autolimit_interval: int
|
|
||||||
|
|
||||||
def __init__(self, ircInstance: 'Irc') -> None:
|
def __init__(self, ircInstance: 'Irc') -> None:
|
||||||
|
|
||||||
# Module name (Mandatory)
|
# Module name (Mandatory)
|
||||||
@@ -81,6 +47,9 @@ class Defender():
|
|||||||
# Add Reputation object to the module (Optional)
|
# Add Reputation object to the module (Optional)
|
||||||
self.Reputation = ircInstance.Reputation
|
self.Reputation = ircInstance.Reputation
|
||||||
|
|
||||||
|
# Add module schemas
|
||||||
|
self.Schemas = schemas
|
||||||
|
|
||||||
# Create module commands (Mandatory)
|
# Create module commands (Mandatory)
|
||||||
self.Irc.build_command(0, self.module_name, 'code', 'Display the code or key for access')
|
self.Irc.build_command(0, self.module_name, 'code', 'Display the code or key for access')
|
||||||
self.Irc.build_command(1, self.module_name, 'info', 'Provide information about the channel or server')
|
self.Irc.build_command(1, self.module_name, 'info', 'Provide information about the channel or server')
|
||||||
@@ -97,7 +66,7 @@ class Defender():
|
|||||||
self.__init_module()
|
self.__init_module()
|
||||||
|
|
||||||
# Log the module
|
# Log the module
|
||||||
self.Logs.debug(f'-- Module {self.module_name} loaded ...')
|
self.Logs.debug(f'-- Module {self.module_name} V2 loaded ...')
|
||||||
|
|
||||||
def __init_module(self) -> None:
|
def __init_module(self) -> None:
|
||||||
|
|
||||||
@@ -179,23 +148,13 @@ class Defender():
|
|||||||
def __load_module_configuration(self) -> None:
|
def __load_module_configuration(self) -> None:
|
||||||
"""### Load Module Configuration
|
"""### Load Module Configuration
|
||||||
"""
|
"""
|
||||||
try:
|
# Variable qui va contenir les options de configuration du module Defender
|
||||||
# Variable qui va contenir les options de configuration du module Defender
|
self.ModConfig = self.Schemas.ModConfModel()
|
||||||
self.ModConfig = self.ModConfModel(
|
|
||||||
reputation=0, reputation_timer=1, reputation_seuil=26, reputation_score_after_release=27,
|
|
||||||
reputation_ban_all_chan=0,reputation_sg=1,
|
|
||||||
local_scan=0, psutil_scan=0, abuseipdb_scan=0, freeipapi_scan=0, cloudfilt_scan=0,
|
|
||||||
flood=0, flood_message=5, flood_time=1, flood_timer=20,
|
|
||||||
autolimit=1, autolimit_amount=3, autolimit_interval=3
|
|
||||||
)
|
|
||||||
|
|
||||||
# Sync the configuration with core configuration (Mandatory)
|
# Sync the configuration with core configuration (Mandatory)
|
||||||
self.Base.db_sync_core_config(self.module_name, self.ModConfig)
|
self.Base.db_sync_core_config(self.module_name, self.ModConfig)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
except TypeError as te:
|
|
||||||
self.Logs.critical(te)
|
|
||||||
|
|
||||||
def __update_configuration(self, param_key: str, param_value: str):
|
def __update_configuration(self, param_key: str, param_value: str):
|
||||||
|
|
||||||
@@ -415,8 +374,6 @@ class Defender():
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
action (str): _description_
|
action (str): _description_
|
||||||
timer (int): _description_
|
|
||||||
nickname (str): _description_
|
|
||||||
channel (str): _description_
|
channel (str): _description_
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@@ -973,10 +930,17 @@ class Defender():
|
|||||||
|
|
||||||
def cmd(self, data: list[str]) -> None:
|
def cmd(self, data: list[str]) -> None:
|
||||||
try:
|
try:
|
||||||
service_id = self.Config.SERVICE_ID # Defender serveur id
|
if not data or len(data) < 2:
|
||||||
cmd = list(data).copy()
|
return None
|
||||||
|
|
||||||
match cmd[1]:
|
service_id = self.Config.SERVICE_ID
|
||||||
|
p = self.Protocol
|
||||||
|
cmd = data.copy() if isinstance(data, list) else list(data).copy()
|
||||||
|
index, command = p.get_ircd_protocol_poisition(cmd)
|
||||||
|
if index == -1:
|
||||||
|
return None
|
||||||
|
|
||||||
|
match command:
|
||||||
|
|
||||||
case 'REPUTATION':
|
case 'REPUTATION':
|
||||||
# :001 REPUTATION 8.8.8.8 118
|
# :001 REPUTATION 8.8.8.8 118
|
||||||
@@ -994,11 +958,6 @@ class Defender():
|
|||||||
except IndexError as ie:
|
except IndexError as ie:
|
||||||
self.Logs.error(f'cmd reputation: index error: {ie}')
|
self.Logs.error(f'cmd reputation: index error: {ie}')
|
||||||
|
|
||||||
if len(cmd) < 3:
|
|
||||||
return None
|
|
||||||
|
|
||||||
match cmd[2]:
|
|
||||||
|
|
||||||
case 'MODE':
|
case 'MODE':
|
||||||
# ['...', ':001XSCU0Q', 'MODE', '#jail', '+b', '~security-group:unknown-users']
|
# ['...', ':001XSCU0Q', 'MODE', '#jail', '+b', '~security-group:unknown-users']
|
||||||
# ['@unrealircd.org/...', ':001C0MF01', 'MODE', '#services', '+l', '1']
|
# ['@unrealircd.org/...', ':001C0MF01', 'MODE', '#services', '+l', '1']
|
||||||
@@ -1011,19 +970,22 @@ class Defender():
|
|||||||
if self.ModConfig.autolimit == 1:
|
if self.ModConfig.autolimit == 1:
|
||||||
if mode == '+l' or mode == '-l':
|
if mode == '+l' or mode == '-l':
|
||||||
chan = self.Channel.get_Channel(channel)
|
chan = self.Channel.get_Channel(channel)
|
||||||
self.Protocol.send2socket(f":{self.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + self.ModConfig.autolimit_amount}")
|
p.send2socket(f":{self.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + self.ModConfig.autolimit_amount}")
|
||||||
|
|
||||||
if self.Config.SALON_JAIL == channel:
|
if self.Config.SALON_JAIL == channel:
|
||||||
if mode == '+b' and group_to_unban in group_to_check:
|
if mode == '+b' and group_to_unban in group_to_check:
|
||||||
self.Protocol.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -b ~security-group:unknown-users")
|
p.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -b ~security-group:unknown-users")
|
||||||
self.Protocol.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
|
p.send2socket(f":{service_id} MODE {self.Config.SALON_JAIL} -eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
case 'PRIVMSG':
|
case 'PRIVMSG':
|
||||||
cmd.pop(0)
|
# ['@mtag....',':python', 'PRIVMSG', '#defender', ':zefzefzregreg', 'regg', 'aerg']
|
||||||
user_trigger = str(cmd[0]).replace(':','')
|
user_trigger = str(cmd[1]).replace(':','')
|
||||||
channel = cmd[2]
|
channel = cmd[3]
|
||||||
find_nickname = self.User.get_nickname(user_trigger)
|
find_nickname = self.User.get_nickname(user_trigger)
|
||||||
self.flood(find_nickname, channel)
|
self.flood(find_nickname, channel)
|
||||||
|
return None
|
||||||
|
|
||||||
case 'UID':
|
case 'UID':
|
||||||
# If Init then do nothing
|
# If Init then do nothing
|
||||||
@@ -1036,6 +998,10 @@ class Defender():
|
|||||||
# Get User information
|
# Get User information
|
||||||
_User = self.User.get_User(str(cmd[7]))
|
_User = self.User.get_User(str(cmd[7]))
|
||||||
|
|
||||||
|
if _User is None:
|
||||||
|
self.Logs.critical(f'This UID: [{cmd[7]}] is not available please check why')
|
||||||
|
return None
|
||||||
|
|
||||||
# If user is not service or IrcOp then scan them
|
# If user is not service or IrcOp then scan them
|
||||||
if not re.match(r'^.*[S|o?].*$', _User.umodes):
|
if not re.match(r'^.*[S|o?].*$', _User.umodes):
|
||||||
self.abuseipdb_UserModel.append(_User) if self.ModConfig.abuseipdb_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None
|
self.abuseipdb_UserModel.append(_User) if self.ModConfig.abuseipdb_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None
|
||||||
@@ -1044,10 +1010,6 @@ class Defender():
|
|||||||
self.psutil_UserModel.append(_User) if self.ModConfig.psutil_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None
|
self.psutil_UserModel.append(_User) if self.ModConfig.psutil_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None
|
||||||
self.localscan_UserModel.append(_User) if self.ModConfig.local_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None
|
self.localscan_UserModel.append(_User) if self.ModConfig.local_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None
|
||||||
|
|
||||||
if _User is None:
|
|
||||||
self.Logs.critical(f'This UID: [{cmd[7]}] is not available please check why')
|
|
||||||
return None
|
|
||||||
|
|
||||||
reputation_flag = self.ModConfig.reputation
|
reputation_flag = self.ModConfig.reputation
|
||||||
reputation_seuil = self.ModConfig.reputation_seuil
|
reputation_seuil = self.ModConfig.reputation_seuil
|
||||||
|
|
||||||
@@ -1058,12 +1020,8 @@ class Defender():
|
|||||||
# currentDateTime = self.Base.get_datetime()
|
# currentDateTime = self.Base.get_datetime()
|
||||||
self.Reputation.insert(
|
self.Reputation.insert(
|
||||||
self.Loader.Definition.MReputation(
|
self.Loader.Definition.MReputation(
|
||||||
**_User.__dict__,
|
**_User.to_dict(),
|
||||||
secret_code=self.Base.get_random(8)
|
secret_code=self.Base.get_random(8)
|
||||||
# uid=_User.uid, nickname=_User.nickname, username=_User.username, realname=_User.realname,
|
|
||||||
# hostname=_User.hostname, umodes=_User.umodes, vhost=_User.vhost, ip=_User.remote_ip, score=_User.score_connexion,
|
|
||||||
# secret_code=self.Base.get_random(8), isWebirc=_User.isWebirc, isWebsocket=_User.isWebsocket, connected_datetime=currentDateTime,
|
|
||||||
# updated_datetime=currentDateTime
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if self.Reputation.is_exist(_User.uid):
|
if self.Reputation.is_exist(_User.uid):
|
||||||
@@ -1071,44 +1029,48 @@ class Defender():
|
|||||||
self.system_reputation(_User.uid)
|
self.system_reputation(_User.uid)
|
||||||
self.Logs.info('Démarrer le systeme de reputation')
|
self.Logs.info('Démarrer le systeme de reputation')
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
case 'SJOIN':
|
case 'SJOIN':
|
||||||
# ['@msgid=F9B7JeHL5pj9nN57cJ5pEr;time=2023-12-28T20:47:24.305Z', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL']
|
# ['@msgid=F9B7JeHL5pj9nN57cJ5pEr..', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL']
|
||||||
try:
|
try:
|
||||||
cmd.pop(0)
|
parsed_chan = cmd[4] if self.Channel.Is_Channel(cmd[4]) else None
|
||||||
parsed_chan = cmd[3] if self.Channel.Is_Channel(cmd[3]) else None
|
parsed_UID = self.User.clean_uid(cmd[5])
|
||||||
|
|
||||||
if self.ModConfig.reputation == 1:
|
if self.ModConfig.reputation == 1:
|
||||||
parsed_UID = self.User.clean_uid(cmd[4])
|
|
||||||
get_reputation = self.Reputation.get_Reputation(parsed_UID)
|
get_reputation = self.Reputation.get_Reputation(parsed_UID)
|
||||||
|
|
||||||
if parsed_chan != self.Config.SALON_JAIL:
|
if parsed_chan != self.Config.SALON_JAIL:
|
||||||
self.Protocol.send2socket(f":{service_id} MODE {parsed_chan} +b ~security-group:unknown-users")
|
p.send2socket(f":{service_id} MODE {parsed_chan} +b ~security-group:unknown-users")
|
||||||
self.Protocol.send2socket(f":{service_id} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
|
p.send2socket(f":{service_id} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
|
||||||
|
|
||||||
if get_reputation is not None:
|
if get_reputation is not None:
|
||||||
isWebirc = get_reputation.isWebirc
|
isWebirc = get_reputation.isWebirc
|
||||||
|
|
||||||
if not isWebirc:
|
if not isWebirc:
|
||||||
if parsed_chan != self.Config.SALON_JAIL:
|
if parsed_chan != self.Config.SALON_JAIL:
|
||||||
self.Protocol.send_sapart(nick_to_sapart=get_reputation.nickname, channel_name=parsed_chan)
|
p.send_sapart(nick_to_sapart=get_reputation.nickname, channel_name=parsed_chan)
|
||||||
|
|
||||||
if self.ModConfig.reputation_ban_all_chan == 1 and not isWebirc:
|
if self.ModConfig.reputation_ban_all_chan == 1 and not isWebirc:
|
||||||
if parsed_chan != self.Config.SALON_JAIL:
|
if parsed_chan != self.Config.SALON_JAIL:
|
||||||
self.Protocol.send2socket(f":{service_id} MODE {parsed_chan} +b {get_reputation.nickname}!*@*")
|
p.send2socket(f":{service_id} MODE {parsed_chan} +b {get_reputation.nickname}!*@*")
|
||||||
self.Protocol.send2socket(f":{service_id} KICK {parsed_chan} {get_reputation.nickname}")
|
p.send2socket(f":{service_id} KICK {parsed_chan} {get_reputation.nickname}")
|
||||||
|
|
||||||
self.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}')
|
self.Logs.debug(f'SJOIN parsed_uid : {parsed_UID}')
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
except KeyError as ke:
|
except KeyError as ke:
|
||||||
self.Logs.error(f"key error SJOIN : {ke}")
|
self.Logs.error(f"key error SJOIN : {ke}")
|
||||||
|
|
||||||
case 'SLOG':
|
case 'SLOG':
|
||||||
# self.Base.scan_ports(cmd[7])
|
['@unrealircd...', ':001', 'SLOG', 'info', 'blacklist', 'BLACKLIST_HIT', ':[Blacklist]', 'IP', '162.x.x.x', 'matches', 'blacklist', 'dronebl', '(dnsbl.dronebl.org/reply=6)']
|
||||||
cmd.pop(0)
|
|
||||||
|
|
||||||
if not self.Base.is_valid_ip(cmd[7]):
|
if not self.Base.is_valid_ip(cmd[8]):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
# if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
# if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||||
# self.localscan_remote_ip.append(cmd[7])
|
# self.localscan_remote_ip.append(cmd[7])
|
||||||
|
|
||||||
@@ -1125,11 +1087,10 @@ class Defender():
|
|||||||
# self.cloudfilt_remote_ip.append(cmd[7])
|
# self.cloudfilt_remote_ip.append(cmd[7])
|
||||||
|
|
||||||
case 'NICK':
|
case 'NICK':
|
||||||
# :0010BS24L NICK [NEWNICK] 1697917711
|
# ['@unrealircd.org...', ':001MZQ0RB', 'NICK', 'halow', '1754663712']
|
||||||
# Changement de nickname
|
# Changement de nickname
|
||||||
try:
|
try:
|
||||||
cmd.pop(0)
|
uid = self.User.clean_uid(str(cmd[1]))
|
||||||
uid = str(cmd[0]).replace(':','')
|
|
||||||
get_Reputation = self.Reputation.get_Reputation(uid)
|
get_Reputation = self.Reputation.get_Reputation(uid)
|
||||||
jail_salon = self.Config.SALON_JAIL
|
jail_salon = self.Config.SALON_JAIL
|
||||||
service_id = self.Config.SERVICE_ID
|
service_id = self.Config.SERVICE_ID
|
||||||
@@ -1140,37 +1101,40 @@ class Defender():
|
|||||||
|
|
||||||
# Update the new nickname
|
# Update the new nickname
|
||||||
oldnick = get_Reputation.nickname
|
oldnick = get_Reputation.nickname
|
||||||
newnickname = cmd[2]
|
newnickname = cmd[3]
|
||||||
get_Reputation.nickname = newnickname
|
get_Reputation.nickname = newnickname
|
||||||
|
|
||||||
# If ban in all channel is ON then unban old nickname an ban the new nickname
|
# If ban in all channel is ON then unban old nickname an ban the new nickname
|
||||||
if self.ModConfig.reputation_ban_all_chan == 1:
|
if self.ModConfig.reputation_ban_all_chan == 1:
|
||||||
for chan in self.Channel.UID_CHANNEL_DB:
|
for chan in self.Channel.UID_CHANNEL_DB:
|
||||||
if chan.name != jail_salon:
|
if chan.name != jail_salon:
|
||||||
self.Protocol.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*")
|
p.send2socket(f":{service_id} MODE {chan.name} -b {oldnick}!*@*")
|
||||||
self.Protocol.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*")
|
p.send2socket(f":{service_id} MODE {chan.name} +b {newnickname}!*@*")
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
except KeyError as ke:
|
except KeyError as ke:
|
||||||
self.Logs.error(f'cmd - NICK - KeyError: {ke}')
|
self.Logs.error(f'cmd - NICK - KeyError: {ke}')
|
||||||
|
|
||||||
case 'QUIT':
|
case 'QUIT':
|
||||||
# :001N1WD7L QUIT :Quit: free_znc_1
|
# ['@unrealircd.org...', ':001MZQ0RB', 'QUIT', ':Quit:', '....']
|
||||||
cmd.pop(0)
|
|
||||||
ban_all_chan = self.Base.int_if_possible(self.ModConfig.reputation_ban_all_chan)
|
ban_all_chan = self.Base.int_if_possible(self.ModConfig.reputation_ban_all_chan)
|
||||||
user_id = str(cmd[0]).replace(':','')
|
final_UID = self.User.clean_uid(str(cmd[1]))
|
||||||
final_UID = user_id
|
|
||||||
|
|
||||||
jail_salon = self.Config.SALON_JAIL
|
jail_salon = self.Config.SALON_JAIL
|
||||||
service_id = self.Config.SERVICE_ID
|
service_id = self.Config.SERVICE_ID
|
||||||
|
|
||||||
get_user_reputation = self.Reputation.get_Reputation(final_UID)
|
get_user_reputation = self.Reputation.get_Reputation(final_UID)
|
||||||
|
|
||||||
if get_user_reputation is not None:
|
if get_user_reputation is not None:
|
||||||
final_nickname = get_user_reputation.nickname
|
final_nickname = get_user_reputation.nickname
|
||||||
for chan in self.Channel.UID_CHANNEL_DB:
|
for chan in self.Channel.UID_CHANNEL_DB:
|
||||||
if chan.name != jail_salon and ban_all_chan == 1:
|
if chan.name != jail_salon and ban_all_chan == 1:
|
||||||
self.Protocol.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*")
|
p.send2socket(f":{service_id} MODE {chan.name} -b {final_nickname}!*@*")
|
||||||
self.Reputation.delete(final_UID)
|
self.Reputation.delete(final_UID)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
case _:
|
||||||
|
return None
|
||||||
|
|
||||||
except KeyError as ke:
|
except KeyError as ke:
|
||||||
self.Logs.error(f"{ke} / {cmd} / length {str(len(cmd))}")
|
self.Logs.error(f"{ke} / {cmd} / length {str(len(cmd))}")
|
||||||
@@ -1183,8 +1147,7 @@ class Defender():
|
|||||||
|
|
||||||
command = str(cmd[0]).lower()
|
command = str(cmd[0]).lower()
|
||||||
fromuser = user
|
fromuser = user
|
||||||
fromchannel = channel if self.Channel.Is_Channel(channel) else None
|
channel = fromchannel = channel if self.Channel.Is_Channel(channel) else None
|
||||||
channel = fromchannel
|
|
||||||
|
|
||||||
dnickname = self.Config.SERVICE_NICKNAME # Defender nickname
|
dnickname = self.Config.SERVICE_NICKNAME # Defender nickname
|
||||||
dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log
|
dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log
|
||||||
@@ -1816,16 +1779,17 @@ class Defender():
|
|||||||
case 'sentinel':
|
case 'sentinel':
|
||||||
# .sentinel on
|
# .sentinel on
|
||||||
activation = str(cmd[1]).lower()
|
activation = str(cmd[1]).lower()
|
||||||
service_id = self.Config.SERVICE_ID
|
|
||||||
|
|
||||||
channel_to_dont_quit = [self.Config.SALON_JAIL, self.Config.SERVICE_CHANLOG]
|
channel_to_dont_quit = [self.Config.SALON_JAIL, self.Config.SERVICE_CHANLOG]
|
||||||
|
|
||||||
if activation == 'on':
|
if activation == 'on':
|
||||||
for chan in self.Channel.UID_CHANNEL_DB:
|
for chan in self.Channel.UID_CHANNEL_DB:
|
||||||
if chan.name not in channel_to_dont_quit:
|
if chan.name not in channel_to_dont_quit:
|
||||||
self.Protocol.send_join_chan(uidornickname=dnickname, channel=chan.name)
|
self.Protocol.send_join_chan(uidornickname=dnickname, channel=chan.name)
|
||||||
|
return None
|
||||||
|
|
||||||
if activation == 'off':
|
if activation == 'off':
|
||||||
for chan in self.Channel.UID_CHANNEL_DB:
|
for chan in self.Channel.UID_CHANNEL_DB:
|
||||||
if chan.name not in channel_to_dont_quit:
|
if chan.name not in channel_to_dont_quit:
|
||||||
self.Protocol.part(uidornickname=dnickname, channel=chan.name)
|
self.Protocol.send_part_chan(uidornickname=dnickname, channel=chan.name)
|
||||||
self.join_saved_channels()
|
self.join_saved_channels()
|
||||||
|
return None
|
||||||
22
mods/defender/schemas.py
Normal file
22
mods/defender/schemas.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from core.definition import MainModel, dataclass
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ModConfModel(MainModel):
|
||||||
|
reputation: int = 0
|
||||||
|
reputation_timer: int = 1
|
||||||
|
reputation_seuil: int = 26
|
||||||
|
reputation_score_after_release: int = 27
|
||||||
|
reputation_ban_all_chan: int = 0
|
||||||
|
reputation_sg: int = 1
|
||||||
|
local_scan: int = 0
|
||||||
|
psutil_scan: int = 0
|
||||||
|
abuseipdb_scan: int = 0
|
||||||
|
freeipapi_scan: int = 0
|
||||||
|
cloudfilt_scan: int = 0
|
||||||
|
flood: int = 0
|
||||||
|
flood_message: int = 5
|
||||||
|
flood_time: int = 1
|
||||||
|
flood_timer: int = 20
|
||||||
|
autolimit: int = 0
|
||||||
|
autolimit_amount: int = 3
|
||||||
|
autolimit_interval: int = 3
|
||||||
0
mods/defender/utils.py
Normal file
0
mods/defender/utils.py
Normal file
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
"requests": "2.32.3",
|
"requests": "2.32.3",
|
||||||
"psutil": "6.0.0",
|
"psutil": "6.0.0",
|
||||||
"unrealircd_rpc_py": "2.0.0",
|
"unrealircd_rpc_py": "2.0.1",
|
||||||
"sqlalchemy": "2.0.35",
|
"sqlalchemy": "2.0.35",
|
||||||
"faker": "30.1.0"
|
"faker": "30.1.0"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user