def start (self, addr, retries=5): """Start the web server listening on addr in a new coroutine. Try up to retries time to bind to that address. Raises an exception if the bind fails.""" server_s = self._make_socket() done = 0 save_errno = 0 self.addr = addr while not done: for x in xrange (retries): try: was_eaddrinuse = 0 server_s.bind (addr) except OSError, why: if why.errno not in (errno.EADDRNOTAVAIL, errno.EADDRINUSE): raise else: save_errno = 0 if why.errno == errno.EADDRINUSE: was_eaddrinuse = 1 else: done = 1 break coro.sleep_relative(1) # ... and retry else: coro.print_stderr ("cannot bind to %s:%d after 5 attempts, errno = %d\n" % (addr[0], addr[1], save_errno)) if was_eaddrinuse: qlog.write('WEBUI.PORT_IN_USE', addr[0], str(addr[1])) coro.sleep_relative(15)
def P(x): """Uses coro.print_stderr in a coro environment, else plain print.""" if GOT_CORO and coro.coro_is_running(): coro.print_stderr("%s\n" % x) else: print x
def start(self, addr, retries=5): """Start the web server listening on addr in a new coroutine. Try up to retries time to bind to that address. Raises an exception if the bind fails.""" server_s = self._make_socket() done = 0 save_errno = 0 self.addr = addr while not done: for x in xrange(retries): try: was_eaddrinuse = 0 server_s.bind(addr) except OSError, why: if why.errno not in (errno.EADDRNOTAVAIL, errno.EADDRINUSE): raise else: save_errno = 0 if why.errno == errno.EADDRINUSE: was_eaddrinuse = 1 else: done = 1 break coro.sleep_relative(1) # ... and retry else: coro.print_stderr( "cannot bind to %s:%d after 5 attempts, errno = %d\n" % (addr[0], addr[1], save_errno)) if was_eaddrinuse: qlog.write('WEBUI.PORT_IN_USE', addr[0], str(addr[1])) coro.sleep_relative(15)
def serve (port=None, ip='', unix_path=None, welcome_message=None, global_dict=None, client_class=None): """Backdoor server function. This function will listen on the backdoor socket and spawn new threads for each connection. :Parameters: - `port`: The IPv4 port to listen on (defaults to automatically choose an unused port between 8023->8033). May also be a list of ports. - `ip`: The IP to listen on. Defaults to all IP's. - `unix_path`: The unix path to listen on. If this is specified, then it will use unix-domain sockets, otherwise it will use IPv4 sockets. - `welcome_message`: A welcome message to display when a user logs in. - `global_dict`: The global dictionary to use for client sessions. """ import errno if unix_path: try: os.remove (unix_path) except OSError, why: if why[0] == errno.ENOENT: pass else: raise s = coro.make_socket (coro.PF.LOCAL, coro.SOCK.STREAM) s.bind (unix_path) coro.print_stderr('Backdoor started on unix socket %s\n' % unix_path)
def go (self): b = backdoor (self, line_separator='\n') # this is to avoid getting the banner/copyright/etc mixed in with ssh client pty/x11 warnings coro.sleep_relative (0.1) b.read_eval_print_loop() self.close() coro.print_stderr ('closed ssh backdoor from: %r\n' % (self.transport.transport.peer,))
def serve(port=None, ip='', unix_path=None, welcome_message=None, global_dict=None, client_class=None): """Backdoor server function. This function will listen on the backdoor socket and spawn new threads for each connection. :Parameters: - `port`: The IPv4 port to listen on (defaults to automatically choose an unused port between 8023->8033). May also be a list of ports. - `ip`: The IP to listen on. Defaults to all IP's. - `unix_path`: The unix path to listen on. If this is specified, then it will use unix-domain sockets, otherwise it will use IPv4 sockets. - `welcome_message`: A welcome message to display when a user logs in. - `global_dict`: The global dictionary to use for client sessions. """ import errno if unix_path: try: os.remove(unix_path) except OSError, why: if why[0] == errno.ENOENT: pass else: raise s = coro.make_socket(coro.PF.LOCAL, coro.SOCK.STREAM) s.bind(unix_path) coro.print_stderr('Backdoor started on unix socket %s\n' % unix_path)
def go(self): b = backdoor(self, line_separator='\n') # this is to avoid getting the banner/copyright/etc mixed in with ssh client pty/x11 warnings coro.sleep_relative(0.1) b.read_eval_print_loop() self.close() coro.print_stderr('closed ssh backdoor from: %r\n' % (self.transport.transport.peer, ))
def test_with_timeout(): try: coro.print_stderr(' Should be a 1 second pause:\n') coro.with_timeout(1, coro.sleep_relative, 5) except coro.TimeoutError: pass else: raise ValueError('Timeout didn\'t happen as expected!')
def test_with_timeout_with_interrupt(): coro.spawn(_test_with_timeout_with_interrupt, coro.current()) try: coro.print_stderr(' Should be no pause:\n') coro.with_timeout(1, coro.sleep_relative, 5) except coro.Interrupted, why: if why != 'foobar': raise ValueError('Interrupt value is not foobar!')
def test_sleep_interrupt(): coro.spawn(_test_sleep_interrupt, coro.current()) # The other thread will interrupt me coro.print_stderr('There should be no pause here:\n') try: coro.sleep_relative(10) except coro.Interrupted, why: if why != 'foobar': raise ValueError('Incorrect interrupt value.')
def _blocker_thread(self): self._blocker_socket = coro.tcp_sock() self._blocker_socket.connect(('127.0.0.1', self.port)) while 1: coro.print_stderr('reading') try: self._blocker_socket.read(1024) except coro.ClosedError: coro.print_stderr('it was closed') return
def do_tests(tests): for x in xrange(5): for func_name in tests: f = globals()[func_name] if isinstance(f, types.FunctionType): if f.func_name.startswith('test_'): coro.print_stderr('Running test %s...\n' % f.func_name) start_ram = mstats.get_malloc_stats()['allocated_bytes'] apply(f, ()) end_ram = mstats.get_malloc_stats()['allocated_bytes'] coro.print_stderr('RAM difference: %s\n' % comma_group(end_ram - start_ram)) coro._exit = 1
def make_data_channel (self): global connect_timeout if self.pasv_mode: reply = self.command ('PASV', '2') ip, port = self.parse_pasv_reply (reply) dc = coro.make_socket (socket.AF_INET, socket.SOCK_STREAM) if self.local_ip: dc.bind((self.local_ip, 0)) if self.debug: coro.print_stderr ('connecting to %s:%s\n' % (ip, port)) coro.with_timeout (connect_timeout, dc.connect, (ip, port)) return dc else: raise ftp_error, "non-pasv transfers not yet implemented"
def thread_manager(self): """thread_manager(self) -> None This is the deadlock detection thread. """ while 1: try: coro.sleep_relative(self.deadlock_check_period) self.check_for_deadlocks() except coro.Interrupted: # Exiting. self.thread = None return except: coro.print_stderr(tb.traceback_string() + '\n')
def test_sleep(): coro.print_stderr(' This pause should be 1 second.\n') coro.sleep_relative(1) coro.print_stderr(' This pause should be 1 second.\n') coro.sleep_relative(1.0) coro.print_stderr(' This pause should be 1 second.\n') coro.sleep_relative(1L * coro.ticks_per_sec) coro.print_stderr(' This pause should be 1 second.\n') coro.sleep_absolute(coro.now + 1L * coro.ticks_per_sec)
def _run (self): """Listens on the FTP port accepting connections and spawning sessions.""" self.thread_id = coro.current().thread_id() s = coro.make_socket (socket.AF_INET, socket.SOCK_STREAM) try: s.set_reuse_addr() done = 0 while not done: for x in xrange (5): try: was_eaddrinuse = 0 s.bind ((self.ip, self.port)) except OSError, why: if why[0] == errno.EACCES: coro.print_stderr( 'Access denied binding to %s:%i. Are you running as root?\n' % (self.ip, self.port)) return elif why[0] == errno.EADDRINUSE: was_eaddrinuse = 1 elif why[0] != errno.EADDRNOTAVAIL: raise else: done = 1 break coro.sleep_relative (1) else: coro.print_stderr ("cannot bind to %s:%d after 5 attempts\n" % (self.ip, self.port)) if was_eaddrinuse: qlog.write('FTPD.PORT_IN_USE', self.ip, str(self.port)) coro.sleep_relative (15) s.listen (1024) while 1: conn_list = s.accept_many() for conn, addr in conn_list: qlog.write('FTPD.CONNECTION', self.session_id, addr[0], self.ip) session = self.channel (self, conn, addr, self.session_id) self.session_id += 1 thread = coro.spawn (session.run) thread.set_name ( "%s_%d" % ( session.__class__.__name__, thread.thread_id() ) ) self.clients.append(session)
def serve (port=None, ip='127.0.0.1', unix_path=None, welcome_message=None, global_dict=None): import errno if unix_path: try: os.remove(unix_path) except OSError, why: if why[0]==errno.ENOENT: pass else: raise try: s = coro.make_socket (socket.AF_UNIX, socket.SOCK_STREAM) s.bind(unix_path) except OSError: coro.print_stderr('Error starting up backdoor on unix socket %s\n' % unix_path) raise coro.print_stderr('Backdoor started on unix socket %s\n' % unix_path)
def test_interrupt(): # Resume myself. This should work without problems. coro.spawn(_test_interrupt_resume, coro.current()) # Interrupt, this should be latent coro.spawn(_test_interrupt_latent, coro.current()) # Interrupt, this should fail coro.spawn(_test_interrupt_fail, coro.current()) result = coro.yield() coro.print_stderr('resuming with result %r\n' % (result,)) if result != 'yoyo': raise ValueError('Resume with wrong value!') # Go back to sleep to catch the latent interrupt try: result = coro.yield() except coro.Interrupted, why: if why != 'foo': raise ValueError('Wrong why %s' % why)
def test_multiple_sleep_interrupt(): # The first interrupt will work just fine coro.spawn(_test_multiple_sleep_interrupt_ok, coro.current()) # Since it has already been interrupted, you can't interrupt it ever again. # The following threads will fail. This is to be expected. # Someday we need to redesign how interrupts work so that these won't fail. # But that will be very tricky. coro.spawn(_test_multiple_sleep_interrupt_fail, coro.current()) coro.spawn(_test_multiple_sleep_interrupt_fail, coro.current()) coro.spawn(_test_multiple_sleep_interrupt_fail, coro.current()) # The other thread will interrupt me coro.print_stderr(' There should be no pause here:\n') try: coro.sleep_relative(10) except coro.Interrupted, why: if why != 'foobar': raise ValueError('Incorrect interrupt value.')
def _run (self): """Listens on the FTP port accepting connections and spawning sessions.""" self.thread_id = coro.current().thread_id() s = coro.make_socket (socket.AF_INET, socket.SOCK_STREAM) try: s.set_reuse_addr() done = 0 while not done: for x in xrange (5): try: was_eaddrinuse = 0 s.bind ((self.ip, self.port)) except OSError, why: if why[0] == errno.EACCES: coro.print_stderr('Access denied binding to %s:%i. Are you running as root?\n' % (self.ip, self.port)) return elif why[0] == errno.EADDRINUSE: was_eaddrinuse = 1 elif why[0] != errno.EADDRNOTAVAIL: raise else: done = 1 break coro.sleep_relative (1) else: coro.print_stderr ("cannot bind to %s:%d after 5 attempts\n" % (self.ip, self.port)) if was_eaddrinuse: qlog.write('FTPD.PORT_IN_USE', self.ip, str(self.port)) coro.sleep_relative (15) s.listen (1024) while 1: conn_list = s.accept_many() for conn, addr in conn_list: qlog.write('FTPD.CONNECTION', self.session_id, addr[0], self.ip) session = self.channel (self, conn, addr, self.session_id) self.session_id += 1 thread = coro.spawn (session.run) thread.set_name ( "%s_%d" % ( session.__class__.__name__, thread.thread_id() ) ) self.clients.append(session)
def smtp_tls_server_session (conn): oconn = conn conn.send ('200 howdy\r\n') while 1: cmd = conn.recv (1024) coro.print_stderr ('got %r\r\n' % (cmd,)) cmd = cmd.lower() if cmd.startswith ('starttls'): conn.send ('220 ready for tls\r\n') ctx = coro_ssl.ssl_ctx (sslip.SSLV23_SERVER_METHOD) try: sconn = coro_ssl.ssl_sock (ctx) sconn.create (sock=conn) sconn.ssl_accept() conn = sconn except sslip.Error: #conn.send ('454 TLS negotiation failed\r\n') pass elif cmd.startswith ('data'): conn.send ('354 go ahead\r\n') while 1: block = conn.recv (8192) if block.endswith ('\r\n.\r\n'): break conn.send ('250 Ok.\r\n') elif cmd.startswith ('quit'): conn.send ('221 byte\r\n') conn.close() break elif cmd.startswith ('ehlo'): conn.send ( '250-loki.ironport.com\r\n' '250-PIPELINING\r\n' '250-SIZE 10240000\r\n' '250-STARTTLS\r\n' '250 8BITMIME\r\n' ) else: conn.send ('200 ok\r\n')
def smtp_tls_server_session (conn): oconn = conn conn.send ('200 howdy\r\n') while True: cmd = conn.recv (1024) coro.print_stderr ('got %r\r\n' % (cmd,)) cmd = cmd.lower() if cmd.startswith ('starttls'): conn.send ('220 ready for tls\r\n') ctx = coro_ssl.ssl_ctx (sslip.SSLV23_SERVER_METHOD) try: sconn = coro_ssl.ssl_sock (ctx) sconn.create (sock=conn) sconn.ssl_accept() conn = sconn except sslip.Error: # conn.send ('454 TLS negotiation failed\r\n') pass elif cmd.startswith ('data'): conn.send ('354 go ahead\r\n') while True: block = conn.recv (8192) if block.endswith ('\r\n.\r\n'): break conn.send ('250 Ok.\r\n') elif cmd.startswith ('quit'): conn.send ('221 byte\r\n') conn.close() break elif cmd.startswith ('ehlo'): conn.send ( '250-loki.ironport.com\r\n' '250-PIPELINING\r\n' '250-SIZE 10240000\r\n' '250-STARTTLS\r\n' '250 8BITMIME\r\n' ) else: conn.send ('200 ok\r\n')
def test2(): coro.sleep_relative (5) f = ftp_client() coro.print_stderr ("connecting...\n") f.connect ('10.1.1.209') coro.print_stderr ("logging in...\n") f.cmd_user ('ftpguy') f.cmd_pass ('ftpguy') f.cmd_type ('I') coro.print_stderr ("sending file...\n") file = open ('ftp_client.py', 'rb') thunk = (lambda f=file: f.read (8192)) f.cmd_stor ('a_file.txt', thunk) coro.print_stderr ("done.\n") f.cmd_quit()
def smtp_tls_session(host, port='25', fromaddr='*****@*****.**', to='*****@*****.**'): print "smtp tls test client" sock = coro.make_socket(socket.AF_INET, socket.SOCK_STREAM) print "host=%r port=%r" % (host, port) port = string.atoi(port) sock.connect((host, port)) print sock.recv(8192) sock.send('EHLO fang\r\n') print sock.recv(8192) sock.send('STARTTLS\r\n') print sock.recv(8192) ctx = coro_ssl.ssl_ctx(sslip.SSLV2_CLIENT_METHOD) client = coro_ssl.ssl_sock(ctx) client.create(sock=sock) # client.ssl.set_connect_state() try: coro.print_stderr('calling ssl_connect()\n') client.ssl_connect() coro.print_stderr('ssl_connect done()\n') except sslip.Error: coro.print_stderr("TLS negotiation failed\n") coro.print_stderr("hit <return> to attempt fallback\n") client.shutdown() raw_input() else: sock = client print "ssl_connect() finished" sock.send('HELP\r\n') print sock.recv(8192) sock.send('MAIL FROM:<' + fromaddr + '>\r\n') print sock.recv(8192) sock.send('RCPT TO:<' + to + '>\r\n') print sock.recv(8192) sock.send('DATA\r\n') print sock.recv(8192) sock.send( 'From: ' + fromaddr + '\r\nSubject: testing STARTTLS\r\n\r\nHi there. I was encrypted\r\n.\r\n' ) print sock.recv(8192) sock.send('QUIT\r\n') print sock.recv(8192) sock.close() coro._exit = 1
def smtp_tls_session ( host, port='25', fromaddr='*****@*****.**', to='*****@*****.**' ): print "smtp tls test client" sock = coro.make_socket (socket.AF_INET, socket.SOCK_STREAM) print "host=%r port=%r" % (host, port) port = string.atoi(port) sock.connect ((host, port)) print sock.recv (8192) sock.send ('EHLO fang\r\n') print sock.recv (8192) sock.send ('STARTTLS\r\n') print sock.recv (8192) ctx = coro_ssl.ssl_ctx (sslip.SSLV2_CLIENT_METHOD) client = coro_ssl.ssl_sock (ctx) client.create (sock=sock) # client.ssl.set_connect_state() try: coro.print_stderr ('calling ssl_connect()\n') client.ssl_connect() coro.print_stderr ('ssl_connect done()\n') except sslip.Error: coro.print_stderr ("TLS negotiation failed\n") coro.print_stderr ("hit <return> to attempt fallback\n") client.shutdown() raw_input() else: sock = client print "ssl_connect() finished" sock.send ('HELP\r\n') print sock.recv (8192) sock.send ('MAIL FROM:<' + fromaddr + '>\r\n') print sock.recv (8192) sock.send ('RCPT TO:<' + to + '>\r\n') print sock.recv (8192) sock.send ('DATA\r\n') print sock.recv (8192) sock.send ('From: ' + fromaddr + '\r\nSubject: testing STARTTLS\r\n\r\nHi there. I was encrypted\r\n.\r\n') print sock.recv (8192) sock.send ('QUIT\r\n') print sock.recv (8192) sock.close() coro._exit = 1
def serve (port=None, ip='127.0.0.1', unix_path=None, welcome_message=None, global_dict=None): import errno if unix_path: try: os.remove(unix_path) except OSError as why: if why[0] == errno.ENOENT: pass else: raise try: s = coro.make_socket (socket.AF_UNIX, socket.SOCK_STREAM) s.bind(unix_path) except OSError: coro.print_stderr('Error starting up backdoor on unix socket %s\n' % unix_path) raise coro.print_stderr('Backdoor started on unix socket %s\n' % unix_path) else: s = coro.make_socket (socket.AF_INET, socket.SOCK_STREAM) s.set_reuse_addr() if port is None: ports = xrange(8023, 8033) else: if isinstance(port, types.IntType): ports = [port] else: ports = port bound = 0 for i in ports: try: s.bind ((ip, i)) bound = 1 break except (OSError, socket.error) as why: if why[0] != errno.EADDRINUSE: raise OSError(why) if not bound: raise Exception("couldn't bind a port (try not specifying a port)") coro.print_stderr('Backdoor started on port %d\n' % i) s.listen (1024) while True: conn, addr = s.accept() coro.print_stderr ('incoming connection from %r\n' % (conn.getsockname(),)) thread = coro.spawn (client, conn, addr, welcome_message, global_dict) thread.set_name('backdoor session')
def monitor_thread(): while 1: if gc.garbage: coro.print_stderr( "Warning: possible memory leak: len(gc.garbage)=%d\n" % (len(gc.garbage), )) coro.print_stderr("\tFirst %d objects in gc.garbage:\n" % (len(gc.garbage[:5]))) for x in gc.garbage[:5]: coro.print_stderr("\t %s\n" % (safe_repr(x), )) coro.sleep_relative(monitor_sleep_interval)
def monitor_thread(): while True: if gc.garbage: coro.print_stderr ( "Warning: possible memory leak: len(gc.garbage)=%d\n" % (len(gc.garbage),) ) coro.print_stderr ( "\tFirst %d objects in gc.garbage:\n" % (len(gc.garbage[:5])) ) for x in gc.garbage[:5]: coro.print_stderr ("\t %s\n" % (safe_repr (x),)) coro.sleep_relative (monitor_sleep_interval)
def _test_multiple_sleep_interrupt_fail(c): try: c.interrupt('foobar') except SystemError, why: coro.print_stderr(' Expected exception: %s\n' % (why,))
s.bind (unix_path) coro.print_stderr('Backdoor started on unix socket %s\n' % unix_path) else: s = coro.make_socket (coro.PF.INET, coro.SOCK.STREAM) s.set_reuse_addr() if port is None: ports = xrange(8023, 8033) else: if type(port) is int: ports = [port] else: ports = port for i in ports: try: s.bind ((ip, i)) coro.print_stderr('Backdoor started on port %d\n' % i) break except OSError, why: if why[0] != errno.EADDRINUSE: raise OSError(why) else: raise Exception("couldn't bind a port (try not specifying a port)") if client_class is None: client_class = client flags = fcntl.fcntl(s.fileno(), fcntl.F_GETFD) fcntl.fcntl(s.fileno(), fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC) s.listen (1024) while 1:
def debug_line (self, line): coro.print_stderr (line + '\n')
def _test_interrupt_resume(c): coro.print_stderr('resume running\n') coro.coro_sched.the_scheduler.schedule(c, 'yoyo')
def test1(): coro.print_stderr ("waiting 5 seconds...\n") coro.sleep_relative (5) f = ftp_client() coro.print_stderr ("connecting...\n") f.connect ('squirl.nightmare.com') coro.print_stderr ("logging in...\n") f.cmd_user ('anonymous') f.cmd_pass ('rushing@') blocks = [] coro.print_stderr ("retrieving directory listing...\n") f.cmd_list (blocks.append) coro.print_stderr ("done.\n") f.cmd_quit() coro.print_stderr ('-'*20 + '\n') coro.print_stderr (''.join (blocks)) coro.print_stderr ('-'*20 + '\n')
def log(self, level, message, *args): if level <= self.options.verbose: if args: message = message % args coro.print_stderr(message + '\n')
def _test_interrupt_latent(c): coro.print_stderr('interrupter running\n') result = c.interrupt('foo') if result != 1: raise ValueError('Not latent? %i' % result)
s.bind(unix_path) coro.print_stderr('Backdoor started on unix socket %s\n' % unix_path) else: s = coro.make_socket(coro.PF.INET, coro.SOCK.STREAM) s.set_reuse_addr() if port is None: ports = xrange(8023, 8033) else: if type(port) is int: ports = [port] else: ports = port for i in ports: try: s.bind((ip, i)) coro.print_stderr('Backdoor started on port %d\n' % i) break except OSError, why: if why[0] != errno.EADDRINUSE: raise OSError(why) else: raise Exception("couldn't bind a port (try not specifying a port)") if client_class is None: client_class = client flags = fcntl.fcntl(s.fileno(), fcntl.F_GETFD) fcntl.fcntl(s.fileno(), fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC) s.listen(1024) while 1: