55 Commits

Author SHA1 Message Date
adator
eeaacddbf2 Merge pull request #68 from adator85/V6.X.X
Update to version 6.0.3
2024-11-17 21:09:51 +01:00
adator
d37c152160 Update to version 6.0.3 2024-11-17 21:09:14 +01:00
adator
39412fc1c0 Merge pull request #67 from adator85/V6.X.X
V6.0.2
2024-11-15 22:14:55 +01:00
adator
b81f502b95 V6.0.2 2024-11-15 22:14:11 +01:00
adator
e148659d00 Merge pull request #66 from adator85/V6.X.X
V6.0.1
2024-11-11 23:38:26 +01:00
adator
44da01945c V6.0.1 2024-11-11 23:38:05 +01:00
adator
71a7d29b08 Merge pull request #65 from adator85/V6.X.X
Update the version 6
2024-11-11 15:39:20 +01:00
adator
71170baf1a Merge pull request #64 from adator85/V6.X.X
Fix clone reply
2024-11-07 23:43:02 +01:00
adator
1b20435b83 Merge pull request #63 from adator85/V6.X.X
fix main file name
2024-11-07 23:11:26 +01:00
adator
008dacfde6 Merge pull request #62 from adator85/V6.X.X
Disable console
2024-11-07 23:03:47 +01:00
adator
5347c45579 Merge pull request #61 from adator85/V6.X.X
V6.0.0
2024-11-07 22:50:18 +01:00
adator
63130fbc06 Merge pull request #60 from adator85/V6.X.X
V6.0.0
2024-11-07 22:46:20 +01:00
adator
b27b503d78 Merge pull request #59 from adator85/V5.X.X
V5.3.9
2024-10-13 22:22:00 +02:00
adator
36e3835e6c Merge pull request #58 from adator85/V5.X.X
update websocket connection
2024-10-06 21:58:24 +02:00
adator
2c78025bfb Merge pull request #57 from adator85/V5.X.X
V5.3.8
2024-10-06 21:49:13 +02:00
adator
979ba40c05 Merge pull request #56 from adator85/V5.X.X
V5.x.x
2024-10-04 01:10:33 +02:00
adator
cea69c1580 Merge pull request #54 from adator85/dev
V5.3.6
2024-10-02 23:40:38 +02:00
adator
c404cc3234 Merge pull request #53 from adator85/dev
Dev
2024-10-02 00:06:54 +02:00
adator
80b329dd5d Merge pull request #52 from adator85/dev
You need to have unrealirc_rpc_py v1.0.3
2024-09-30 01:40:36 +02:00
adator
f7b49c151f Merge pull request #51 from adator85/dev
V5.3.4
2024-09-29 22:43:28 +02:00
adator
1ee9b7e3ff Merge pull request #50 from adator85/dev
Dev
2024-09-26 01:00:39 +02:00
adator
4d0087623c Merge pull request #49 from adator85/dev
unsubscribe before unload
2024-09-22 23:54:22 +02:00
adator
dc20f5ec3c Merge pull request #48 from adator85/dev
Dev
2024-09-22 23:20:37 +02:00
adator
110cae3b84 Merge pull request #47 from adator85/dev
Update the way to clean exceptions and bans
2024-09-22 16:45:54 +02:00
adator
857cbfc85d Merge pull request #46 from adator85/dev
Send the ready msg to channel log
2024-09-22 16:33:49 +02:00
adator
3518589e9c Merge pull request #45 from adator85/dev
Fix ConfModel error
2024-09-22 16:31:35 +02:00
adator
e14c97de03 Merge pull request #44 from adator85/dev
V5.3.0
2024-09-22 16:20:45 +02:00
adator
69360be3ad Merge pull request #43 from adator85/dev
Update info command
2024-09-21 20:28:29 +02:00
adator
bfa90c6bd5 Merge pull request #42 from adator85/dev
V5.2.9
2024-09-21 20:22:42 +02:00
adator
5c8378a0e7 Merge pull request #41 from adator85/dev
V5.2.9
2024-09-21 16:43:14 +02:00
adator
e3b212ea88 Merge pull request #40 from adator85/dev
finetune clone connection
2024-09-20 23:13:33 +02:00
adator
0c2a350d38 Merge pull request #39 from adator85/dev
Dev
2024-09-20 21:12:59 +02:00
adator
1cea8d0601 Merge pull request #38 from adator85/dev
V5.2.1
2024-09-15 03:09:22 +02:00
adator
652b400d5e Merge pull request #37 from adator85/dev
update mode clone
2024-09-15 02:50:27 +02:00
adator
2f8b965b59 Merge pull request #36 from adator85/dev
Dev
2024-09-15 02:04:32 +02:00
adator
3c043cefd8 Merge pull request #35 from adator85/dev
V5.1.8
2024-09-08 00:42:57 +02:00
adator
59a75cecd8 Merge pull request #34 from adator85/dev
V5.1.7
2024-09-03 00:21:32 +02:00
adator
71053437a7 Merge pull request #33 from adator85/dev
V5.1.6
2024-09-01 22:15:54 +02:00
adator
7796d05206 Merge pull request #32 from adator85/dev
Update vote kick commands
2024-09-01 18:55:57 +02:00
adator
5f2567f9e5 Merge pull request #31 from adator85/dev
mod_command update
2024-09-01 17:30:05 +02:00
adator
aaa1dd9a1a Merge pull request #30 from adator85/dev
adding Say command for clones
2024-09-01 16:40:25 +02:00
adator
a02f2f9a26 Merge pull request #29 from adator85/dev
update mod_clone module
2024-09-01 15:54:50 +02:00
adator
d73adb6f0b Merge pull request #28 from adator85/dev
update readme
2024-09-01 15:35:59 +02:00
adator
b812e64992 Merge pull request #27 from adator85/dev
Dev
2024-09-01 15:24:18 +02:00
adator
9bd1f68df2 Merge pull request #26 from adator85/dev
Dev
2024-09-01 14:59:38 +02:00
adator
f44b08bf36 Merge pull request #25 from adator85/dev
fix Installation
2024-08-29 01:36:38 +02:00
adator
1a19e1613a Merge pull request #24 from adator85/dev
Fix Bug installation
2024-08-29 01:31:19 +02:00
adator
cdc15b7b47 Merge pull request #23 from adator85/dev
Dev
2024-08-29 01:16:55 +02:00
adator
31fe9f62ec Merge pull request #22 from adator85/dev
Dev
2024-08-24 01:39:11 +02:00
adator
f0853e3afb Merge pull request #21 from adator85/dev
New Installation file created for unix system
2024-08-22 01:02:00 +02:00
adator
6dade09257 Merge pull request #20 from adator85/dev
README Update
2024-08-21 00:50:31 +02:00
adator
9533b010b2 Merge pull request #19 from adator85/dev
V5.0.4 - Delete a user when a user has been kicked
2024-08-20 02:24:37 +02:00
adator
824db73590 Merge pull request #18 from adator85/dev
Delete channel mode information
2024-08-20 02:14:31 +02:00
adator
96bf4b6f80 Merge pull request #17 from adator85/dev
Fix channel update
2024-08-20 02:08:09 +02:00
adator
922336363e Merge pull request #16 from adator85/dev
Dev
2024-08-20 01:56:04 +02:00
14 changed files with 595 additions and 352 deletions

View File

@@ -194,14 +194,19 @@ class Base:
file_hanlder = logging.FileHandler(f'logs{self.Config.OS_SEP}defender.log',encoding='UTF-8') file_hanlder = logging.FileHandler(f'logs{self.Config.OS_SEP}defender.log',encoding='UTF-8')
file_hanlder.setLevel(self.Config.DEBUG_LEVEL) file_hanlder.setLevel(self.Config.DEBUG_LEVEL)
stdout_handler = logging.StreamHandler()
stdout_handler.setLevel(50)
# Define log format # Define log format
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s - %(lineno)d - %(funcName)s - %(message)s') formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s - %(lineno)d - %(funcName)s - %(message)s')
# Apply log format # Apply log format
file_hanlder.setFormatter(formatter) file_hanlder.setFormatter(formatter)
stdout_handler.setFormatter(formatter)
# Add handler to logs # Add handler to logs
self.logs.addHandler(file_hanlder) self.logs.addHandler(file_hanlder)
self.logs.addHandler(stdout_handler)
# Apply the filter # Apply the filter
self.logs.addFilter(self.replace_filter) self.logs.addFilter(self.replace_filter)

View File

@@ -2,6 +2,8 @@ from re import findall
from typing import Union, Literal, TYPE_CHECKING from typing import Union, Literal, TYPE_CHECKING
from dataclasses import asdict from dataclasses import asdict
from core.classes import user
if TYPE_CHECKING: if TYPE_CHECKING:
from core.definition import MChannel from core.definition import MChannel
from core.base import Base from core.base import Base
@@ -31,6 +33,10 @@ class Channel:
result = False result = False
exist = False exist = False
if not self.Is_Channel(newChan.name):
self.Logs.error(f"The channel {newChan.name} is not valid, channel must start with #")
return False
for record in self.UID_CHANNEL_DB: for record in self.UID_CHANNEL_DB:
if record.name.lower() == newChan.name.lower(): if record.name.lower() == newChan.name.lower():
# If the channel exist, update the user list and do not go further # If the channel exist, update the user list and do not go further
@@ -129,6 +135,29 @@ class Channel:
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.Logs.error(f'{err}')
def is_user_present_in_channel(self, channel_name: str, uid: str) -> bool:
"""Check if a user is present in the channel
Args:
channel_name (str): The channel to check
uid (str): The UID
Returns:
bool: True if the user is present in the channel
"""
user_found = False
chan = self.get_Channel(channel_name=channel_name)
if chan is None:
return user_found
clean_uid = self.Base.clean_uid(uid=uid)
for chan_uid in chan.uids:
if self.Base.clean_uid(chan_uid) == clean_uid:
user_found = True
break
return user_found
def clean_channel(self) -> None: def clean_channel(self) -> None:
"""Remove Channels if empty """Remove Channels if empty
""" """

View File

@@ -1,9 +1,11 @@
from re import match, findall from re import match, findall
from datetime import datetime from datetime import datetime
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Union
from ssl import SSLEOFError, SSLError from ssl import SSLEOFError, SSLError
from dataclasses import dataclass from dataclasses import dataclass
from websockets import serve
if TYPE_CHECKING: if TYPE_CHECKING:
from core.irc import Irc from core.irc import Irc
@@ -17,6 +19,12 @@ 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',
'EOS', 'PRIVMSG', 'MODE', 'UMODE2',
'VERSION', 'REPUTATION', 'SVS2MODE',
'SLOG', 'NICK', 'PART', 'PONG'
]
self.__Base.logs.info(f"** Loading protocol [{__name__}]") self.__Base.logs.info(f"** Loading protocol [{__name__}]")
def send2socket(self, message: str, print_log: bool = True) -> None: def send2socket(self, message: str, print_log: bool = True) -> None:
@@ -104,6 +112,40 @@ class Unrealircd6:
except Exception as err: except Exception as err:
self.__Base.logs.error(f"General Error: {err}") self.__Base.logs.error(f"General Error: {err}")
def parse_server_msg(self, server_msg: list[str]) -> Union[str, None]:
"""Parse the server message and return the command
Args:
server_msg (list[str]): The Original server message >>
Returns:
Union[str, None]: Return the command protocol name
"""
protocol_exception = ['PING', 'SERVER', 'PROTOCTL']
increment = 0
server_msg_copy = server_msg.copy()
first_index = 0
second_index = 0
for index, element in enumerate(server_msg_copy):
# Handle the protocol exceptions ex. ping, server ....
if element in protocol_exception and index == 0:
return element
if element.startswith(':'):
increment += 1
first_index = index + 1 if increment == 1 else first_index
second_index = index if increment == 2 else second_index
second_index = len(server_msg_copy) if second_index == 0 else second_index
parsed_msg = server_msg_copy[first_index:second_index]
for cmd in parsed_msg:
if cmd in self.known_protocol:
return cmd
return None
def link(self): def link(self):
"""Créer le link et envoyer les informations nécessaires pour la """Créer le link et envoyer les informations nécessaires pour la
connexion au serveur. connexion au serveur.
@@ -408,6 +450,43 @@ class Unrealircd6:
self.__Irc.Channel.delete_user_from_channel(channel, userObj.uid) self.__Irc.Channel.delete_user_from_channel(channel, userObj.uid)
return None return None
def on_svs2mode(self, serverMsg: list[str]) -> None:
"""Handle svs2mode coming from a server
Args:
serverMsg (list[str]): Original server message
"""
try:
# >> [':00BAAAAAG', 'SVS2MODE', '001U01R03', '-r']
uid_user_to_edit = serverMsg[2]
umode = serverMsg[3]
userObj = self.__Irc.User.get_User(uid_user_to_edit)
if userObj is None:
return None
if self.__Irc.User.update_mode(userObj.uid, umode):
return None
return None
except IndexError as ie:
self.__Base.logs.error(f"{__name__} - Index Error: {ie}")
except Exception as err:
self.__Base.logs.error(f"{__name__} - General Error: {err}")
def on_mode(self, serverMsg: list[str]) -> None:
"""Handle mode coming from a server
Args:
serverMsg (list[str]): Original server message
"""
#['@msgid=d0ySx56Yd0nc35oHts2SkC-/J9mVUA1hfM6...', ':001', 'MODE', '#a', '+nt', '1723207536']
#['@unrealircd.org/userhost=adator@localhost;...', ':001LQ0L0C', 'MODE', '#services', '-l']
return None
def on_umode2(self, serverMsg: list[str]) -> None: def on_umode2(self, serverMsg: list[str]) -> None:
"""Handle umode2 coming from a server """Handle umode2 coming from a server
@@ -490,12 +569,32 @@ class Unrealircd6:
serverMsg (list[str]): Original server message serverMsg (list[str]): Original server message
""" """
# ['PROTOCTL', 'CHANMODES=beI,fkL,lFH,cdimnprstzCDGKMNOPQRSTVZ', 'USERMODES=diopqrstwxzBDGHIRSTWZ', 'BOOTED=1728815798', 'PREFIX=(qaohv)~&@%+', 'SID=001', 'MLOCK', 'TS=1730662755', 'EXTSWHOIS'] # ['PROTOCTL', 'CHANMODES=beI,fkL,lFH,cdimnprstzCDGKMNOPQRSTVZ', 'USERMODES=diopqrstwxzBDGHIRSTWZ', 'BOOTED=1728815798', 'PREFIX=(qaohv)~&@%+', 'SID=001', 'MLOCK', 'TS=1730662755', 'EXTSWHOIS']
if len(serverMsg) > 5: user_modes: str = None
if '=' in serverMsg[5]: prefix: str = None
serveur_hosting_id = str(serverMsg[5]).split('=') host_server_id: str = None
self.__Config.HSID = serveur_hosting_id[1]
if 'USERMODES=' in serverMsg[2]: for msg in serverMsg:
self.__Settings.USER_MODES = list(serverMsg[2].split('=')[1]) pattern = None
if msg.startswith('PREFIX='):
pattern = r'^PREFIX=\((.*)\).*$'
find_match = match(pattern, msg)
prefix = find_match.group(1) if find_match else None
if find_match:
prefix = find_match.group(1)
elif msg.startswith('USERMODES='):
pattern = r'^USERMODES=(.*)$'
find_match = match(pattern, msg)
user_modes = find_match.group(1) if find_match else None
elif msg.startswith('SID='):
host_server_id = msg.split('=')[1]
if user_modes is None or prefix is None or host_server_id is None:
return None
self.__Config.HSID = host_server_id
self.__Settings.PROTOCTL_USER_MODES = list(user_modes)
self.__Settings.PROTOCTL_PREFIX = list(prefix)
return None return None
@@ -534,8 +633,11 @@ class Unrealircd6:
# ':001T6VU3F', '001JGWB2K', '@11ZAAAAAB', # ':001T6VU3F', '001JGWB2K', '@11ZAAAAAB',
# '001F16WGR', '001X9YMGQ', '*+001DYPFGP', '@00BAAAAAJ', '001AAGOG9', '001FMFVG8', '001DAEEG7', # '001F16WGR', '001X9YMGQ', '*+001DYPFGP', '@00BAAAAAJ', '001AAGOG9', '001FMFVG8', '001DAEEG7',
# '&~G:unknown-users', '"~G:websocket-users', '"~G:known-users', '"~G:webirc-users'] # '&~G:unknown-users', '"~G:websocket-users', '"~G:known-users', '"~G:webirc-users']
# [':00B', 'SJOIN', '1731872579', '#services', '+', ':00BAAAAAB']
serverMsg_copy = serverMsg.copy() serverMsg_copy = serverMsg.copy()
if serverMsg_copy[0].startswith('@'):
serverMsg_copy.pop(0) serverMsg_copy.pop(0)
channel = str(serverMsg_copy[3]).lower() channel = str(serverMsg_copy[3]).lower()
len_cmd = len(serverMsg_copy) len_cmd = len(serverMsg_copy)
list_users:list = [] list_users:list = []
@@ -630,7 +732,7 @@ class Unrealircd6:
else: else:
geoip = None geoip = None
score_connexion = 0 score_connexion = self.__Irc.first_score
self.__Irc.User.insert( self.__Irc.User.insert(
self.__Irc.Loader.Definition.MUser( self.__Irc.Loader.Definition.MUser(
@@ -662,7 +764,7 @@ class Unrealircd6:
serverMsg (list[str]): List of str coming from the server serverMsg (list[str]): List of str coming from the server
""" """
try: try:
#
pong = str(serverMsg[1]).replace(':','') pong = str(serverMsg[1]).replace(':','')
self.send2socket(f"PONG :{pong}", print_log=False) self.send2socket(f"PONG :{pong}", print_log=False)
@@ -754,7 +856,7 @@ class Unrealircd6:
def on_version_msg(self, serverMsg: list[str]) -> None: def on_version_msg(self, serverMsg: list[str]) -> None:
"""Handle version coming from the server """Handle version coming from the server
\n ex. /version Defender
Args: Args:
serverMsg (list[str]): Original message from the server serverMsg (list[str]): Original message from the server
""" """
@@ -776,7 +878,7 @@ class Unrealircd6:
response_005 = ' | '.join(modules) response_005 = ' | '.join(modules)
self.send2socket(f':{self.__Config.SERVICE_HOST} 005 {getUser.nickname} {response_005} are supported by this server') self.send2socket(f':{self.__Config.SERVICE_HOST} 005 {getUser.nickname} {response_005} are supported by this server')
response_005 = ''.join(self.__Settings.USER_MODES) response_005 = ''.join(self.__Settings.PROTOCTL_USER_MODES)
self.send2socket(f":{self.__Config.SERVICE_HOST} 005 {getUser.nickname} {response_005} are supported by this server") self.send2socket(f":{self.__Config.SERVICE_HOST} 005 {getUser.nickname} {response_005} are supported by this server")
return None return None

View File

@@ -11,4 +11,5 @@ class Settings:
CONSOLE: bool = False CONSOLE: bool = False
USER_MODES: list[str] = [] PROTOCTL_USER_MODES: list[str] = []
PROTOCTL_PREFIX: list[str] = []

View File

@@ -92,7 +92,7 @@ class User:
return False return False
liste_umodes = list(umodes) liste_umodes = list(umodes)
final_umodes_liste = [x for x in self.Base.Settings.USER_MODES if x in liste_umodes] final_umodes_liste = [x for x in self.Base.Settings.PROTOCTL_USER_MODES if x in liste_umodes]
final_umodes = ''.join(final_umodes_liste) final_umodes = ''.join(final_umodes_liste)
userObj.umodes = f"+{final_umodes}" userObj.umodes = f"+{final_umodes}"

View File

@@ -1,3 +1,5 @@
from ast import parse
from http import server
import sys import sys
import socket import socket
import threading import threading
@@ -73,10 +75,13 @@ class Irc:
self.autolimit_started: bool = False self.autolimit_started: bool = False
"""This variable is to make sure the thread is not running""" """This variable is to make sure the thread is not running"""
self.first_score: int = 100 # define first reputation score to 0
self.first_score: int = 0
# Define the dict that will contain all loaded modules
self.loaded_classes:dict[str, 'Irc'] = {} # Definir la variable qui contiendra la liste modules chargés self.loaded_classes:dict[str, 'Irc'] = {} # Definir la variable qui contiendra la liste modules chargés
# Define the IrcSocket object
self.IrcSocket:Union[socket.socket, SSLSocket] = None self.IrcSocket:Union[socket.socket, SSLSocket] = None
# Liste des commandes internes du bot # Liste des commandes internes du bot
@@ -731,109 +736,28 @@ class Irc:
""" """
try: try:
original_response: list[str] = data.copy() original_response: list[str] = data.copy()
interm_response: list[str] = data.copy() interm_response: list[str] = data.copy()
"""This the original without first value""" """This the original without first value"""
interm_response.pop(0) interm_response.pop(0)
if len(original_response) == 0 or len(original_response) == 1: if len(original_response) == 0 or len(original_response) == 1:
self.Logs.warning(f'Size ({str(len(original_response))}) - {original_response}') self.Logs.warning(f'Size ({str(len(original_response))}) - {original_response}')
return False return False
if len(original_response) == 7: parsed_protocol = self.Protocol.parse_server_msg(original_response.copy())
if original_response[2] == 'PRIVMSG' and original_response[4] == ':auth':
data_copy = original_response.copy()
data_copy[6] = '**********'
self.Logs.debug(f">> {data_copy}")
else:
self.Logs.debug(f">> {original_response}")
else:
self.Logs.debug(f">> {original_response}")
match original_response[0]: match parsed_protocol:
case 'PING': case 'PING':
# Sending PONG response to the serveur self.Protocol.on_server_ping(serverMsg=original_response)
self.Protocol.on_server_ping(original_response) self.Logs.debug(f"** handle {parsed_protocol}")
return None return None
case 'PROTOCTL': case 'SJOIN':
#['PROTOCTL', 'CHANMODES=beI,fkL,lFH,cdimnprstzCDGKMNOPQRSTVZ', 'USERMODES=diopqrstwxzBDGHIRSTWZ', 'BOOTED=1702138935', self.Protocol.on_sjoin(serverMsg=original_response)
# 'PREFIX=(qaohv)~&@%+', 'SID=001', 'MLOCK', 'TS=1703793941', 'EXTSWHOIS'] self.Logs.debug(f"** handle {parsed_protocol}")
# GET SERVER ID HOST
self.Protocol.on_protoctl(serverMsg=original_response)
return None
case _:
pass
if len(original_response) < 2:
return False
match original_response[1]:
case 'PING':
# Sending PONG response to the serveur
self.Protocol.on_server_ping(original_response)
return None
case 'SLOG':
# self.Base.scan_ports(cmd[7])
# if self.Config.ABUSEIPDB == 1:
# self.Base.create_thread(self.abuseipdb_scan, (cmd[7], ))
pass
case 'VERSION':
self.Protocol.on_version_msg(original_response)
case 'UMODE2':
# [':adator_', 'UMODE2', '-i']
self.Protocol.on_umode2(serverMsg=original_response)
case 'SQUIT':
self.Protocol.on_squit(serverMsg=original_response)
case 'REPUTATION':
# :001 REPUTATION 127.0.0.1 118
try:
self.first_connexion_ip = original_response[2]
self.first_score = 0
if str(original_response[3]).find('*') != -1:
# If * available, it means that an ircop changed the repurtation score
# means also that the user exist will try to update all users with same IP
self.first_score = int(str(original_response[3]).replace('*',''))
for user in self.User.UID_DB:
if user.remote_ip == self.first_connexion_ip:
user.score_connexion = self.first_score
else:
self.first_score = int(original_response[3])
# Possibilité de déclancher les bans a ce niveau.
except IndexError as ie:
self.Logs.error(f'{ie}')
except ValueError as ve:
self.first_score = 0
self.Logs.error(f'Impossible to convert first_score: {ve}')
case '320':
#:irc.deb.biz.st 320 PyDefender IRCParis07 :is in security-groups: known-users,webirc-users,tls-and-known-users,tls-users
pass
case '318':
#:irc.deb.biz.st 318 PyDefender IRCParis93 :End of /WHOIS list.
pass
case 'MD':
# [':001', 'MD', 'client', '001CG0TG7', 'webirc', ':2']
pass
case 'EOS':
case 'EOS': # TODO
hsid = str(original_response[0]).replace(':','') hsid = str(original_response[0]).replace(':','')
if hsid == self.Config.HSID: if hsid == self.Config.HSID:
if self.Config.DEFENDER_INIT == 1: if self.Config.DEFENDER_INIT == 1:
@@ -886,45 +810,9 @@ class Irc:
classe_object.cmd(original_response) classe_object.cmd(original_response)
# Stop here When EOS # Stop here When EOS
self.Logs.debug(f"** handle {parsed_protocol}")
return None return None
case _:
pass
if len(original_response) < 3:
return False
match original_response[2]:
case 'VERSION':
self.Protocol.on_version_msg(original_response)
case 'QUIT':
self.Protocol.on_quit(serverMsg=original_response)
case 'PONG':
# ['@msgid=aTNJhp17kcPboF5diQqkUL;time=2023-12-28T20:35:58.411Z', ':irc.deb.biz.st', 'PONG', 'irc.deb.biz.st', ':Dev-PyDefender']
self.Base.execute_periodic_action()
case 'NICK':
self.Protocol.on_nick(original_response)
case 'MODE':
#['@msgid=d0ySx56Yd0nc35oHts2SkC-/J9mVUA1hfM6+Z4494xWUg;time=2024-08-09T12:45:36.651Z',
# ':001', 'MODE', '#a', '+nt', '1723207536']
# [':adator_', 'UMODE2', '-i']
pass
case 'SJOIN':
self.Protocol.on_sjoin(serverMsg=original_response)
case 'PART':
self.Protocol.on_part(serverMsg=original_response)
case 'UID': case 'UID':
try: try:
self.Protocol.on_uid(serverMsg=original_response) self.Protocol.on_uid(serverMsg=original_response)
@@ -932,10 +820,76 @@ class Irc:
for classe_name, classe_object in self.loaded_classes.items(): for classe_name, classe_object in self.loaded_classes.items():
classe_object.cmd(original_response) classe_object.cmd(original_response)
self.Logs.debug(f"** handle {parsed_protocol}")
except Exception as err: except Exception as err:
self.Logs.error(f'General Error: {err}') self.Logs.error(f'General Error: {err}')
case 'PRIVMSG': case 'QUIT':
self.Protocol.on_quit(serverMsg=original_response)
self.Logs.debug(f"** handle {parsed_protocol}")
case 'PROTOCTL':
self.Protocol.on_protoctl(serverMsg=original_response)
self.Logs.debug(f"** handle {parsed_protocol}")
case 'SVS2MODE':
# >> [':00BAAAAAG', 'SVS2MODE', '001U01R03', '-r']
self.Protocol.on_svs2mode(serverMsg=original_response)
self.Logs.debug(f"** handle {parsed_protocol}")
case 'SQUIT':
self.Protocol.on_squit(serverMsg=original_response)
self.Logs.debug(f"** handle {parsed_protocol}")
case 'PART':
self.Protocol.on_part(serverMsg=parsed_protocol)
self.Logs.debug(f"** handle {parsed_protocol}")
case 'VERSION':
self.Protocol.on_version_msg(serverMsg=original_response)
self.Logs.debug(f"** handle {parsed_protocol}")
case 'UMODE2':
# [':adator_', 'UMODE2', '-i']
self.Protocol.on_umode2(serverMsg=original_response)
self.Logs.debug(f"** handle {parsed_protocol}")
case 'NICK':
self.Protocol.on_nick(serverMsg=original_response)
self.Logs.debug(f"** handle {parsed_protocol}")
case 'REPUTATION': # TODO
# :001 REPUTATION 127.0.0.1 118
try:
self.first_connexion_ip = original_response[2]
self.first_score = 0
if str(original_response[3]).find('*') != -1:
# If * available, it means that an ircop changed the repurtation score
# means also that the user exist will try to update all users with same IP
self.first_score = int(str(original_response[3]).replace('*',''))
for user in self.User.UID_DB:
if user.remote_ip == self.first_connexion_ip:
user.score_connexion = self.first_score
else:
self.first_score = int(original_response[3])
self.Logs.debug(f"** handle {parsed_protocol}")
# Possibilité de déclancher les bans a ce niveau.
except IndexError as ie:
self.Logs.error(f'{ie}')
except ValueError as ve:
self.first_score = 0
self.Logs.error(f'Impossible to convert first_score: {ve}')
case 'SLOG': # TODO
self.Logs.debug(f"** handle {parsed_protocol}")
case 'MD': # TODO
self.Logs.debug(f"** handle {parsed_protocol}")
case 'PRIVMSG': # TODO
try: try:
# Supprimer la premiere valeur # Supprimer la premiere valeur
cmd = interm_response.copy() cmd = interm_response.copy()
@@ -975,7 +929,7 @@ class Irc:
self.Base.log_cmd(user_trigger, cmd_to_send) self.Base.log_cmd(user_trigger, cmd_to_send)
fromchannel = str(cmd[2]).lower() if self.Channel.Is_Channel(cmd[2]) else None fromchannel = str(cmd[2]).lower() if self.Channel.Is_Channel(cmd[2]) else None
self._hcmds(user_trigger, fromchannel, arg, cmd) self.hcmds(user_trigger, fromchannel, arg, cmd)
if cmd[2] == self.Config.SERVICE_ID: if cmd[2] == self.Config.SERVICE_ID:
pattern = fr'^:.*?:(.*)$' pattern = fr'^:.*?:(.*)$'
@@ -1013,14 +967,42 @@ class Irc:
if len(arg) >= 2: if len(arg) >= 2:
fromchannel = str(arg[1]).lower() if self.Channel.Is_Channel(arg[1]) else None fromchannel = str(arg[1]).lower() if self.Channel.Is_Channel(arg[1]) else None
self._hcmds(user_trigger, fromchannel, arg, cmd) self.hcmds(user_trigger, fromchannel, arg, cmd)
# print(f"** handle {parsed_protocol}")
except IndexError as io: except IndexError as io:
self.Logs.error(f'{io}') self.Logs.error(f'{io}')
case _: case 'PONG': # TODO
pass self.Logs.debug(f"** handle {parsed_protocol}")
case 'MODE': # TODO
#['@msgid=d0ySx56Yd0nc35oHts2SkC-/J9mVUA1hfM6...', ':001', 'MODE', '#a', '+nt', '1723207536']
#['@unrealircd.org/userhost=adator@localhost;...', ':001LQ0L0C', 'MODE', '#services', '-l']
self.Logs.debug(f"** handle {parsed_protocol}")
case '320': # TODO
#:irc.deb.biz.st 320 PyDefender IRCParis07 :is in security-groups: known-users,webirc-users,tls-and-known-users,tls-users
self.Logs.debug(f"** handle {parsed_protocol}")
case '318': # TODO
#:irc.deb.biz.st 318 PyDefender IRCParis93 :End of /WHOIS list.
self.Logs.debug(f"** handle {parsed_protocol}")
case None:
self.Logs.debug(f"** TO BE HANDLE {original_response}")
if len(original_response) == 7:
if original_response[2] == 'PRIVMSG' and original_response[4] == ':auth':
data_copy = original_response.copy()
data_copy[6] = '**********'
self.Logs.debug(f">> {data_copy}")
else:
self.Logs.debug(f">> {original_response}")
else:
self.Logs.debug(f">> {original_response}")
if len(original_response) > 2:
if original_response[2] != 'UID': if original_response[2] != 'UID':
# Envoyer la commande aux classes dynamiquement chargées # Envoyer la commande aux classes dynamiquement chargées
for classe_name, classe_object in self.loaded_classes.items(): for classe_name, classe_object in self.loaded_classes.items():
@@ -1032,8 +1014,8 @@ class Irc:
self.Logs.error(f"General Error: {err}") self.Logs.error(f"General Error: {err}")
self.Logs.error(f"General Error: {traceback.format_exc()}") self.Logs.error(f"General Error: {traceback.format_exc()}")
def _hcmds(self, user: str, channel: Union[str, None], cmd: list, fullcmd: list = []) -> None: def hcmds(self, user: str, channel: Union[str, None], cmd: list, fullcmd: list = []) -> None:
"""_summary_ """Create
Args: Args:
user (str): The user who sent the query user (str): The user who sent the query
@@ -1064,7 +1046,7 @@ class Irc:
# Envoyer la commande aux classes dynamiquement chargées # Envoyer la commande aux classes dynamiquement chargées
if command != 'notallowed': if command != 'notallowed':
for classe_name, classe_object in self.loaded_classes.items(): for classe_name, classe_object in self.loaded_classes.items():
classe_object._hcmds(user, channel, cmd, fullcmd) classe_object.hcmds(user, channel, cmd, fullcmd)
match command: match command:
@@ -1184,6 +1166,10 @@ class Irc:
case 'auth': case 'auth':
# ['auth', 'adator', 'password'] # ['auth', 'adator', 'password']
if len(cmd) != 3:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} [nickname] [password]")
return None
current_command = cmd[0] current_command = cmd[0]
user_to_log = self.User.get_nickname(cmd[1]) user_to_log = self.User.get_nickname(cmd[1])
password = cmd[2] password = cmd[2]
@@ -1241,25 +1227,30 @@ class Irc:
case 'editaccess': case 'editaccess':
# .editaccess [USER] [PASSWORD] [LEVEL] # .editaccess [USER] [PASSWORD] [LEVEL]
try: try:
user_to_edit = cmd[1] if len(cmd) < 3:
user_new_level = int(cmd[3]) self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Right command : /msg {dnickname} editaccess [nickname] [NEWPASSWORD] [NEWLEVEL]")
user_password = self.Base.crypt_password(cmd[2]) self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"level: from 1 to 4")
if len(cmd) < 4 or len(cmd) > 4:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{self.Config.SERVICE_PREFIX}editaccess [USER] [NEWPASSWORD] [NEWLEVEL]")
return None return None
user_to_edit = cmd[1]
user_password = self.Base.crypt_password(cmd[2])
get_admin = self.Admin.get_Admin(fromuser) get_admin = self.Admin.get_Admin(fromuser)
if get_admin is None: if get_admin is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" This user {fromuser} has no Admin access") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"This user {fromuser} has no Admin access")
return None return None
current_user = self.User.get_nickname(fromuser) current_user = self.User.get_nickname(fromuser)
current_uid = self.User.get_uid(fromuser) current_uid = self.User.get_uid(fromuser)
current_user_level = get_admin.level current_user_level = get_admin.level
user_new_level = int(cmd[3]) if len(cmd) == 4 else get_admin.level
if current_user == fromuser:
user_new_level = get_admin.level
if user_new_level > 5: if user_new_level > 5:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" Maximum authorized level is 5") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Maximum authorized level is 5")
return None return None
# Rechercher le user dans la base de données. # Rechercher le user dans la base de données.
@@ -1271,7 +1262,7 @@ class Irc:
if not isUserExist is None: if not isUserExist is None:
if current_user_level < int(isUserExist[1]): if current_user_level < int(isUserExist[1]):
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" You are not allowed to edit this access") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You are not allowed to edit this access")
return None return None
if current_user_level == int(isUserExist[1]) and current_user != user_to_edit: if current_user_level == int(isUserExist[1]) and current_user != user_to_edit:

View File

@@ -1,5 +1,4 @@
from core.classes import user, admin, channel, clone, reputation, settings from core.classes import user, admin, channel, clone, reputation, settings
import utils
import core.definition as df import core.definition as df
import core.base as baseModule import core.base as baseModule
import core.classes.config as confModule import core.classes.config as confModule
@@ -15,8 +14,6 @@ class Loader:
self.BaseModule: baseModule = baseModule self.BaseModule: baseModule = baseModule
self.Utils: utils
# Load Classes # Load Classes
self.Settings: settings = settings.Settings() self.Settings: settings = settings.Settings()

View File

@@ -306,7 +306,7 @@ class Clone():
except Exception as err: except Exception as err:
self.Logs.error(f'General Error: {err}') self.Logs.error(f'General Error: {err}')
def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: def hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None:
try: try:
command = str(cmd[0]).lower() command = str(cmd[0]).lower()

View File

@@ -1,10 +1,12 @@
from typing import TYPE_CHECKING from typing import Union, TYPE_CHECKING
from dataclasses import dataclass, fields from dataclasses import dataclass
if TYPE_CHECKING: if TYPE_CHECKING:
from core.irc import Irc from core.irc import Irc
from core.definition import MUser
from sqlalchemy import CursorResult, Row, Sequence
class Command(): class Command:
@dataclass @dataclass
class ModConfModel: class ModConfModel:
@@ -20,6 +22,9 @@ class Command():
# Add Irc Object to the module (Mandatory) # Add Irc Object to the module (Mandatory)
self.Irc = ircInstance self.Irc = ircInstance
# Add Loader Object to the module (Mandatory)
self.Loader = ircInstance.Loader
# Add Protocol object to the module (Mandatory) # Add Protocol object to the module (Mandatory)
self.Protocol = ircInstance.Protocol self.Protocol = ircInstance.Protocol
@@ -42,12 +47,12 @@ class Command():
self.commands_level = { self.commands_level = {
1: ['join', 'part','owner', 'deowner', 'protect', 'deprotect', 'op', 1: ['join', 'part','owner', 'deowner', 'protect', 'deprotect', 'op',
'deop', 'halfop', 'dehalfop', 'voice','devoice', 'topic'], 'deop', 'halfop', 'dehalfop', 'voice','devoice', 'topic'],
2: ['opall', 'deopall', 'devoiceall', 'voiceall', 'ban', 2: ['opall', 'deopall', 'devoiceall', 'voiceall', 'ban', 'automode',
'unban','kick', 'kickban', 'umode', 'mode', 'get_mode', 'svsjoin', 'svspart', 'svsnick', 'unban', 'kick', 'kickban', 'umode',
'mode', 'get_mode', 'svsjoin', 'svspart', 'svsnick',
'wallops', 'globops','gnotice','whois', 'names', 'invite', 'inviteme', 'wallops', 'globops','gnotice','whois', 'names', 'invite', 'inviteme',
'sajoin', 'sapart', 'sajoin', 'sapart', 'kill', 'gline', 'ungline', 'kline',
'kill', 'gline', 'ungline', 'kline', 'unkline', 'shun', 'unshun', 'unkline', 'shun', 'unshun', 'glinelist', 'shunlist', 'klinelist'],
'glinelist', 'shunlist', 'klinelist'],
3: ['map'] 3: ['map']
} }
@@ -74,7 +79,7 @@ class Command():
return None return None
def __set_commands(self, commands:dict[int, list[str]]) -> None: def __set_commands(self, commands: dict[int, list[str]]) -> None:
"""### Rajoute les commandes du module au programme principal """### Rajoute les commandes du module au programme principal
Args: Args:
@@ -82,7 +87,7 @@ class Command():
""" """
for level, com in commands.items(): for level, com in commands.items():
for c in commands[level]: for c in commands[level]:
if not c in self.Irc.commands: if c not in self.Irc.commands:
self.Irc.commands_level[level].append(c) self.Irc.commands_level[level].append(c)
self.Irc.commands.append(c) self.Irc.commands.append(c)
@@ -98,14 +103,17 @@ class Command():
None: Aucun retour n'es attendu None: Aucun retour n'es attendu
""" """
table_logs = '''CREATE TABLE IF NOT EXISTS test_logs ( table_automode = '''CREATE TABLE IF NOT EXISTS command_automode (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
datetime TEXT, created_on TEXT,
server_msg TEXT updated_on TEXT,
nickname TEXT,
channel TEXT,
mode TEXT
) )
''' '''
# self.Base.db_execute_query(table_logs) self.Base.db_execute_query(table_automode)
return None return None
def __load_module_configuration(self) -> None: def __load_module_configuration(self) -> None:
@@ -136,11 +144,11 @@ class Command():
return None return None
def cmd(self, data: list) -> None: def cmd(self, data: list[str]) -> None:
try:
service_id = self.Config.SERVICE_ID # service_id = self.Config.SERVICE_ID
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.Config.SERVICE_NICKNAME
dchanlog = self.Config.SERVICE_CHANLOG # dchanlog = self.Config.SERVICE_CHANLOG
red = self.Config.COLORS.red red = self.Config.COLORS.red
green = self.Config.COLORS.green green = self.Config.COLORS.green
bold = self.Config.COLORS.bold bold = self.Config.COLORS.bold
@@ -224,19 +232,146 @@ class Command():
case _: case _:
pass pass
if len(cmd) < 3:
return None return None
def _hcmds(self, user: str, channel: any, cmd: list, fullcmd: list = []) -> None: match cmd[2]:
case 'SJOIN':
# ['@msgid=yldTlbwAGbzCGUcCIHi3ku;time=2024-11-11T17:56:24.297Z', ':001', 'SJOIN', '1728815963', '#znc', ':001LQ0L0C']
# Check if the user has an automode
try:
if len(cmd) < 6:
return None
user_uid = self.User.clean_uid(cmd[5])
userObj: MUser = self.User.get_User(user_uid)
channel_name = cmd[4] if self.Channel.Is_Channel(cmd[4]) else None
if userObj is None:
return None
if 'r' not in userObj.umodes and 'o' not in userObj.umodes:
return None
db_data: dict[str, str] = {"nickname": userObj.nickname, "channel": channel_name}
db_query = self.Base.db_execute_query("SELECT id, mode FROM command_automode WHERE nickname = :nickname AND channel = :channel", db_data)
db_result = db_query.fetchone()
if db_result is not None:
id, mode = db_result
self.Protocol.send2socket(f":{self.Config.SERVICE_ID} MODE {channel_name} {mode} {userObj.nickname}")
except KeyError as ke:
self.Logs.error(f"Key Error: {err}")
except Exception as err:
self.Logs.error(f"General Error: {err}")
def hcmds(self, uidornickname: str, channel_name: Union[str, None], cmd: list, fullcmd: list = []) -> None:
command = str(cmd[0]).lower() command = str(cmd[0]).lower()
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.Config.SERVICE_NICKNAME
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
dchanlog = self.Config.SERVICE_CHANLOG dchanlog = self.Config.SERVICE_CHANLOG
self.user_to_notice = user self.user_to_notice = uidornickname
fromuser = user fromuser = uidornickname
fromchannel = channel fromchannel = channel_name
match command: match command:
case "automode":
# automode set nickname [+/-mode] #channel
# automode set adator +o #channel
try:
option: str = str(cmd[1]).lower()
match option:
case 'set':
allowed_modes: list[str] = self.Base.Settings.PROTOCTL_PREFIX # ['q','a','o','h','v']
if len(cmd) < 5:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} [nickname] [+/-mode] [#channel]")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AutoModes available: {' / '.join(allowed_modes)}")
return None
# userObj: MUser = self.User.get_User(str(cmd[2]))
nickname = str(cmd[2])
mode = str(cmd[3])
chan: str = str(cmd[4]).lower() if self.Channel.Is_Channel(cmd[4]) else None
sign = mode[0] if mode.startswith( ('+', '-')) else None
clean_mode = mode[1:] if len(mode) > 0 else None
if sign is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You must provide the flag mode + or -")
return None
if clean_mode not in allowed_modes:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}")
return None
if chan is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You should use one of those modes {' / '.join(allowed_modes)}")
return None
db_data: dict[str, str] = {"nickname": nickname, "channel": chan}
db_query = self.Base.db_execute_query(query="SELECT id FROM command_automode WHERE nickname = :nickname and channel = :channel", params=db_data)
db_result = db_query.fetchone()
if db_result is not None:
if sign == '+':
db_data = {"updated_on": self.Base.get_datetime(), "nickname": nickname, "channel": chan, "mode": mode}
db_result = self.Base.db_execute_query(query="UPDATE command_automode SET mode = :mode, updated_on = :updated_on WHERE nickname = :nickname and channel = :channel",
params=db_data)
if db_result.rowcount > 0:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} edited for {nickname} in {chan}")
elif sign == '-':
db_data = {"nickname": nickname, "channel": chan, "mode": f"+{clean_mode}"}
db_result = self.Base.db_execute_query(query="DELETE FROM command_automode WHERE nickname = :nickname and channel = :channel and mode = :mode",
params=db_data)
if db_result.rowcount > 0:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} deleted for {nickname} in {chan}")
else:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The mode [{mode}] has not been found for {nickname} in channel {chan}")
return None
# Instert a new automode
if sign == '+':
db_data = {"created_on": self.Base.get_datetime(), "updated_on": self.Base.get_datetime(), "nickname": nickname, "channel": chan, "mode": mode}
db_query = self.Base.db_execute_query(
query="INSERT INTO command_automode (created_on, updated_on, nickname, channel, mode) VALUES (:created_on, :updated_on, :nickname, :channel, :mode)",
params=db_data
)
if db_query.rowcount > 0:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Automode {mode} applied to {nickname} in {chan}")
if self.Channel.is_user_present_in_channel(chan, self.User.get_uid(nickname)):
self.Protocol.send2socket(f":{service_id} MODE {chan} {mode} {nickname}")
else:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"AUTOMODE {mode} cannot be added to {nickname} in {chan} because it doesn't exist")
case 'list':
db_query: CursorResult = self.Base.db_execute_query("SELECT nickname, channel, mode FROM command_automode")
db_results: Sequence[Row] = db_query.fetchall()
if not db_results:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,
msg="There is no automode to display.")
for db_result in db_results:
db_nickname, db_channel, db_mode = db_result
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,
msg=f"Nickname: {db_nickname} | Channel: {db_channel} | Mode: {db_mode}")
case _:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} SET [nickname] [+/-mode] [#channel]")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} LIST")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"[AUTOMODES AVAILABLE] are {' / '.join(allowed_modes)}")
except IndexError:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} SET [nickname] [+/-mode] [#channel]")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} LIST")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"[AUTOMODES AVAILABLE] are {' / '.join(self.Base.Settings.PROTOCTL_PREFIX)}")
except Exception as err:
self.Logs.error(f"General Error: {err}")
case 'deopall': case 'deopall':
try: try:
@@ -696,7 +831,7 @@ class Command():
chan = str(cmd[1]) chan = str(cmd[1])
if not self.Channel.Is_Channel(chan): if not self.Channel.Is_Channel(chan):
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The channel must start with #") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE")
return None return None
@@ -705,7 +840,7 @@ class Command():
if topic_msg: if topic_msg:
self.Protocol.send2socket(f':{dnickname} TOPIC {chan} :{topic_msg}') self.Protocol.send2socket(f':{dnickname} TOPIC {chan} :{topic_msg}')
else: else:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You need to specify the topic") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the topic")
except KeyError as ke: except KeyError as ke:
self.Logs.error(ke) self.Logs.error(ke)
@@ -723,7 +858,7 @@ class Command():
if wallops_msg: if wallops_msg:
self.Protocol.send2socket(f':{dnickname} WALLOPS {wallops_msg} ({dnickname})') self.Protocol.send2socket(f':{dnickname} WALLOPS {wallops_msg} ({dnickname})')
else: else:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You need to specify the wallops message") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the wallops message")
except KeyError as ke: except KeyError as ke:
self.Logs.error(ke) self.Logs.error(ke)
@@ -741,7 +876,7 @@ class Command():
if globops_msg: if globops_msg:
self.Protocol.send2socket(f':{dnickname} GLOBOPS {globops_msg} ({dnickname})') self.Protocol.send2socket(f':{dnickname} GLOBOPS {globops_msg} ({dnickname})')
else: else:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You need to specify the globops message") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the globops message")
except KeyError as ke: except KeyError as ke:
self.Logs.error(ke) self.Logs.error(ke)
@@ -759,7 +894,7 @@ class Command():
if gnotice_msg: if gnotice_msg:
self.Protocol.send_notice(nick_from=dnickname, nick_to='$*.*', msg=f"[{self.Config.COLORS.red}GLOBAL NOTICE{self.Config.COLORS.nogc}] {gnotice_msg}") self.Protocol.send_notice(nick_from=dnickname, nick_to='$*.*', msg=f"[{self.Config.COLORS.red}GLOBAL NOTICE{self.Config.COLORS.nogc}] {gnotice_msg}")
else: else:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You need to specify the global notice message") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the global notice message")
except KeyError as ke: except KeyError as ke:
self.Logs.error(ke) self.Logs.error(ke)
@@ -776,7 +911,7 @@ class Command():
nickname = str(cmd[1]) nickname = str(cmd[1])
if self.User.get_nickname(nickname) is None: if self.User.get_nickname(nickname) is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Nickname not found !") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nickname not found !")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME")
return None return None
@@ -796,7 +931,7 @@ class Command():
chan = str(cmd[1]) chan = str(cmd[1])
if not self.Channel.Is_Channel(chan): if not self.Channel.Is_Channel(chan):
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The channel must start with #") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #channel") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} #channel")
return None return None
@@ -817,12 +952,12 @@ class Command():
chan = str(cmd[2]) chan = str(cmd[2])
if not self.Channel.Is_Channel(chan): if not self.Channel.Is_Channel(chan):
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"The channel must start with #") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="The channel must start with #")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL")
return None return None
if self.User.get_nickname(nickname) is None: if self.User.get_nickname(nickname) is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Nickname not found !") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nickname not found !")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {str(cmd[0]).upper()} NICKNAME #CHANNEL")
return None return None
@@ -906,8 +1041,10 @@ class Command():
self.Logs.warning(f'Unknown Error: {str(err)}') self.Logs.warning(f'Unknown Error: {str(err)}')
case 'get_mode': case 'get_mode':
try:
self.Protocol.send2socket(f'MODE {channel}') self.Protocol.send2socket(f'MODE {fromchannel}')
except Exception as err:
self.Logs.error(f"General Error {err}")
case 'svsjoin': case 'svsjoin':
try: try:
@@ -927,7 +1064,7 @@ class Command():
case 'svspart': case 'svspart':
try: try:
# .svspart nickname #channel # svspart nickname #channel
nickname = str(cmd[1]) nickname = str(cmd[1])
channel = str(cmd[2]) channel = str(cmd[2])
if len(cmd) != 3: if len(cmd) != 3:

View File

@@ -4,10 +4,9 @@ import time
import re import re
import psutil import psutil
import requests import requests
from dataclasses import dataclass, fields, field from dataclasses import dataclass
from datetime import datetime from datetime import datetime
from typing import Union, TYPE_CHECKING from typing import Union, TYPE_CHECKING
from sys import exit
import core.definition as df import core.definition as df
# Le module crée devra réspecter quelques conditions # Le module crée devra réspecter quelques conditions
@@ -19,7 +18,7 @@ import core.definition as df
# 4 . Créer vos tables, en utilisant toujours le nom des votre classe en minuscule ==> defender_votre-table # 4 . Créer vos tables, en utilisant toujours le nom des votre classe en minuscule ==> defender_votre-table
# 3. Methode suivantes: # 3. Methode suivantes:
# cmd(self, data:list) # cmd(self, data:list)
# _hcmds(self, user:str, cmd: list) # hcmds(self, user:str, cmd: list)
# unload(self) # unload(self)
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -141,6 +140,8 @@ class Defender():
self.Base.create_thread(func=self.thread_local_scan) self.Base.create_thread(func=self.thread_local_scan)
self.Base.create_thread(func=self.thread_psutil_scan) self.Base.create_thread(func=self.thread_psutil_scan)
self.Base.create_thread(func=self.thread_reputation_timer) self.Base.create_thread(func=self.thread_reputation_timer)
if self.ModConfig.autolimit == 1:
self.Base.create_thread(func=self.thread_autolimit) self.Base.create_thread(func=self.thread_autolimit)
if self.ModConfig.reputation == 1: if self.ModConfig.reputation == 1:
@@ -149,7 +150,7 @@ class Defender():
return None return None
def __set_commands(self, commands:dict[int, list[str]]) -> None: def __set_commands(self, commands: dict[int, list[str]]) -> None:
"""### Rajoute les commandes du module au programme principal """### Rajoute les commandes du module au programme principal
Args: Args:
@@ -157,7 +158,7 @@ class Defender():
""" """
for level, com in commands.items(): for level, com in commands.items():
for c in commands[level]: for c in commands[level]:
if not c in self.Irc.commands: if c not in self.Irc.commands:
self.Irc.commands_level[level].append(c) self.Irc.commands_level[level].append(c)
self.Irc.commands.append(c) self.Irc.commands.append(c)
@@ -173,31 +174,15 @@ class Defender():
None: Aucun retour n'es attendu None: Aucun retour n'es attendu
""" """
table_channel = '''CREATE TABLE IF NOT EXISTS def_channels ( # table_autoop = '''CREATE TABLE IF NOT EXISTS defender_autoop (
id INTEGER PRIMARY KEY AUTOINCREMENT, # id INTEGER PRIMARY KEY AUTOINCREMENT,
datetime TEXT, # datetime TEXT,
channel TEXT # nickname TEXT,
) # channel TEXT
''' # )
# '''
table_config = '''CREATE TABLE IF NOT EXISTS def_config ( # self.Base.db_execute_query(table_autoop)
id INTEGER PRIMARY KEY AUTOINCREMENT,
datetime TEXT,
parameter TEXT,
value TEXT
)
'''
table_trusted = '''CREATE TABLE IF NOT EXISTS def_trusted (
id INTEGER PRIMARY KEY AUTOINCREMENT,
datetime TEXT,
user TEXT,
host TEXT,
vhost TEXT
)
'''
# self.Base.db_execute_query(table_channel)
# self.Base.db_execute_query(table_config) # self.Base.db_execute_query(table_config)
# self.Base.db_execute_query(table_trusted) # self.Base.db_execute_query(table_trusted)
return None return None
@@ -255,7 +240,7 @@ class Defender():
exec_query = self.Base.db_execute_query(query, {"user": nickname}) exec_query = self.Base.db_execute_query(query, {"user": nickname})
response = exec_query.fetchone() response = exec_query.fetchone()
if not response is None: if response is not None:
q_insert = "INSERT INTO def_trusted (datetime, user, host, vhost) VALUES (?, ?, ?, ?)" q_insert = "INSERT INTO def_trusted (datetime, user, host, vhost) VALUES (?, ?, ?, ?)"
mes_donnees = {'datetime': self.Base.get_datetime(), 'user': nickname, 'host': '*', 'vhost': '*'} mes_donnees = {'datetime': self.Base.get_datetime(), 'user': nickname, 'host': '*', 'vhost': '*'}
exec_query = self.Base.db_execute_query(q_insert, mes_donnees) exec_query = self.Base.db_execute_query(q_insert, mes_donnees)
@@ -301,7 +286,8 @@ class Defender():
# Convertir la date enregistrée dans UID_DB en un objet {datetime} # Convertir la date enregistrée dans UID_DB en un objet {datetime}
connected_time_string = get_user.connexion_datetime connected_time_string = get_user.connexion_datetime
if type(connected_time_string) == datetime:
if isinstance(connected_time_string, datetime):
connected_time = connected_time_string connected_time = connected_time_string
else: else:
connected_time = datetime.strptime(connected_time_string, "%Y-%m-%d %H:%M:%S.%f") connected_time = datetime.strptime(connected_time_string, "%Y-%m-%d %H:%M:%S.%f")
@@ -386,7 +372,6 @@ class Defender():
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
dchanlog = self.Config.SERVICE_CHANLOG dchanlog = self.Config.SERVICE_CHANLOG
color_red = self.Config.COLORS.red color_red = self.Config.COLORS.red
color_black = self.Config.COLORS.black
nogc = self.Config.COLORS.nogc nogc = self.Config.COLORS.nogc
salon_jail = self.Config.SALON_JAIL salon_jail = self.Config.SALON_JAIL
@@ -480,7 +465,7 @@ class Defender():
unixtime = self.Base.get_unixtime() unixtime = self.Base.get_unixtime()
get_diff_secondes = 0 get_diff_secondes = 0
if not get_detected_uid in self.flood_system: if get_detected_uid not in self.flood_system:
self.flood_system[get_detected_uid] = { self.flood_system[get_detected_uid] = {
'nbr_msg': 0, 'nbr_msg': 0,
'first_msg_time': unixtime 'first_msg_time': unixtime
@@ -694,7 +679,7 @@ class Defender():
# Formatted output # Formatted output
decodedResponse = json.loads(response.text) decodedResponse = json.loads(response.text)
if not 'data' in decodedResponse: if 'data' not in decodedResponse:
return None return None
result = { result = {
@@ -707,7 +692,6 @@ class Defender():
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
service_chanlog = self.Config.SERVICE_CHANLOG service_chanlog = self.Config.SERVICE_CHANLOG
color_red = self.Config.COLORS.red color_red = self.Config.COLORS.red
color_black = self.Config.COLORS.black
nogc = self.Config.COLORS.nogc nogc = self.Config.COLORS.nogc
# pseudo!ident@host # pseudo!ident@host
@@ -780,7 +764,6 @@ class Defender():
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
service_chanlog = self.Config.SERVICE_CHANLOG service_chanlog = self.Config.SERVICE_CHANLOG
color_red = self.Config.COLORS.red color_red = self.Config.COLORS.red
color_black = self.Config.COLORS.black
nogc = self.Config.COLORS.nogc nogc = self.Config.COLORS.nogc
url = f'https://freeipapi.com/api/json/{remote_ip}' url = f'https://freeipapi.com/api/json/{remote_ip}'
@@ -797,7 +780,7 @@ class Defender():
status_code = response.status_code status_code = response.status_code
if status_code == 429: if status_code == 429:
self.Logs.warning(f'Too Many Requests - The rate limit for the API has been exceeded.') self.Logs.warning('Too Many Requests - The rate limit for the API has been exceeded.')
return None return None
elif status_code != 200: elif status_code != 200:
self.Logs.warning(f'status code = {str(status_code)}') self.Logs.warning(f'status code = {str(status_code)}')
@@ -873,10 +856,9 @@ class Defender():
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
service_chanlog = self.Config.SERVICE_CHANLOG service_chanlog = self.Config.SERVICE_CHANLOG
color_red = self.Config.COLORS.red color_red = self.Config.COLORS.red
color_black = self.Config.COLORS.black
nogc = self.Config.COLORS.nogc nogc = self.Config.COLORS.nogc
url = f"https://developers18334.cloudfilt.com/" url = "https://developers18334.cloudfilt.com/"
data = { data = {
'ip': remote_ip, 'ip': remote_ip,
@@ -941,7 +923,7 @@ class Defender():
def thread_autolimit(self) -> None: def thread_autolimit(self) -> None:
if self.ModConfig.autolimit == 0: if self.ModConfig.autolimit == 0:
self.Logs.debug(f"autolimit deactivated ... canceling the thread") self.Logs.debug("autolimit deactivated ... canceling the thread")
return None return None
while self.Irc.autolimit_started: while self.Irc.autolimit_started:
@@ -958,7 +940,7 @@ class Defender():
while self.autolimit_isRunning: while self.autolimit_isRunning:
if self.ModConfig.autolimit == 0: if self.ModConfig.autolimit == 0:
self.Logs.debug(f"autolimit deactivated ... stopping the current thread") self.Logs.debug("autolimit deactivated ... stopping the current thread")
break break
for chan in self.Channel.UID_CHANNEL_DB: for chan in self.Channel.UID_CHANNEL_DB:
@@ -967,14 +949,14 @@ class Defender():
self.Protocol.send2socket(f":{self.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + self.ModConfig.autolimit_amount}") self.Protocol.send2socket(f":{self.Config.SERVICE_ID} MODE {chan.name} +l {len(chan.uids) + self.ModConfig.autolimit_amount}")
chan_copy["uids_count"] = len(chan.uids) chan_copy["uids_count"] = len(chan.uids)
if not chan.name in chan_list: if chan.name not in chan_list:
chan_list.append(chan.name) chan_list.append(chan.name)
chanObj_copy.append({"name": chan.name, "uids_count": 0}) chanObj_copy.append({"name": chan.name, "uids_count": 0})
# Verifier si un salon a été vidé # Verifier si un salon a été vidé
current_chan_in_list = [d.name for d in self.Channel.UID_CHANNEL_DB] current_chan_in_list = [d.name for d in self.Channel.UID_CHANNEL_DB]
for c in chan_list: for c in chan_list:
if not c in current_chan_in_list: if c not in current_chan_in_list:
chan_list.remove(c) chan_list.remove(c)
# Si c'est la premiere execution # Si c'est la premiere execution
@@ -1008,7 +990,7 @@ class Defender():
match cmd[1]: match cmd[1]:
case 'REPUTATION': case 'REPUTATION':
# :001 REPUTATION 91.168.141.239 118 # :001 REPUTATION 8.8.8.8 118
try: try:
self.reputation_first_connexion['ip'] = cmd[2] self.reputation_first_connexion['ip'] = cmd[2]
self.reputation_first_connexion['score'] = cmd[3] self.reputation_first_connexion['score'] = cmd[3]
@@ -1059,12 +1041,12 @@ class Defender():
_User = self.User.get_User(str(cmd[7])) _User = self.User.get_User(str(cmd[7]))
# If user is not service or IrcOp then scan them # If user is not service or IrcOp then scan them
if not re.match(fr'^.*[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 not _User.remote_ip 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
self.freeipapi_UserModel.append(_User) if self.ModConfig.freeipapi_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None self.freeipapi_UserModel.append(_User) if self.ModConfig.freeipapi_scan == 1 and _User.remote_ip not in self.Config.WHITELISTED_IP else None
self.cloudfilt_UserModel.append(_User) if self.ModConfig.cloudfilt_scan == 1 and not _User.remote_ip in self.Config.WHITELISTED_IP else None self.cloudfilt_UserModel.append(_User) if self.ModConfig.cloudfilt_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 not _User.remote_ip 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 not _User.remote_ip 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: if _User is None:
self.Logs.critical(f'This UID: [{cmd[7]}] is not available please check why') self.Logs.critical(f'This UID: [{cmd[7]}] is not available please check why')
@@ -1075,9 +1057,9 @@ class Defender():
if self.Config.DEFENDER_INIT == 0: if self.Config.DEFENDER_INIT == 0:
# Si le user n'es pas un service ni un IrcOP # Si le user n'es pas un service ni un IrcOP
if not re.match(fr'^.*[S|o?].*$', _User.umodes): if not re.match(r'^.*[S|o?].*$', _User.umodes):
if reputation_flag == 1 and _User.score_connexion <= reputation_seuil: if reputation_flag == 1 and _User.score_connexion <= reputation_seuil:
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.__dict__,
@@ -1107,7 +1089,7 @@ class Defender():
self.Protocol.send2socket(f":{service_id} MODE {parsed_chan} +b ~security-group:unknown-users") self.Protocol.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") self.Protocol.send2socket(f":{service_id} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
if not get_reputation is None: if get_reputation is not None:
isWebirc = get_reputation.isWebirc isWebirc = get_reputation.isWebirc
if not isWebirc: if not isWebirc:
@@ -1187,7 +1169,7 @@ class Defender():
get_user_reputation = self.Reputation.get_Reputation(final_UID) get_user_reputation = self.Reputation.get_Reputation(final_UID)
if not get_user_reputation is 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:
@@ -1201,7 +1183,7 @@ class Defender():
except Exception as err: except Exception as err:
self.Logs.error(f"General Error: {err}") self.Logs.error(f"General Error: {err}")
def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: def hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None:
command = str(cmd[0]).lower() command = str(cmd[0]).lower()
fromuser = user fromuser = user
@@ -1231,12 +1213,12 @@ class Defender():
case 'show_reputation': case 'show_reputation':
if not self.Reputation.UID_REPUTATION_DB: if not self.Reputation.UID_REPUTATION_DB:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=" No one is suspected") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="No one is suspected")
for suspect in self.Reputation.UID_REPUTATION_DB: for suspect in self.Reputation.UID_REPUTATION_DB:
self.Protocol.send_notice(nick_from=dnickname, self.Protocol.send_notice(nick_from=dnickname,
nick_to=fromuser, nick_to=fromuser,
msg=f" Uid: {suspect.uid} | Nickname: {suspect.nickname} | Reputation: {suspect.score_connexion} | Secret code: {suspect.secret_code} | Connected on: {suspect.connected_datetime}") msg=f" Uid: {suspect.uid} | Nickname: {suspect.nickname} | Reputation: {suspect.score_connexion} | Secret code: {suspect.secret_code} | Connected on: {suspect.connexion_datetime}")
case 'code': case 'code':
try: try:
@@ -1522,7 +1504,7 @@ class Defender():
except ValueError as ve: except ValueError as ve:
self.Logs.warning(f'{ve}') self.Logs.warning(f'{ve}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" La valeur devrait etre un entier >= 0") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=" La valeur devrait etre un entier >= 0")
case 'proxy_scan': case 'proxy_scan':
@@ -1729,14 +1711,14 @@ class Defender():
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_after_release ==> {self.ModConfig.reputation_score_after_release}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_after_release ==> {self.ModConfig.reputation_score_after_release}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_ban_all_chan ==> {self.ModConfig.reputation_ban_all_chan}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_ban_all_chan ==> {self.ModConfig.reputation_ban_all_chan}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_timer ==> {self.ModConfig.reputation_timer}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' reputation_timer ==> {self.ModConfig.reputation_timer}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [Proxy_scan]') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=' [Proxy_scan]')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.local_scan == 1 else color_red}local_scan{nogc} ==> {self.ModConfig.local_scan}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.local_scan == 1 else color_red}local_scan{nogc} ==> {self.ModConfig.local_scan}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.psutil_scan == 1 else color_red}psutil_scan{nogc} ==> {self.ModConfig.psutil_scan}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.psutil_scan == 1 else color_red}psutil_scan{nogc} ==> {self.ModConfig.psutil_scan}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.abuseipdb_scan == 1 else color_red}abuseipdb_scan{nogc} ==> {self.ModConfig.abuseipdb_scan}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.abuseipdb_scan == 1 else color_red}abuseipdb_scan{nogc} ==> {self.ModConfig.abuseipdb_scan}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.freeipapi_scan == 1 else color_red}freeipapi_scan{nogc} ==> {self.ModConfig.freeipapi_scan}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.freeipapi_scan == 1 else color_red}freeipapi_scan{nogc} ==> {self.ModConfig.freeipapi_scan}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.cloudfilt_scan == 1 else color_red}cloudfilt_scan{nogc} ==> {self.ModConfig.cloudfilt_scan}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' {color_green if self.ModConfig.cloudfilt_scan == 1 else color_red}cloudfilt_scan{nogc} ==> {self.ModConfig.cloudfilt_scan}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.ModConfig.flood == 1 else color_red}Flood{nogc}] ==> {self.ModConfig.flood}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' [{color_green if self.ModConfig.flood == 1 else color_red}Flood{nogc}] ==> {self.ModConfig.flood}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_action ==> Coming soon') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=' flood_action ==> Coming soon')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_message ==> {self.ModConfig.flood_message}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_message ==> {self.ModConfig.flood_message}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_time ==> {self.ModConfig.flood_time}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_time ==> {self.ModConfig.flood_time}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_timer ==> {self.ModConfig.flood_timer}') self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f' flood_timer ==> {self.ModConfig.flood_timer}')
@@ -1748,7 +1730,7 @@ class Defender():
nickoruid = cmd[1] nickoruid = cmd[1]
UserObject = self.User.get_User(nickoruid) UserObject = self.User.get_User(nickoruid)
if not UserObject is None: if UserObject is not None:
channels: list = [] channels: list = []
for chan in self.Channel.UID_CHANNEL_DB: for chan in self.Channel.UID_CHANNEL_DB:
for uid_in_chan in chan.uids: for uid_in_chan in chan.uids:
@@ -1784,10 +1766,10 @@ class Defender():
if activation == 'on': if activation == 'on':
for chan in self.Channel.UID_CHANNEL_DB: for chan in self.Channel.UID_CHANNEL_DB:
if not chan.name 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)
if activation == 'off': if activation == 'off':
for chan in self.Channel.UID_CHANNEL_DB: for chan in self.Channel.UID_CHANNEL_DB:
if not chan.name in channel_to_dont_quit: if chan.name not in channel_to_dont_quit:
self.Protocol.part(uidornickname=dnickname, channel=chan.name) self.Protocol.part(uidornickname=dnickname, channel=chan.name)
self.join_saved_channels() self.join_saved_channels()

View File

@@ -57,6 +57,7 @@ class Jsonrpc():
# Insert module commands into the core one (Mandatory) # Insert module commands into the core one (Mandatory)
self.__set_commands(self.commands_level) self.__set_commands(self.commands_level)
logging.getLogger('websockets').setLevel(logging.WARNING) logging.getLogger('websockets').setLevel(logging.WARNING)
logging.getLogger('unrealircd-rpc-py').setLevel(logging.CRITICAL)
# Create you own tables (Mandatory) # Create you own tables (Mandatory)
# self.__create_tables() # self.__create_tables()
@@ -65,13 +66,6 @@ class Jsonrpc():
self.__load_module_configuration() self.__load_module_configuration()
# End of mandatory methods you can start your customization # # End of mandatory methods you can start your customization #
# self.UnrealIrcdRpcLive: Live = Live(
# req_method='unixsocket',
# path_to_socket_file=self.Config.JSONRPC_PATH_TO_SOCKET_FILE,
# callback_object_instance=self,
# callback_method_name='callback_sent_to_irc'
# )
self.UnrealIrcdRpcLive: Live = Live( self.UnrealIrcdRpcLive: Live = Live(
req_method='websocket', req_method='websocket',
url=self.Config.JSONRPC_URL, url=self.Config.JSONRPC_URL,
@@ -214,7 +208,7 @@ class Jsonrpc():
return None return None
def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: def hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None:
command = str(cmd[0]).lower() command = str(cmd[0]).lower()
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.Config.SERVICE_NICKNAME
@@ -235,6 +229,11 @@ class Jsonrpc():
match option: match option:
case 'on': case 'on':
# for logger_name, logger in logging.root.manager.loggerDict.items():
# if isinstance(logger, logging.Logger):
# self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"{logger_name} - {logger.level}")
for thread in self.Base.running_threads: for thread in self.Base.running_threads:
if thread.getName() == 'thread_start_jsonrpc': if thread.getName() == 'thread_start_jsonrpc':
if thread.is_alive(): if thread.is_alive():

View File

@@ -147,7 +147,7 @@ class Test():
except Exception as err: except Exception as err:
self.Logs.error(f"General Error: {err}") self.Logs.error(f"General Error: {err}")
def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: def hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None:
command = str(cmd[0]).lower() command = str(cmd[0]).lower()
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.Config.SERVICE_NICKNAME

View File

@@ -274,7 +274,7 @@ class Votekick():
except Exception as err: except Exception as err:
self.Logs.error(f"General Error: {err}") self.Logs.error(f"General Error: {err}")
def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: def hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None:
# cmd is the command starting from the user command # cmd is the command starting from the user command
# full cmd is sending the entire server response # full cmd is sending the entire server response

View File

@@ -1,9 +1,9 @@
{ {
"version": "6.0.0", "version": "6.0.3",
"requests": "2.32.3", "requests": "2.32.3",
"psutil": "6.0.0", "psutil": "6.0.0",
"unrealircd_rpc_py": "1.0.6", "unrealircd_rpc_py": "1.0.7",
"sqlalchemy": "2.0.35", "sqlalchemy": "2.0.35",
"faker": "30.1.0" "faker": "30.1.0"
} }