def __init__(self, data_dir: Optional[str] = None): _create = False if data_dir is None or data_dir == '': data_dir = self.get_default_data_dir() _create = True data_dir = os.path.abspath(data_dir) self.__data_dir = data_dir fn = os.path.join(data_dir, 'db.sqlite3') if not os.path.exists(data_dir): if _create: logging.info(f"Working on new {data_dir=:s}") os.mkdir(data_dir) else: raise FileNotFoundError(data_dir) # The specified directory does not exist. else: logging.info(f"Working on {data_dir=:s}") self._audit_open_files_allowed = set() sys.addaudithook(self.__audit_hook) is_new = not os.path.exists(fn) self._db: sqlite3.Connection = sqlite3.connect( 'file:' + fn, uri=True, isolation_level='EXCLUSIVE') # uri=True is for ATTACH commands. self.__db_file = fn if is_new: logging.debug(f"New db file, will create schema.") self.__execute_schema_script()
def main_(): addaudithook(_audit_hook) if len(argv) >= 2: cmd = argv.pop(1) else: cmd = "" argv[0] += ' ' + cmd if cmd == 'qt': from .qt.__main__ import main return main() if cmd == 'manifolds': from .scripts.manifolds import main return main() if cmd == 'thumbs': from .scripts.thumbs import main return main() if cmd == 'load_coco': from .scripts.load_coco import main return main() if cmd == 'build_procrustes': from .scripts.build_procrustes import main return main() if cmd == 'load_dir': from .scripts.load_dir import main return main() print("Unrecognized command.") print("Please choose one from " + ", ".join(commands) + ".") return 1
def test_sys_getframe(): import sys def hook(event, args): if event.startswith("sys."): print(event, args[0].f_code.co_name) sys.addaudithook(hook) sys._getframe()
def run(*, port: int): import sys def p(x, y): print("@@", x, y, file=sys.stderr) sys.addaudithook(p) port = _find_free_port() sentinel = tempfile.mktemp() cmd = [ sys.executable, "-m", "uvicorn", "x00hello:app", "--port", str(port), "--no-use-colors", ] server_process = subprocess.Popen(cmd, env={"SENTINEL": sentinel}) # TODO: # - headers # - cookies # - queries # - trace (logging, dump headers like httpie) # - retry # - auth # - post JSON # - post formData with connect_server(server_process, sentinel=sentinel): headers = {"user-agent": "me"} def log_request(request): print( f"** Request event hook: {request.method} {request.url} - Waiting for response" ) def log_response(response): request = response.request print( f"** Response event hook: {request.method} {request.url} - Status {response.status_code}" ) with httpx.Client( headers=headers, event_hooks={"request": [log_request], "response": [log_response]}, ) as client: print("----------------------------------------") url = f"http://localhost:{port}/" res = client.request("GET", url, params={"pretty": True}) print(res, res.text) print(res.json()) print("----------------------------------------")
def main() -> None: # This says importlib.util.find_spec() can test if a module is currently importable: # https://docs.python.org/3/library/importlib.html#importlib.util.find_spec if not importlib.util.find_spec("invoke"): ensure_invoke() from invoke import task, Program, Config, Collection from invoke.config import merge_dicts from invoke.watchers import Responder namespace = Collection() globs = dict(globals()) namespace.add_task(task(atask_default, post=[ atask_install_scoop, atask_install_keepass, atask_setup_keepass, atask_schedule_updates, ]), default=True) for i,name in enumerate(namespace.tasks["atask-default"].post): namespace.tasks["atask-default"].post[i] = task(name) namespace.add_task(task(name)) class SetupConfig(Config): prefix: str = PROG_NAME @staticmethod def global_defaults(): base_defaults = Config.global_defaults() overrides = { "tasks": {"collection_name": PROG_NAME}, "run": { "shell": "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "echo": True, "debug": True, }, } return merge_dicts(base=base_defaults, updates=overrides) program = Program( name=PROG_NAME, namespace=namespace, config_class=SetupConfig, version="0.0.1" ) # NOTE: Debug # This uses the Python auditing framework in Python 3.8+ if sys.version_info>=(3,8): print("auditing enabled") def print_popen(*args, **kwargs) -> None: if args[0] == "subprocess.Popen": # sys.audit("subprocess.Popen", executable, args, cwd, env) # ("subprocess.Popen", (executable, args, cwd, env)) print(f"{args[1][0]} -> {args[1][1]}") sys.addaudithook(print_popen) program.run()
def start_charybdisfs(source: str, # noqa: C901 # ignore "is too complex" message target: str, debug: bool, rest_api: bool, rest_api_port: int, mount: bool, static_enospc: bool, static_enospc_probability: float) -> None: logging.basicConfig(stream=sys.stdout, level=logging.DEBUG if debug else logging.INFO, format=LOG_FORMAT) if not rest_api and not mount: raise click.UsageError(message="can't run --no-rest-api and --no-mount simultaneously") if debug: sys.addaudithook(sys_audit_hook) if static_enospc: static_enospc_probability = max(0, min(100, round(static_enospc_probability * 100))) LOGGER.info("Going to add ENOSPC fault for all syscalls with probability %s%%", static_enospc_probability) enospc_fault = ErrorFault(sys_call=SysCall.ALL, probability=static_enospc_probability, error_no=errno.ENOSPC) Configuration.add_fault(fault_id=generate_fault_id(), fault=enospc_fault) LOGGER.debug("Faults added: %s", Configuration.get_all_faults()) if rest_api: api_server_thread = \ threading.Thread(target=start_charybdisfs_api_server, kwargs={"port": rest_api_port, }, name="RestServerApi", daemon=True) api_server_thread.start() atexit.register(stop_charybdisfs_api_server) if mount: if source is None or target is None: raise click.BadArgumentUsage("both source and target parameters are required for CharybdisFS mount") fuse_options = set(pyfuse3.default_options) fuse_options.add("fsname=charybdisfs") if debug: fuse_options.add("debug") operations = CharybdisOperations(source=source) pyfuse3.init(operations, target, fuse_options) atexit.register(pyfuse3.close) try: if mount: trio.run(pyfuse3.main) else: api_server_thread.join() except KeyboardInterrupt: LOGGER.info("Interrupted by user...") sys.exit(0)
def test_unraisablehook(): from _testcapi import write_unraisable_exc def unraisablehook(hookargs): pass def hook(event, args): if event == "sys.unraisablehook": if args[0] != unraisablehook: raise ValueError(f"Expected {args[0]} == {unraisablehook}") print(event, repr(args[1].exc_value), args[1].err_msg) sys.addaudithook(hook) sys.unraisablehook = unraisablehook write_unraisable_exc(RuntimeError("nonfatal-error"), "for audit hook test", None)
def test_gc(): import gc def hook(event, args): if event.startswith("gc."): print(event, *args) sys.addaudithook(hook) gc.get_objects(generation=1) x = object() y = [x] gc.get_referrers(x) gc.get_referents(y)
def test_http_client(): import http.client def hook(event, args): if event.startswith("http.client."): print(event, *args[1:]) sys.addaudithook(hook) conn = http.client.HTTPConnection('www.python.org') try: conn.request('GET', '/') except OSError: print('http.client.send', '[cannot send]') finally: conn.close()
def test_excepthook(): def excepthook(exc_type, exc_value, exc_tb): if exc_type is not RuntimeError: sys.__excepthook__(exc_type, exc_value, exc_tb) def hook(event, args): if event == "sys.excepthook": if not isinstance(args[2], args[1]): raise TypeError(f"Expected isinstance({args[2]!r}, " f"{args[1]!r})") if args[0] != excepthook: raise ValueError(f"Expected {args[0]} == {excepthook}") print(event, repr(args[2])) sys.addaudithook(hook) sys.excepthook = excepthook raise RuntimeError("fatal-error")
def test_sqlite3(): import sqlite3 def hook(event, *args): if event.startswith("sqlite3."): print(event, *args) sys.addaudithook(hook) cx = sqlite3.connect(":memory:") # Configured without --enable-loadable-sqlite-extensions if hasattr(sqlite3.Connection, "enable_load_extension"): cx.enable_load_extension(False) try: cx.load_extension("test") except sqlite3.OperationalError: pass else: raise RuntimeError("Expected sqlite3.load_extension to fail")
def test_socket(): import socket def hook(event, args): if event.startswith("socket."): print(event, *args) sys.addaudithook(hook) socket.gethostname() # Don't care if this fails, we just want the audit message sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: # Don't care if this fails, we just want the audit message sock.bind(('127.0.0.1', 8080)) except error: pass finally: sock.close()
def test_winreg(): from winreg import OpenKey, EnumKey, CloseKey, HKEY_LOCAL_MACHINE def hook(event, args): if not event.startswith("winreg."): return print(event, *args) sys.addaudithook(hook) k = OpenKey(HKEY_LOCAL_MACHINE, "Software") EnumKey(k, 0) try: EnumKey(k, 10000) except OSError: pass else: raise RuntimeError("Expected EnumKey(HKLM, 10000) to fail") kv = k.Detach() CloseKey(kv)
def spawner(): if request.method == 'GET': return render_template('index.html') if request.method == 'POST': postvars = request.form _, items_off = find('33 D2 8B 41 28 01', -7, 'imm') items = proc.r64(state + items_off) player_index = proc.r8(items) size = proc.r8(items + 1) player = proc.r64(items + 8 + player_index * 8) # Player X, Y x, y = struct.unpack("<2f", proc.read(player + 0x40, 8)) x += float(postvars['x']) y += float(postvars['y']) spawnid = int(postvars['id']) proc.run(rf""" import ctypes import sys import os def hook(name, *args): if name != 'ctypes.seh_exception': return sys.addaudithook(hook) class CriticalSection: def __enter__(self, *args): ctypes.windll.kernel32.SuspendThread({main_thread}) def __exit__(self, *args): ctypes.windll.kernel32.ResumeThread({main_thread}) # load_item(state.layer[0], entity_name, x, y) try: with CriticalSection(): load_item = (ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int64, ctypes.c_float, ctypes.c_float))({load_item}) instance = load_item({layer}, {spawnid}, {x}, {y}) except Exception as e: import os os.system("msg * \"%s\"" % e) """.strip().encode()) return 'OK'
def sandbox(calculation, result): from sys import addaudithook from os import _exit import constants code = compile(calculation, '<math>', 'exec') def audit(name, args): if not audit.calculated and name == 'exec': audit.calculuated = True else: _exit(1) audit.calculated = False addaudithook(audit) # College Board SAT compliance (prevent cheating) if (any(s in calculation for s in ('__', '==', 'del', 'not', 'in', 'if', 'while', 'for', 'await', 'with', 'import')) or set(calculation) & set('()[]{}+-*@/%&|^<>!~')): return state = {} exec(code, {'__builtins__': {}, 'constants': constants}, state) result.put(state)
def trace_imports() -> Generator[List[Tuple[FileType, Path]], None, None]: files = [] def hook(event: str, args: Tuple[Any, ...]) -> None: if files is not None: if event == "open": path_name = args[0] if isinstance(path_name, str): path = Path(path_name) if not path.is_absolute(): path = Path.cwd() / path files.append((FileType.OPEN, path)) elif event == "import": module_name = args[0] assert isinstance(module_name, str), f"{type(module_name)}: {module_name}" module = importlib.util.find_spec(module_name) if module: if module.origin and module.origin != "built-in": files.append((FileType.IMPORT, Path(module.origin))) sys.addaudithook(hook) yield files files = None
result = True # Fail secure try: import threading managers = security_hook.managers tid = threading.current_thread().ident if -1 in managers: result = managers[-1].dispatch_audit(name, *args[0]) if result: if tid in managers: result = managers[tid].dispatch_audit(name, *args[0]) except BaseException as e: # This ensures that the traceback doesn't reveal anything about the Manager # Possibly over-paranoid, but also makes tracebacks look cleaner e.__traceback__ = None if isinstance(e, errors.SecurityException): raise e from None else: raise errors.ManagerException( f"Manager raised unexpected Exception {type(e).__name__} while handling audit {name}" ) from e if not result: raise errors.PermissionsException(name) security_hook.managers = manager._managers security_hook.code = security_hook.__code__ sys.addaudithook(security_hook) del manager._managers del threading
def __enter__(self, *a): sys.addaudithook(self) return self
def test_finalize_hooks(): sys.addaudithook(TestFinalizeHook())
# --> Monty Python's Flying Circus # >>> s # "Monty Python's Flying Circus" # 如果加载了 readline 模块,input() 将使用它来提供复杂的行编辑和历史记录功能。 # 如果加载了 readline 模块,input() 将使用它来提供复杂的行编辑和历史记录功能。 import readline history_filepath = 'history.txt' while True: line = input('请输入内容:') print(f'{ line = }') readline.write_history_file(history_filepath) # # 引发一个 审计事件 builtins.input 附带参数 prompt。 # # 在成功读取输入之后引发一个审计事件 builtins.input/result 附带结果。 # 引发一个 审计事件 builtins.input 附带参数 prompt。 # 在成功读取输入之后引发一个审计事件 builtins.input/result 附带结果。 import sys def audit_hook(event, args): if event in ['builtins.input', 'builtins.input/result']: print(f'{ event = } { args = }') sys.addaudithook(audit_hook) line = input('请输入内容:') print(f'{ line = }')
#!/usr/local/bin/python import sys def hook(event, args): if not all( [e not in ['subprocess', 'system', 'spawn'] for e in event.split(".")]): print("Bad system call (core dumped)") sys.exit() sys.addaudithook(hook) SOURCE = open(__file__).read() if __name__ == "__main__": assert (sys.version_info[:3] == (3, 8, 5)) print(""" ________ __ ________________ ____ / _/ __ )/ |/ / ____< / __ \/ __ \\ / // __ / /|_/ /___ \ / / / / / / / / _/ // /_/ / / / /___/ // / /_/ / /_/ / /___/_____/_/ /_/_____//_/\____/\____/ """) while True: try: command = input("JohnTitor@IBM5100:~$ ").strip()
def setup_tests(ns): try: stderr_fd = sys.__stderr__.fileno() except (ValueError, AttributeError): # Catch ValueError to catch io.UnsupportedOperation on TextIOBase # and ValueError on a closed stream. # # Catch AttributeError for stderr being None. stderr_fd = None else: # Display the Python traceback on fatal errors (e.g. segfault) faulthandler.enable(all_threads=True, file=stderr_fd) # Display the Python traceback on SIGALRM or SIGUSR1 signal signals = [] if hasattr(signal, 'SIGALRM'): signals.append(signal.SIGALRM) if hasattr(signal, 'SIGUSR1'): signals.append(signal.SIGUSR1) for signum in signals: faulthandler.register(signum, chain=True, file=stderr_fd) _adjust_resource_limits() replace_stdout() support.record_original_stdout(sys.stdout) if ns.testdir: # Prepend test directory to sys.path, so runtest() will be able # to locate tests sys.path.insert(0, os.path.abspath(ns.testdir)) # Some times __path__ and __file__ are not absolute (e.g. while running from # Lib/) and, if we change the CWD to run the tests in a temporary dir, some # imports might fail. This affects only the modules imported before os.chdir(). # These modules are searched first in sys.path[0] (so '' -- the CWD) and if # they are found in the CWD their __file__ and __path__ will be relative (this # happens before the chdir). All the modules imported after the chdir, are # not found in the CWD, and since the other paths in sys.path[1:] are absolute # (site.py absolutize them), the __file__ and __path__ will be absolute too. # Therefore it is necessary to absolutize manually the __file__ and __path__ of # the packages to prevent later imports to fail when the CWD is different. for module in sys.modules.values(): if hasattr(module, '__path__'): for index, path in enumerate(module.__path__): module.__path__[index] = os.path.abspath(path) if getattr(module, '__file__', None): module.__file__ = os.path.abspath(module.__file__) if ns.huntrleaks: yp_unittest.BaseTestSuite._cleanup = False sys._deactivate_opcache() if ns.memlimit is not None: support.set_memlimit(ns.memlimit) if ns.threshold is not None: gc.set_threshold(ns.threshold) support.suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2) support.use_resources = ns.use_resources if hasattr(sys, 'addaudithook'): # Add an auditing hook for all tests to ensure PySys_Audit is tested def _test_audit_hook(name, args): pass sys.addaudithook(_test_audit_hook) setup_unraisable_hook() setup_threading_excepthook() if ns.timeout is not None: # For a slow buildbot worker, increase SHORT_TIMEOUT and LONG_TIMEOUT support.SHORT_TIMEOUT = max(support.SHORT_TIMEOUT, ns.timeout / 40) support.LONG_TIMEOUT = max(support.LONG_TIMEOUT, ns.timeout / 4) # If --timeout is short: reduce timeouts support.LOOPBACK_TIMEOUT = min(support.LOOPBACK_TIMEOUT, ns.timeout) support.INTERNET_TIMEOUT = min(support.INTERNET_TIMEOUT, ns.timeout) support.SHORT_TIMEOUT = min(support.SHORT_TIMEOUT, ns.timeout) support.LONG_TIMEOUT = min(support.LONG_TIMEOUT, ns.timeout) if ns.xmlpath: from yp_test.support.testresult import RegressionTestResult RegressionTestResult.USE_XML = True # Ensure there's a non-ASCII character in env vars at all times to force # tests consider this case. See BPO-44647 for details. os.environ.setdefault( UNICODE_GUARD_ENV, "\N{SMILING FACE WITH SUNGLASSES}", )
from sys import addaudithook def hook(action, _): if action not in ("import", "exec"): # print(f"Dangerous {action}") raise SystemExit(0) raise 0 # exit whatever source = compile(bytes.fromhex(input()), "", "exec") addaudithook(hook) del hook, addaudithook exec(source)
def engage_auditwall() -> None: sys.dont_write_bytecode = True # disable .pyc file writing if sys.version_info >= (3, 8): # audithook is new in 3.8 sys.addaudithook(audithook)
def run_finalize_test(): """Called by test_finalize_hooks in a subprocess.""" sys.addaudithook(TestFinalizeHook())
def is_package(self, fullname): if fullname == "packages": return True return False def get_code(self, fullname): if fullname == "packages": return None if fullname.find("packages.") == 0: f = open(os.path.join('./repo', fullname[9:], "package"), 'r') code = f.read() f.close() return code def create_module(self, spec): return None def exec_module(self, module): code = self.get_code(module.__name__) if code is None: return builts = packagebuiltins.PackageScriptBuiltins(__builtins__) module.__dict__["__builtins__"] = builts PkgLoader.audit_enable = True exec(code, module.__dict__) PkgLoader.audit_enable = False sys.addaudithook(PkgLoader.audit_hook)
def setup(self): self.collect_all() sys.addaudithook(_make_audithook(self))
def setup_tests(ns): try: stderr_fd = sys.__stderr__.fileno() except (ValueError, AttributeError): # Catch ValueError to catch io.UnsupportedOperation on TextIOBase # and ValueError on a closed stream. # # Catch AttributeError for stderr being None. stderr_fd = None else: # Display the Python traceback on fatal errors (e.g. segfault) faulthandler.enable(all_threads=True, file=stderr_fd) # Display the Python traceback on SIGALRM or SIGUSR1 signal signals = [] if hasattr(signal, 'SIGALRM'): signals.append(signal.SIGALRM) if hasattr(signal, 'SIGUSR1'): signals.append(signal.SIGUSR1) for signum in signals: faulthandler.register(signum, chain=True, file=stderr_fd) replace_stdout() support.record_original_stdout(sys.stdout) if ns.testdir: # Prepend test directory to sys.path, so runtest() will be able # to locate tests sys.path.insert(0, os.path.abspath(ns.testdir)) # Some times __path__ and __file__ are not absolute (e.g. while running from # Lib/) and, if we change the CWD to run the tests in a temporary dir, some # imports might fail. This affects only the modules imported before os.chdir(). # These modules are searched first in sys.path[0] (so '' -- the CWD) and if # they are found in the CWD their __file__ and __path__ will be relative (this # happens before the chdir). All the modules imported after the chdir, are # not found in the CWD, and since the other paths in sys.path[1:] are absolute # (site.py absolutize them), the __file__ and __path__ will be absolute too. # Therefore it is necessary to absolutize manually the __file__ and __path__ of # the packages to prevent later imports to fail when the CWD is different. for module in sys.modules.values(): if hasattr(module, '__path__'): for index, path in enumerate(module.__path__): module.__path__[index] = os.path.abspath(path) if getattr(module, '__file__', None): module.__file__ = os.path.abspath(module.__file__) # MacOSX (a.k.a. Darwin) has a default stack size that is too small # for deeply recursive regular expressions. We see this as crashes in # the Python test suite when running test_re.py and test_sre.py. The # fix is to set the stack limit to 2048. # This approach may also be useful for other Unixy platforms that # suffer from small default stack limits. if sys.platform == 'darwin': try: import resource except ImportError: pass else: soft, hard = resource.getrlimit(resource.RLIMIT_STACK) newsoft = min(hard, max(soft, 1024 * 2048)) resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard)) if ns.huntrleaks: unittest.BaseTestSuite._cleanup = False if ns.memlimit is not None: support.set_memlimit(ns.memlimit) if ns.threshold is not None: gc.set_threshold(ns.threshold) suppress_msvcrt_asserts(ns.verbose and ns.verbose >= 2) support.use_resources = ns.use_resources if hasattr(sys, 'addaudithook'): # Add an auditing hook for all tests to ensure PySys_Audit is tested def _test_audit_hook(name, args): pass sys.addaudithook(_test_audit_hook)
def bar(): print("bar") boo() print("bar") def boo(): print("boo") raise Exception("oops") def p(x, y): print("@@", x, y, file=sys.stderr) sys.addaudithook(p) logger = logging.getLogger(__name__) logging.basicConfig( level=logging.DEBUG, format= "%(levelname)s:%(name)s:%(message)s -- %(module)s.%(funcName)s:%(lineno)d", ) def log(typ, val, tb): logger.info("hmm %r", val, exc_info=val) sys.excepthook = log foo()
eval("1") # No traced call hook.__cantrace__ = False eval("2") # One traced call hook.__cantrace__ = True eval("3") # Two traced calls (writing to private member, eval) hook.__cantrace__ = 1 eval("4") # One traced call (writing to private member) hook.__cantrace__ = 0 finally: sys.settrace(old) self.assertSequenceEqual(["call"] * 4, traced) if __name__ == "__main__": if len(sys.argv) >= 2 and sys.argv[1] == "spython_test": # Doesn't matter what we add - it will be blocked sys.addaudithook(None) sys.exit(0) unittest.main()