|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +# interactive console with easy access to krb5 test harness stuff |
| 4 | + |
| 5 | +import code |
| 6 | +import os |
| 7 | +import sys |
| 8 | +import copy |
| 9 | + |
| 10 | +from gssapi.tests import k5test |
| 11 | + |
| 12 | + |
| 13 | +READLINE_SRC = """ |
| 14 | +# python startup file |
| 15 | +import readline |
| 16 | +import rlcompleter |
| 17 | +import atexit |
| 18 | +import os |
| 19 | +
|
| 20 | +completer = rlcompleter.Completer(globals()) |
| 21 | +readline.set_completer(completer.complete) |
| 22 | +
|
| 23 | +# tab completion |
| 24 | +readline.parse_and_bind('Control-space: complete') |
| 25 | +# history file |
| 26 | +histfile = os.path.join(os.environ['HOME'], '.pythonhistory') |
| 27 | +try: |
| 28 | + readline.read_history_file(histfile) |
| 29 | +except IOError: |
| 30 | + pass |
| 31 | +
|
| 32 | +atexit.register(readline.write_history_file, histfile) |
| 33 | +del os, histfile, readline, rlcompleter |
| 34 | +""" |
| 35 | + |
| 36 | +BANNER = """GSSAPI Interactive console |
| 37 | +Python {ver} on {platform} |
| 38 | +Type "help", "copyright", "credits" or "license" for more information about Python. |
| 39 | +
|
| 40 | +mechansim: {mech}, realm: {realm}, user: {user}, host: {host} |
| 41 | +(functions for controlling the realm available in `REALM`)""" |
| 42 | + |
| 43 | + |
| 44 | +class GSSAPIConsole(code.InteractiveConsole): |
| 45 | + def __init__(self, use_readline=True, realm_args={}, *args, **kwargs): |
| 46 | + code.InteractiveConsole.__init__(self, *args, **kwargs) |
| 47 | + |
| 48 | + self.realm = self._create_realm(realm_args) |
| 49 | + self.locals['REALM'] = self.realm |
| 50 | + |
| 51 | + self.runsource('import gssapi') |
| 52 | + self.runsource('import gssapi.raw as gb') |
| 53 | + |
| 54 | + if use_readline: |
| 55 | + self._add_readline() |
| 56 | + |
| 57 | + if os.environ.get('LD_LIBRARY_PATH'): |
| 58 | + self.realm.env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH'] |
| 59 | + |
| 60 | + def _create_realm(self): |
| 61 | + return None |
| 62 | + |
| 63 | + def _add_readline(self): |
| 64 | + res = self.runsource(READLINE_SRC, '<readline setup>', 'exec') |
| 65 | + |
| 66 | + |
| 67 | +class Krb5Console(GSSAPIConsole): |
| 68 | + def _create_realm(self, realm_args): |
| 69 | + return k5test.K5Realm(**realm_args) |
| 70 | + |
| 71 | + |
| 72 | +MECH_MAP = {'krb5': Krb5Console} |
| 73 | + |
| 74 | + |
| 75 | +import argparse |
| 76 | +parser = argparse.ArgumentParser(description='An interactive Python console with krb5 setup') |
| 77 | +parser.add_argument('file', metavar='FILE', nargs='?', |
| 78 | + help='a file to run', default=None) |
| 79 | +parser.add_argument('-i', default=False, dest='force_interactive', |
| 80 | + action='store_const', const=True, |
| 81 | + help='Force interactive mode when running with a file') |
| 82 | +parser.add_argument('--realm-args', default=None, |
| 83 | + help='A comma-separated list of key=(true|false) values to ' |
| 84 | + 'pass to the realm constructor') |
| 85 | +parser.add_argument('--mech', default='krb5', |
| 86 | + help='Which environment to setup up ' |
| 87 | + '(supports krb5 [default])') |
| 88 | + |
| 89 | +PARSED_ARGS = parser.parse_args() |
| 90 | + |
| 91 | + |
| 92 | +if PARSED_ARGS.mech not in MECH_MAP: |
| 93 | + sys.exit('The %s environment is not supported by the ' |
| 94 | + 'GSSAPI console' % PARSED_ARGS.mech) |
| 95 | + |
| 96 | + |
| 97 | +realm_args = {} |
| 98 | +if PARSED_ARGS.realm_args: |
| 99 | + for arg in PARSED_ARGS.realm_args.split(','): |
| 100 | + key, raw_val = arg.split('=') |
| 101 | + realm_args[key] = (raw_val.lower() == 'true') |
| 102 | + |
| 103 | +console = MECH_MAP[PARSED_ARGS.mech](realm_args=realm_args) |
| 104 | +SAVED_ENV = None |
| 105 | + |
| 106 | +try: |
| 107 | + # create the banner |
| 108 | + banner_text = BANNER.format(ver=sys.version, platform=sys.platform, |
| 109 | + mech=PARSED_ARGS.mech, |
| 110 | + realm=console.realm.realm, |
| 111 | + user=console.realm.user_princ, |
| 112 | + host=console.realm.host_princ) |
| 113 | + |
| 114 | + # import the env |
| 115 | + SAVED_ENV = copy.deepcopy(os.environ) |
| 116 | + for k,v in console.realm.env.items(): |
| 117 | + os.environ[k] = v |
| 118 | + |
| 119 | + INTER = True |
| 120 | + # run the interactive interpreter |
| 121 | + if PARSED_ARGS.file is not None: |
| 122 | + if not PARSED_ARGS.force_interactive: |
| 123 | + INTER = False |
| 124 | + |
| 125 | + with open(PARSED_ARGS.file) as src: |
| 126 | + console.runsource(src.read(), src.name, 'exec') |
| 127 | + |
| 128 | + if INTER: |
| 129 | + console.interact(banner_text) |
| 130 | + |
| 131 | +except (KeyboardInterrupt, EOFError): |
| 132 | + pass |
| 133 | +finally: |
| 134 | + # restore the env |
| 135 | + if SAVED_ENV is not None: |
| 136 | + for k in copy.deepcopy(os.environ): |
| 137 | + if k in SAVED_ENV: |
| 138 | + os.environ[k] = SAVED_ENV[k] |
| 139 | + else: |
| 140 | + del os.environ[k] |
| 141 | + |
| 142 | + console.realm.stop() |
0 commit comments