Robot de sécurité OPER iRC

A compléter, robot IRC de sécurité (loin, loin d'etre terminé)

#!/usr/bin/eval PYTHONPATH=/home/mon_compte/modules python
import socket, sys, threading,time

class timerListe(threading.Thread):
    def __init__(self,time,liste,nick):
        self.time = time
        self.liste = liste
        self.nick = nick
        threading.Thread.__init__(self)
    def run(self):
        self.liste.append(self.nick)
        time.sleep(self.time)
        print "nick ajouté !"
        print str(self.liste)
        if self.nick in self.liste:
            self.liste.remove(self.nick)
        return self.liste
    
class Bot:
    def __init__(self, name, ip, port):
        self.s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.ip = ip
        self.port = int(port)
        self.name = name
    #-------------------------------------------------------------
    # variable gérant la reception de listes                     |    
    #-------------------------------------------------------------
        self.rcvlist = 0
        self.liste = [] # + = voice ; % = halfop ; @ = op ; & = protect ; ~ = owner
        self.whouah = [' ',' ']
        self.listeCanal = []
    #------------------------------------------------------------
    # variables de sécurité
    #------------------------------------------------------------
        self.listeJoin = []
        self.blacklist = []
        self.banlist = []
        self.listeAdmin = ['iZy_TeH_PariaH']
        self.listeProtect = []
        self.listeOp = []
        self.listeHOp = []
#-------------------------------------------------------------
# Gestion de connection au serveur
#         - fonction connection se connecte au serveur
#        - fonction recv reçoit les données octet/octet
#                reception_liste stocke une liste dans la
#                                variable self.liste
#         - fonction on_ping maintient la connection
#-------------------------------------------------------------
    def connection (self):
        """ établit la conection au serveur """
        try:
            self.s.connect((self.ip,self.port))
        except:
            print "erreur de connection"
            exit(0)
        print "connecte au serveur"
        self.s.send("NICK :"+ self.name +"\r\n")
        self.s.send("USER iBotnet localhost irc_server :18 F izy<3\r\n")
        
    def recv(self):
        """ reçoit les données octet par octet"""
        msg = ""
        while 1:
            msg = msg + self.s.recv(1)
            if "\r\n" in msg:
                break
        if self.rcvlist == 1:
            self.reception_liste(msg)
        return msg
        
    def reception_liste(self,msg):
        """ reçoit les données de type liste """
        self.rcvlist = 0
        self.liste = []
        msg = msg.split(":")
        msg = msg[2].split(" ")
        self.liste = msg[:-1]
        
    def on_ping(self,ping):
        """ Traite les données de type ping """
        self.s.send("PONG " + ping + "\r\n")    
#-------------------------------------------------------------
# Gestion des evenements
#     - fonction on_notice traite les notices reçues
#     - fonction on_msg redirige les PRIVMSG reçus vers:
#            - on_pubmsg si le destinataire n'est pas le bot
#            - on_privmsg si le destinataire est le bot
#    - fonction on_join redirige les JOIN vers:
#            - on_self_join si celui qui rejoint est le BOT
#            - on_new_join si celui qui rejoint est un autre
#    - fonction on_names
#    - fonction on_who
#-------------------------------------------------------------
    def on_notice(self,msg):
        """ Traites les données de type NOTICE """
        userathost = msg[0]
        target = msg[2]
        message = msg[3:]
        nick = userathost.split("!")[0]
        nick = nick[1:]
        user = " "
        host = " "
        if len(userathost.split("!")) > 1:
            uah = userathost.split("!")[1]
            user = uah.split("@")[0]
            host = uah.split("@")[1]
    #début des evenements de type NOTICE
        if message[0].lower() == ":join" and nick not in self.blacklist:
            if len(message) < 2:
                self.notice(nick,"Syntaxe : join #canal")
            else:
                self.join(message[1])
    #####################################################################
    #    RUBRIQUE MESSAGE
    #####################################################################
    def on_msg(self,msg):
        """ Traite les données de type PRIVMSG """
        userathost = msg[0]
        target = msg[2]
        message = msg[3:]
        nick = userathost.split("!")[0]
        nick = nick[1:]
        user = " "
        host = " "
        if len(userathost.split("!")) > 1:
            uah = userathost.split("!")[1]
            user = uah.split("@")[0]
            host = uah.split("@")[1]
        if target != self.name:
            self.on_pubmsg(nick,user,host,target,message)
        else:
            self.on_privmsg(nick,user,host,message)
            
    def on_pubmsg(self,auteur,user,host,canal,message):
        """ Traite les données de types Message PUBLIC [sur un canal] """
        if message[0].lower() == ":<k" and message[0].lower() != ":<kb" :
            if len(message) < 2:
                self.notice(auteur,"syntaxe : <k pseudo raison")
            if len(message) == 2:
                self.kick(canal,message[1])
            if len(message) > 2:
                raison = ""
                for mot in message[2:]:
                    raison = raison + " " + mot
                self.kick(canal,message[1],raison + " [Kicked by " + auteur + "]")
        if message[0].lower() == ":<b":
            if len(message) < 2:
                self.notice(auteur,"syntaxe : <b pseudo raison")
            if len(message) >= 2:
                self.ban_h(canal,message[1])
        if message[0].lower() == ":<kb":
            if len(message) < 2:
                self.notice(auteur,"syntaxe : <kb pseudo raison")
            if len(message) == 2:
                self.ban_h(canal,message[1])
                self.kick(canal,message[1])
            if len(message) > 2:
                raison = ""
                for mot in message[2:]:
                    raison = raison + " " + mot
                self.ban_h(canal,message[1])
                self.kick(canal,message[1],raison + " [Kicked/Banned by " + auteur + "]")
        if message[0].lower() == ":<m":
            if len(message) < 2:
                self.notice(auteur,"syntaxe : <m mode (pseudo)")
            if len(message) == 2:
                self.set_mode(canal,message[1])
            if len(message) > 2:
                self.set_mode(canal,message[1],message[2])
        if message[0].lower() == ":<topic":
            if len(message) < 2:
                self.notice(auteur,"syntaxe : <topic nouveau_sujet")
            else:
                topic = ""
                for mot in message[1:]:
                    topic = topic + " " + mot
                self.set_topic(canal,topic)
        if message[0].lower() == ":<actulistes":
            self.names(canal)
            for nom in self.liste:
                if nom[0] == "~":
                    self.listeAdmin.append(nom[1:])
                if nom[0] == "&":
                    self.listeProtect.append(nom[1:])
                if nom[0] == "@":
                    self.listeOp.append(nom[1:])
                if nom[0] == "%":
                    self.listeHOp.append(nom[1:])
            self.msg(canal,"Listes actualisées")
        if message[0].lower() == ":<listes":
            self.msg(canal,"Liste des users ::: " + str(self.liste))
            self.msg(canal,"Liste des admins ::: " + str(self.listeAdmin))
            self.msg(canal,"Liste des protects ::: " + str(self.listeProtect))
            self.msg(canal,"Liste des OP ::: " + str(self.listeOp))
            self.msg(canal,"Liste des HalfOP ::: " + str(self.listeHOp))
        if message[0].lower() == ":<who" and len(message) > 1:
            self.who(message[1])
        if message[0].lower() == ":<reboot":
            self.reboot()
            
    def on_privmsg(self,auteur,user,host,message):
        """ Traite les données de type message Privé """
        if message[0].lower() == ":invite":
            if len(message) < 2:
                self.msg(auteur,"Syntaxe : invite #canal")
            else:
                self.invite(auteur, message[1])
    
    #####################################################################
    #            RUBRIQUE JOIN
    #####################################################################
    def on_join(self,msg):    
        """ Traite les données de type JOIN"""
        userathost = msg[0]
        target = msg[2][1:]
        message = msg[3:]
        nick = userathost.split("!")[0]
        nick = nick[1:]
        user = " "
        host = " "
        if len(userathost.split("!")) > 1:
            uah = userathost.split("!")[1]
            user = uah.split("@")[0]
            host = uah.split("@")[1]
        if nick == self.name:
            self.on_self_join(target)
        else:
            self.on_new_join(nick,user,host,target)
            
    def on_self_join(self,canal):
        """ Traite le cas où le BOT rejoint le salon """
        self.listeCanal.append(canal)
    def on_new_join(self,nick,user,host,canal):
        """ Traite le cas où une nouvelle personne rejoint le salon """
    ######################################################################
    #            RUBRIQUE NICK
    ######################################################################
    def on_nick(self,msg):
        """ Traite les données de type NICK """
        userathost = msg[0]
        target = msg[2][1:]
        message = msg[3:]
        nick = userathost.split("!")[0]
        nick = nick[1:]
        user = " "
        host = " "
        if len(userathost.split("!")) > 1:
            uah = userathost.split("!")[1]
            user = uah.split("@")[0]
            host = uah.split("@")[1]
        ancien_nick = nick
        nouveau_nick = target
        if ancien_nick in self.listeAdmin:
            self.listeAdmin.remove(ancien_nick)
            self.listeAdmin.append(nouveau_nick)
        if ancien_nick in self.listeProtect:
            self.listeProtect.remove(ancien_nick)
            self.listeProtect.append(nouveau_nick)
        if ancien_nick in self.listeOp:
            self.listeOp.remove(ancien_nick)
            self.listeOp.append(nouveau_nick)
        if ancien_nick in self.listeHOp:
            self.listeHOp.remove(ancien_nick)
            self.listeHOp.append(nouveau_nick)
    ######################################################################
    #            RUBRIQUE WHO
    ######################################################################
    def on_who(self,msg):
        """ Traite les réponses de type WHO """
        self.whouah = []
        i = 0 #represente le nombre de canaux surlequel est le nick
        for mot in msg:
            if "#" in mot:
                i = i + 1
        if len(msg) >= 4 + i:
            self.whouah.append( msg[3 + i] )
            self.whouah.append( msg[4 + i] )
#-------------------------------------------------------------
# Fonction RUN :: constitue le developpement du robot et
#                   l'assignement des taches aux fonctions
#                  chargées de traiter les données
#-------------------------------------------------------------
        
    def run(self):
        """ Demarre le bot """
        self.connection()
        while 1:
            msg = self.recv()
            msg = msg[:-2]
            print msg
            a = msg.split(" ")
            type = a[1]
            if a[0] == "PING":
                self.on_ping(a[1])
            if type == "NOTICE":
                self.on_notice(a)
            if type == "PRIVMSG":
                self.on_msg(a)
            if type == "JOIN":
                self.on_join(a)
            if type == "NICK":
                self.on_nick(a)
            if type == "352": #réponse WHO
                self.on_who(a)
#-------------------------------------------------------------
# Gestion des Actions:
#    fonction join : le bot rejoint le salon
#    fonction notice : le bot envoie une notice
#     fonction kick : le bot kick un utilisateur
#    fonction ban/deban : le bot ban/deban la cible
#        fonction nick_ban / nick_deban : ban/deban le host de la cible a partir du nick
#    fonction set_mode : le bot affecte un mode à la cible
#    fonction msg : le bot envoie le message à la cible
#    fonction part : le bot part du salon
#    fonction set_topic : le bot fixe le topic
#    fonction names : le bot envoie une requête NAMES
#    fonction invite : le bot envoie une requête INVITE
#    fonction renames : renomme le robot
#    fonction n_h : retourne le host a partir du nick
#
#     fonction reboot : Redemare le bot sur le même serveur
#-------------------------------------------------------------
    def join(self,canal):
        """ Ordre de joindre un canal """
        self.s.send("JOIN " + canal + "\r\n")
    def notice(self,target,message):
        """ Ordre d'emettre une notice """
        self.s.send("NOTICE " + target + " :" + message + "\r\n")
    def kick(self,canal, target,raison = " Kicked "):
        """ Ordre de Kick """
        self.s.send("KICK " + canal + " " + target + " :" + raison + " \r\n")
    def ban(self,canal,target):
        """ Ordre de bannir """
        self.banlist.append(target)
        self.set_mode(canal,"+b",target)
    def ban_h(self,canal,nick):
        """ Ordre de bannir le host"""
        self.banlist.append(nick)
        host = self.n_h(nick)
        self.set_mode(canal,"+b","*!*@" + host + "\r\n")
    def deban(self,canal,target):
        """ Ordre de débannir """
        if target in self.banlist:
            self.banlist.remove(target)
        self.set_mode(canal,"-b",target)
    def deban_h(self,canal,nick):
        """ Ordre de bannir le nick """
        self.banlist.append(nick)
        host = self.n_h(nick)
        self.set_mode(canal,"-b","*!*@" + host + "\r\n")
    def set_mode(self,target,mode,p = 'NULL'):
        """ Ordre d'etablissement du mode """
        if p != 'NULL':
            self.s.send("MODE " + target + " " + mode + " :" + p + "\r\n")    
        else:
            self.s.send("MODE " + target + " " + mode + "\r\n")
    def msg(self,target,msg):
        """ Envoie le message à la cible (Salon ou Personne) """
        self.s.send("PRIVMSG " + target + " :" + msg + "\r\n")
    def part(self,canal,msg = "Admin Request"):
        """ Le robot part du salon """
        self.s.send("PART " + canal + " :" + msg +"\r\n")
    def set_topic(self,target,topic):
        """ Le robot change le sujet du salon """
        self.s.send("TOPIC " + target + " :" + topic + "\r\n")
    def names(self,target):
        """ Execute une requête de type NAMES """
        self.rcvlist = 1
        self.s.send("NAMES " + target + "\r\n")
    def invite(self,auteur,canal):
        """ Execute une requête de type INVITE """
        self.s.send("INVITE " + auteur + " " + canal + "\r\n")
    def renames(self,nouveau_nick):
        """  Execute une requête de type NICK """
        self.s.send("NICK " + nouveau_nick + "\r\n")
    def n_h(self,nick):
        self.who(nick)
        msgR = self.recv()
        msg = msgR.split(" ")
        self.on_who(msg)
        if len(self.whouah) == 2:
            return self.whouah[1]
        else:
            return 'ERREUR'
    def n_u(self,nick):
        self.who(nick)
        msgR = self.recv()
        msg = msgR.split(" ")
        self.on_who(msg)
        if len(self.whouah) == 2:
            return self.whouah[0]
        else:
            return 'ERREUR'
    def who(self,nick):
        self.s.send("WHO " + nick + "\r\n")
    def reboot(self):    
        """ Reboot le rebot """
        self.s.send("QUIT :Rebooting System [Admin request]\r\n")
        self.s.close()
        self.__init__(self.name,self.ip,self.port)
        self.run()
#-------------------------------------------------------------
#    Gestion de la sécurité du robot
#        fonction antiflood_user : protege le robot contre une attaque
#                                   flood commandes user
#        fonction antiflood_clone : protege contre une attaque flood clone
#        fonction anti-massJoin : protege le salon contre les
#                                 attaques de clones
#        fonction anti-usurpation d'accès:
#                            tous les opérateurs sont sur la liste
#                            des op/hop/protect/+q?. Si l'un d'entre
#                            eux n'est pas dans la liste, il est
#                            automatiquement destitué
#-------------------------------------------------------------
            

if __name__ == '__main__':
    #if len(sys.argv) < 3:
    #    print "Syntaxe : /botnet.py ip port"
    #    exit(0)
    NICK = "Botnet"
    #ip = sys.argv[1]
    #port = sys.argv[2]
    #connection(ip,port,sock,NICK)
    i = Bot(NICK,"irc.discut.fr",6667)
    i.run()


Pour être informé des derniers articles, inscrivez vous :