X-Git-Url: https://git.ucc.asn.au/?p=progcomp10.git;a=blobdiff_plain;f=src%2Flink%2Fpexpect%2Fexamples%2Fbd_serv.py;fp=src%2Flink%2Fpexpect%2Fexamples%2Fbd_serv.py;h=0000000000000000000000000000000000000000;hp=b7def9e140220ae9b03c3cdb90447fca30f87bf2;hb=edf8e5b569e75692d61a44f2c3241fb6410e4fbd;hpb=35ff18a5beda685e59ca898026570d67b7ead333 diff --git a/src/link/pexpect/examples/bd_serv.py b/src/link/pexpect/examples/bd_serv.py deleted file mode 100755 index b7def9e..0000000 --- a/src/link/pexpect/examples/bd_serv.py +++ /dev/null @@ -1,316 +0,0 @@ -#!/usr/bin/env python - -"""Back door shell server - -This exposes an shell terminal on a socket. - - --hostname : sets the remote host name to open an ssh connection to. - --username : sets the user name to login with - --password : (optional) sets the password to login with - --port : set the local port for the server to listen on - --watch : show the virtual screen after each client request -""" - -# Having the password on the command line is not a good idea, but -# then this entire project is probably not the most security concious thing -# I've ever built. This should be considered an experimental tool -- at best. -import pxssh, pexpect, ANSI -import time, sys, os, getopt, getpass, traceback, threading, socket - -def exit_with_usage(exit_code=1): - - print globals()['__doc__'] - os._exit(exit_code) - -class roller (threading.Thread): - - """This runs a function in a loop in a thread.""" - - def __init__(self, interval, function, args=[], kwargs={}): - - """The interval parameter defines time between each call to the function. - """ - - threading.Thread.__init__(self) - self.interval = interval - self.function = function - self.args = args - self.kwargs = kwargs - self.finished = threading.Event() - - def cancel(self): - - """Stop the roller.""" - - self.finished.set() - - def run(self): - - while not self.finished.isSet(): - # self.finished.wait(self.interval) - self.function(*self.args, **self.kwargs) - -def endless_poll (child, prompt, screen, refresh_timeout=0.1): - - """This keeps the screen updated with the output of the child. This runs in - a separate thread. See roller(). """ - - #child.logfile_read = screen - try: - s = child.read_nonblocking(4000, 0.1) - screen.write(s) - except: - pass - #while True: - # #child.prompt (timeout=refresh_timeout) - # try: - # #child.read_nonblocking(1,timeout=refresh_timeout) - # child.read_nonblocking(4000, 0.1) - # except: - # pass - -def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): - - '''This forks the current process into a daemon. Almost none of this is - necessary (or advisable) if your daemon is being started by inetd. In that - case, stdin, stdout and stderr are all set up for you to refer to the - network connection, and the fork()s and session manipulation should not be - done (to avoid confusing inetd). Only the chdir() and umask() steps remain - as useful. - - References: - UNIX Programming FAQ - 1.7 How do I get my program to act like a daemon? - http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 - - Advanced Programming in the Unix Environment - W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7. - - The stdin, stdout, and stderr arguments are file names that will be opened - and be used to replace the standard file descriptors in sys.stdin, - sys.stdout, and sys.stderr. These arguments are optional and default to - /dev/null. Note that stderr is opened unbuffered, so if it shares a file - with stdout then interleaved output may not appear in the order that you - expect. ''' - - # Do first fork. - try: - pid = os.fork() - if pid > 0: - sys.exit(0) # Exit first parent. - except OSError, e: - sys.stderr.write ("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror) ) - sys.exit(1) - - # Decouple from parent environment. - os.chdir("/") - os.umask(0) - os.setsid() - - # Do second fork. - try: - pid = os.fork() - if pid > 0: - sys.exit(0) # Exit second parent. - except OSError, e: - sys.stderr.write ("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror) ) - sys.exit(1) - - # Now I am a daemon! - - # Redirect standard file descriptors. - si = open(stdin, 'r') - so = open(stdout, 'a+') - se = open(stderr, 'a+', 0) - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) - - # I now return as the daemon - return 0 - -def add_cursor_blink (response, row, col): - - i = (row-1) * 80 + col - return response[:i]+''+response[i:] - -def main (): - - try: - optlist, args = getopt.getopt(sys.argv[1:], 'h?d', ['help','h','?', 'hostname=', 'username=', 'password=', 'port=', 'watch']) - except Exception, e: - print str(e) - exit_with_usage() - - command_line_options = dict(optlist) - options = dict(optlist) - # There are a million ways to cry for help. These are but a few of them. - if [elem for elem in command_line_options if elem in ['-h','--h','-?','--?','--help']]: - exit_with_usage(0) - - hostname = "127.0.0.1" - port = 1664 - username = os.getenv('USER') - password = "" - daemon_mode = False - if '-d' in options: - daemon_mode = True - if '--watch' in options: - watch_mode = True - else: - watch_mode = False - if '--hostname' in options: - hostname = options['--hostname'] - if '--port' in options: - port = int(options['--port']) - if '--username' in options: - username = options['--username'] - print "Login for %s@%s:%s" % (username, hostname, port) - if '--password' in options: - password = options['--password'] - else: - password = getpass.getpass('password: ') - - if daemon_mode: - print "daemonizing server" - daemonize() - #daemonize('/dev/null','/tmp/daemon.log','/tmp/daemon.log') - - sys.stdout.write ('server started with pid %d\n' % os.getpid() ) - - virtual_screen = ANSI.ANSI (24,80) - child = pxssh.pxssh() - child.login (hostname, username, password) - print 'created shell. command line prompt is', child.PROMPT - #child.sendline ('stty -echo') - #child.setecho(False) - virtual_screen.write (child.before) - virtual_screen.write (child.after) - - if os.path.exists("/tmp/mysock"): os.remove("/tmp/mysock") - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - localhost = '127.0.0.1' - s.bind('/tmp/mysock') - os.chmod('/tmp/mysock',0777) - print 'Listen' - s.listen(1) - print 'Accept' - #s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - #localhost = '127.0.0.1' - #s.bind((localhost, port)) - #print 'Listen' - #s.listen(1) - - r = roller (0.01, endless_poll, (child, child.PROMPT, virtual_screen)) - r.start() - print "screen poll updater started in background thread" - sys.stdout.flush() - - try: - while True: - conn, addr = s.accept() - print 'Connected by', addr - data = conn.recv(1024) - if data[0]!=':': - cmd = ':sendline' - arg = data.strip() - else: - request = data.split(' ', 1) - if len(request)>1: - cmd = request[0].strip() - arg = request[1].strip() - else: - cmd = request[0].strip() - if cmd == ':exit': - r.cancel() - break - elif cmd == ':sendline': - child.sendline (arg) - #child.prompt(timeout=2) - time.sleep(0.2) - shell_window = str(virtual_screen) - elif cmd == ':send' or cmd==':xsend': - if cmd==':xsend': - arg = arg.decode("hex") - child.send (arg) - time.sleep(0.2) - shell_window = str(virtual_screen) - elif cmd == ':cursor': - shell_window = '%x%x' % (virtual_screen.cur_r, virtual_screen.cur_c) - elif cmd == ':refresh': - shell_window = str(virtual_screen) - - response = [] - response.append (shell_window) - #response = add_cursor_blink (response, row, col) - sent = conn.send('\n'.join(response)) - if watch_mode: print '\n'.join(response) - if sent < len (response): - print "Sent is too short. Some data was cut off." - conn.close() - finally: - r.cancel() - print "cleaning up socket" - s.close() - if os.path.exists("/tmp/mysock"): os.remove("/tmp/mysock") - print "done!" - -def pretty_box (rows, cols, s): - - """This puts an ASCII text box around the given string, s. - """ - - top_bot = '+' + '-'*cols + '+\n' - return top_bot + '\n'.join(['|'+line+'|' for line in s.split('\n')]) + '\n' + top_bot - -def error_response (msg): - - response = [] - response.append ("""All commands start with : -:{REQUEST} {ARGUMENT} -{REQUEST} may be one of the following: - :sendline: Run the ARGUMENT followed by a line feed. - :send : send the characters in the ARGUMENT without a line feed. - :refresh : Use to catch up the screen with the shell if state gets out of sync. -Example: - :sendline ls -l -You may also leave off :command and it will be assumed. -Example: - ls -l -is equivalent to: - :sendline ls -l -""") - response.append (msg) - return '\n'.join(response) - -def parse_host_connect_string (hcs): - - """This parses a host connection string in the form - username:password@hostname:port. All fields are options expcet hostname. A - dictionary is returned with all four keys. Keys that were not included are - set to empty strings ''. Note that if your password has the '@' character - then you must backslash escape it. """ - - if '@' in hcs: - p = re.compile (r'(?P[^@:]*)(:?)(?P.*)(?!\\)@(?P[^:]*):?(?P[0-9]*)') - else: - p = re.compile (r'(?P)(?P)(?P[^:]*):?(?P[0-9]*)') - m = p.search (hcs) - d = m.groupdict() - d['password'] = d['password'].replace('\\@','@') - return d - -if __name__ == "__main__": - - try: - start_time = time.time() - print time.asctime() - main() - print time.asctime() - print "TOTAL TIME IN MINUTES:", - print (time.time() - start_time) / 60.0 - except Exception, e: - print str(e) - tb_dump = traceback.format_exc() - print str(tb_dump) -