def main(file: click.File, debug: bool, input: int) -> int: """ A Python implementation of the chicken esoteric programming language. Pass a source file using -f/--file or pipe the source to the program. """ # Debug mode if debug: log.setLevel(logging.DEBUG) # Accept source code from both the --file option and stdin # https://stackoverflow.com/a/13443424/11457597 stdin_mode = os.fstat(sys.stdin.fileno()).st_mode if file: log.debug(f"Reading source from file: {file.name!r}") source_code = file.read() elif stat.S_ISFIFO(stdin_mode) or stat.S_ISREG(stdin_mode): log.debug("Reading source from pipe/redirect...") source_code = click.open_file("-").read() else: log.debug("Couldn't find source!") message = ( "ERROR: Source code required. Pipe text into the program or pass the --file option." ) click.echo(message=message, err=True) return EXIT_FAILURE exit_status = interpret(source_code, input) return exit_status
def main(source: click.File, destination: click.File) -> int: requirements = source.read().split() new_requirements = sort_requirements(requirements=requirements) destination.write("\n".join(new_requirements)) click.echo(f"Successfully wrote to {destination.name}") return 0
def write_file(ctx: click.Context, bin_file: click.File) -> None: """Write boot image data. \b FILE - binary file to write """ click.echo(WARNING_MSG) data = bin_file.read() # type: ignore with SDPS(ctx.obj['interface'], device_name=ctx.obj['name']) as sdps: sdps.write_file(data)
def receive_sb_file(ctx: click.Context, sb_file: click.File) -> None: """Receive SB file. \b FILE - SB file to send to target """ with McuBoot(ctx.obj['interface']) as mboot: data = sb_file.read() # type: ignore mboot.receive_sb_file(data) display_output([], mboot.status_code, ctx.obj['use_json'])
def process_optional_file(input: click.File): "Process a file given as option" if input is None: click.echo("no input file given") while True: click.echo(f"Reading from {input.name}...") chunk = input.read(2048) if not chunk: break click.echo(chunk.upper())
def load_image(ctx: click.Context, boot_file: click.File) -> None: """Load a boot image to the device. \b FILE - boot file to load """ data = boot_file.read() # type: ignore with McuBoot(ctx.obj['interface']) as mboot: mboot.load_image(data) display_output([], mboot.status_code, ctx.obj['use_json'])
def parse(device: str, revision: str, area: str, output: click.Path, binary: click.File, show_calc: bool, show_diff: bool) -> None: """Parse binary a extract configuration.""" pfr_obj = _get_pfr_class(area)(device=device, revision=revision) data = binary.read() # type: ignore parsed = pfr_obj.parse(data, exclude_computed=False) if show_diff: parsed = dict_diff( pfr_obj.generate_config(exclude_computed=not show_calc), parsed) json_data = json.dumps(parsed, indent=2) _store_output(json_data, output)
def receive_sb_file(ctx: click.Context, sb_file: click.File) -> None: """Receive SB file. \b FILE - SB file to send to target """ with McuBoot(ctx.obj['interface']) as mboot: data = sb_file.read() # type: ignore write_response = mboot.receive_sb_file(data) assert write_response, f"Error sending SB file." display_output([write_response], mboot.status_code, ctx.obj['use_json'])
def write_file(ctx: click.Context, address: int, bin_file: click.File, count: int) -> None: """Write file at address. \b ADDRESS - starting address of the image FILE - binary file to write COUNT - Count is size of data to write in bytes (default: whole file) """ data = bin_file.read(count) # type: ignore with SDP(ctx.obj['interface']) as sdp: sdp.write_file(address, data) display_output([], sdp.response_value)
def write_memory(ctx: click.Context, address: int, in_file: click.File, memory_id: int) -> None: """Write memory. \b ADDRESS - starting address FILE - write content of this file MEMORY_ID - id of memory to read from (default: 0) """ with McuBoot(ctx.obj['interface']) as mboot: data = in_file.read() # type: ignore write_response = mboot.write_memory(address, data, memory_id) assert write_response, f"Error writing memory addr={address:#0x} memory_id={memory_id}" display_output([write_response], mboot.status_code, ctx.obj['use_json'])
def process_input_file(input: click.File, output: click.File): "Process file and create a download link for output file" if DEBUG: click.echo("global debug set, printing some debug output") while True: click.echo(f"Reading from {input.name}...") chunk = input.read(2048) if not chunk: break click.echo(f"Writing to {output.name}...") chunk = chunk.upper() output.write(chunk) click.echo({output.name})
def generate_key_blob(ctx: click.Context, dek_file: click.File, blob_file: click.File) -> None: """Generate the Key Blob for a given DEK. \b DEK_FILE - the file with the binary DEK key BLOB_FILE - the generated file with binary key blob """ with McuBoot(ctx.obj['interface']) as mboot: data = dek_file.read() # type: ignore write_response = mboot.generate_key_blob(data) if not write_response: raise ValueError(f"Error generating key blob") blob_file.write(write_response) # type: ignore display_output([mboot.status_code, len(write_response)], mboot.status_code, ctx.obj['use_json'])
def load_file(verbose, file: click.File): """Load and execute a script file into database.""" sql = file.read() click.secho(f'Loading file {file.name}...', bold = True, fg = 'yellow') if verbose: click.echo(sql) with _db.session.begin_nested(): _db.session.execute(sql) _db.session.commit() click.secho(f'File {file.name} loaded!', bold = True, fg = 'green')
def write_file(ctx: click.Context, address: int, bin_file: click.File, count: int) -> None: """Writes file to the device’s memory address. \b ADDRESS - starting address of the image FILE - binary file to write COUNT - Count is the size of data to write in bytes (default: whole file) """ data = bin_file.read(count) # type: ignore with SDP(ctx.obj["interface"]) as sdp: sdp.write_file(address, data) display_output( [], sdp.hab_status, extra_output=f"Response status = {decode_status_code(sdp.cmd_status)}.", )
def main(program: click.File, raw: bool = False) -> None: space = FungeSpace(program.read()) # type: ignore # TODO: logging, commenting # If no state activated, continue processing of char # else, move to next cell while space.running: cmd = space.val() char = chr(cmd) if space.toggle_states(char): run_instruction(char, space) space.move() # output newline to terminal unless --raw if (not raw) and stdout.isatty(): click.echo("")
def parse_binary( device: str, revision: str, area: str, output: click.Path, binary: click.File, show_calc: bool, show_diff: bool, ) -> None: """Parse binary and extract configuration.""" pfr_obj = _get_pfr_class(area)(device=device, revision=revision) data = binary.read() # type: ignore pfr_obj.parse(data) parsed = pfr_obj.get_yaml_config(exclude_computed=not show_calc, diff=show_diff) yaml = YAML() yaml.indent(sequence=4, offset=2) stream = io.StringIO() yaml.dump(parsed, stream) yaml_data = stream.getvalue() _store_output(yaml_data, output)
def migra( owner: str, file: click.File, urls: List[str], submodule_from: str, ): if not check_if_installed("git") or not check_if_installed("hub"): return # Filter out invalid URLs and join file and args URLs urls = list(filter(validate_git_url, urls)) if file: urls += list(filter(validate_git_url, file.read().splitlines())) # Removes duplicates urls = list(set(urls)) names: Dict[str, List[str]] = {} # Assumes a match is always found for url in urls: match = REPO_NAME_REGEX.search(url) name = match.group(1) if name in names: names[name].append(url) else: names[name] = [url] # Removes repositories with same name duplicates: Dict[str, List[str]] = {k: v for k, v in names.items() if len(v) > 1} repos: Dict[str, str] = {k: v[0] for k, v in names.items() if len(v) == 1} # Warn users that duplicates won't be processed if len(duplicates) > 0: print("Skipping repositories with same name:") for name, repo_urls in duplicates.items(): print(f"{name}") for url in repo_urls: print(f" {url}") # Starts processing repositories asyncio.run(process(owner, repos, submodule_from))
def get_docker_compose(input_file: click.File) -> dict: """Gets the contents of the docker-compose file after it's been parsed by PyYaml. If the file cannot be opened or parsed i.e. incorrect yaml. Then it will throw an error and exit. Args: input_file (click.File): An file object (docker-compose). Returns: dict: Contents of the docker-compose file. """ logger.info("Opening docker-compose file.") try: data = "".join(sys.stdin.readlines( )) if input_file.name == "<stdin>" else input_file.read() docker_compose = yaml.load(data, Loader=yaml.SafeLoader) except yaml.YAMLError as e: error_message = f"Invalid yaml file, {input_file.name}." logger.error(f"error_message, {e}") click.echo(error_message, err=True) sys.exit(1) logger.info("Retrieved docker compose data.") return docker_compose
def generate_key_blob(ctx: click.Context, dek_file: click.File, blob_file: click.File, key_sel: str) -> None: """Generate the Key Blob for a given DEK. \b DEK_FILE - the file with the binary DEK key BLOB_FILE - the generated file with binary key blob KEY_SEL - select the BKEK used to wrap the BK and generate the blob. For devices with SNVS, valid options of [key_sel] are 0, 1 or OTPMK: OTPMK from FUSE or OTP(default), 2 or ZMK: ZMK from SNVS, 3 or CMK: CMK from SNVS, For devices without SNVS, this option will be ignored. """ with McuBoot(ctx.obj['interface']) as mboot: data = dek_file.read() # type: ignore key_sel_int = int(key_sel) if key_sel.isnumeric() else GenerateKeyBlobSelect.get(key_sel) assert isinstance(key_sel_int, int) write_response = mboot.generate_key_blob(data, key_sel=key_sel_int) display_output( [mboot.status_code, len(write_response)] if write_response else None, mboot.status_code, ctx.obj['use_json'] ) if write_response: blob_file.write(write_response) # type: ignore
def rsvp_chase(ctx, template_file: click.File): user_list = _get_not_yet_rsvp_users(ctx.obj['WM_API_URL'], ctx.obj['WM_API_USER'], ctx.obj['WM_API_PASS']) message = template_file.read() _send_messages(ctx, user_list, message)
def explore(startup_command: str, quiet: bool, file_commands, startup_script: click.File, enable_api: bool, plugin_folder: str) -> None: """ Start the objection exploration REPL. """ agent = Agent() pause_early = not (file_commands is None and startup_script is None and startup_command is None) try: agent.inject(pause_early) except (frida.ServerNotRunningError, frida.NotSupportedError) as e: click.secho('Unable to connect to the frida server: {error}'.format( error=str(e)), fg='red') return # set the frida agent state_connection.set_agent(agent=agent) # load plugins if plugin_folder: folder = os.path.abspath(plugin_folder) debug_print('[plugin] Plugins path is: {0}'.format(folder)) for p in os.scandir(folder): # skip files and hidden directories if p.is_file() or p.name.startswith('.'): debug_print('[plugin] Skipping {0}'.format(p.name)) continue debug_print('[plugin] Attempting to load plugin at {0}'.format( p.path)) load_plugin([p.path]) # start the main REPL r = Repl() # if we have a command to run, do that first before # the call to get_device_info(). if startup_command: for command in startup_command: click.secho('Running a startup command... {0}'.format(command), dim=True) r.run_command(command) # If we have a script, import and run that asap if startup_script: click.secho( 'Importing and running startup script at: {location}'.format( location=startup_script), dim=True) response = agent.single(startup_script.read(), pause_early) print(response) # process commands from a resource file if file_commands: click.secho('Running commands from file...', bold=True) for command in file_commands.readlines(): # clean up newlines command = command.strip() # do nothing for empty lines if command == '': continue # run the command using the instantiated repl click.secho('Running: \'{0}\':\n'.format(command), dim=True) r.run_command(command) agent.resume() try: # poll the device for information. this method also sets # the device type internally in state.device device_info = get_device_info() except (frida.TimedOutError, frida.ServerNotRunningError, frida.ProcessNotFoundError, frida.NotSupportedError) as e: click.secho('Could not connect with error: {0}'.format(str(e)), fg='red') print_frida_connection_help() return warn_about_older_operating_systems() # start the api server if enable_api: def api_thread(): """ Small method to run Flash non-blocking :return: """ a = create_api_app() a.run(host=app_state.api_host, port=app_state.api_port) click.secho('Starting API server on {host}:{port}'.format( host=app_state.api_host, port=app_state.api_port), fg='yellow', bold=True) thread = threading.Thread(target=api_thread) thread.daemon = True thread.start() time.sleep(2) # run the REPL and wait for more commands r.set_prompt_tokens(device_info) r.start_repl(quiet=quiet)
def start(plugin_folder: str, quiet: bool, startup_command: str, file_commands, startup_script: click.File, enable_api: bool) -> None: """ Start a new session """ agent = get_agent() state_connection.set_agent(agent) # load plugins if plugin_folder: folder = Path(plugin_folder).resolve() debug_print(f'[plugin] Plugins path is: {folder}') for p in folder.iterdir(): if p.is_file() or p.name.startswith('.'): debug_print(f'[plugin] Skipping {p.name}') continue debug_print(f'[plugin] Attempting to load plugin at {p}') load_plugin([p]) repl = Repl() if startup_script: click.secho( f'Importing and running startup script at: {startup_script}', dim=True) agent.attach_script(startup_script.read()) if startup_command: for command in startup_command: click.secho(f'Running a startup command... {command}', dim=True) repl.run_command(command) if file_commands: click.secho('Running commands from file...', bold=True) for command in file_commands.readlines(): command = command.strip() if command == '': continue # run the command using the instantiated repl click.secho(f'Running: \'{command}\':\n', dim=True) repl.run_command(command) warn_about_older_operating_systems() # start the api server if enable_api: def api_thread(): """ Small method to run Flask non-blocking """ api_state.start(app_state.api_host, app_state.api_port) click.secho( f'Starting API server on {app_state.api_host}:{app_state.api_port}', fg='yellow', bold=True) thread = threading.Thread(target=api_thread) thread.daemon = True thread.start() time.sleep(2) # drop into the repl repl.run(quiet=quiet)
def update(ctx, template_file: click.File): user_list = _get_all_contact_users(ctx.obj['WM_API_URL'], ctx.obj['WM_API_USER'], ctx.obj['WM_API_PASS']) message = template_file.read() _send_messages(ctx, user_list, message)
def run(file: click.File): config = json.loads(file.read()) th = TaskHandler(config=config) for task in th.getTasks(): task.process()