def download_wrapper(): """Provides wrapper method to use in 'syntribos download' subcommand.""" templates_uri = CONF.remote.templates_uri payloads_uri = CONF.remote.payloads_uri templates_dir = (CONF.remote.cache_dir or os.path.join(get_syntribos_root(), "templates")) payloads_dir = (CONF.remote.cache_dir or os.path.join(get_syntribos_root(), "payloads")) if not CONF.sub_command.templates and not CONF.sub_command.payloads: print( _("Please specify the --templates flag and/or the --payloads" "flag to this command.\nNo files have been downloaded.\n")) if CONF.sub_command.templates: print( _("Downloading template files from %(uri)s to %(dir)s...") % { "uri": templates_uri, "dir": templates_dir }) try: remotes.get(templates_uri, templates_dir) print( _("Download successful! To use these templates, edit your " "config file to update the location of templates.")) except Exception: print( _("Template download failed. Our documentation contains " "instructions to provide templates manually.")) exit(1) if CONF.sub_command.payloads: print( _("Downloading payload files from %(uri)s to %(dir)s...\n") % { "uri": payloads_uri, "dir": payloads_dir }) try: remotes.get(payloads_uri, payloads_dir) print( _("Download successful! To use these payloads, edit your " "config file to update the location of payloads.")) except Exception: print( _("Payload download failed. Our documentation contains " "instructions to provide payloads manually.")) exit(1)
def download_wrapper(): """Provides wrapper method to use in 'syntribos download' subcommand.""" templates_uri = CONF.remote.templates_uri payloads_uri = CONF.remote.payloads_uri templates_dir = (CONF.remote.cache_dir or os.path.join(get_syntribos_root(), "templates")) payloads_dir = (CONF.remote.cache_dir or os.path.join(get_syntribos_root(), "payloads")) if not CONF.sub_command.templates and not CONF.sub_command.payloads: print( _( "Please specify the --templates flag and/or the --payloads" "flag to this command.\nNo files have been downloaded.\n")) if CONF.sub_command.templates: print(_( "Downloading template files from %(uri)s to %(dir)s..." ) % {"uri": templates_uri, "dir": templates_dir}) try: remotes.get(templates_uri, templates_dir) print(_( "Download successful! To use these templates, edit your " "config file to update the location of templates.")) except Exception: print(_( "Template download failed. Our documentation contains " "instructions to provide templates manually.")) exit(1) if CONF.sub_command.payloads: print(_( "Downloading payload files from %(uri)s to %(dir)s...\n") % { "uri": payloads_uri, "dir": payloads_dir}) try: remotes.get(payloads_uri, payloads_dir) print(_( "Download successful! To use these payloads, edit your " "config file to update the location of payloads.")) except Exception: print(_( "Payload download failed. Our documentation contains " "instructions to provide payloads manually.")) exit(1)
def _get_strings(cls, file_name=None): payloads = CONF.syntribos.payloads if not payloads: payloads = remotes.get(CONF.remote.payloads_uri) content = ContentType('r', 0)(payloads) for file_path, _ in content: if file_path.endswith(".txt"): file_dir = os.path.split(file_path)[0] payloads = os.path.join(payloads, file_dir) break try: path = os.path.join(payloads, file_name or cls.data_key) with open(path, "rb") as fp: return fp.read().splitlines() except IOError as e: LOG.error("Exception raised: {}".format(e)) print("\nNo file named {} found in the payloads dir, " "exiting..".format(file_name or cls.data_key)) exit(1)
def _get_strings(cls, file_name=None): payloads = CONF.syntribos.payloads if not payloads: payloads = remotes.get(CONF.remote.payloads_uri) content = ContentType('r', 0)(payloads) for file_path, _ in content: if file_path.endswith(".txt"): file_dir = os.path.split(file_path)[0] payloads = os.path.join(payloads, file_dir) break try: if os.path.isfile(cls.data_key): path = cls.data_key else: path = os.path.join(payloads, file_name or cls.data_key) with open(path, "rb") as fp: return fp.read().splitlines() except (IOError, AttributeError, TypeError) as e: LOG.error("Exception raised: {}".format(e)) print("\nPayload file for test '{}' not readable, " "exiting...".format(cls.test_name)) exit(1)
def initialize_syntribos_env(): """Sets up payloads, config, etc. for syntribos after installation.""" def prompt_yes(prompt): answer = input(prompt).lower() return answer == "yes" or answer == "y" def prompt_yes_or_quit(prompt): prompt = ("{0}\n\tType 'yes' or 'y' to continue, anything else " "to quit: ").format(prompt) if not prompt_yes(prompt): print("Aborting syntribos initialization.") exit(0) return True def prompt_yes_or_continue(prompt): prompt = ("{0}\n\tType 'yes' or 'y' to continue, anything else " "for more options: ").format(prompt) return prompt_yes(prompt) global FILE logging.basicConfig(level=logging.DEBUG) root_dir = get_venv_root() if is_venv() else get_user_home_root() force = CONF.sub_command.force custom_root = CONF.sub_command.custom_install_root or "" if custom_root: root_dir = custom_root elif CONF.sub_command.force: pass else: # Check if we've already initalized env so we don't overwrite anything if is_syntribos_initialized(): prompt = ("It seems syntribos has already been initialized.") prompt_yes_or_quit(prompt) else: if not CONF.sub_command.no_downloads: prompt = ("Syntribos has not been initialized. By default, " "this process will create a '.syntribos' folder\n " "with a barebones configuration file, and " "sub-folders for templates, debug logs, and\n " "payloads. Syntribos will also attempt to download " "payload files, which are necessary for fuzz\n " "tests to run. To avoid this behavior, run this " "command again with the --no_downloads flag") else: prompt = ("Syntribos has not been initialized. By default, " "this process will create a '.syntribos' folder\n " "with a barebones configuration file, and " "sub-folders for templates, debug logs, and\n " "payloads. Syntribos will not attempt to download " "any files during the initialization process.") prompt_yes_or_quit(prompt) if is_venv(): prompt = "Virtual environment detected. Install to {0}?".format( get_venv_root()) if prompt_yes_or_continue(prompt): root_dir = get_venv_root() else: prompt = ("Install to your home directory ({0})?").format( get_user_home_root()) if prompt_yes_or_quit(prompt): root_dir = get_user_home_root() folders_created = create_env_dirs(root_dir, force=force) # Grab payloads logging.disable(logging.ERROR) # Don't want to log to console here... payloads_dir = folders_created[1] if not CONF.sub_command.no_downloads: print("\nDownloading payload files to {0}...".format(payloads_dir)) try: remote_path = remotes.get(CONF.remote.payloads_uri, payloads_dir) conf_file = create_conf_file(folders_created, remote_path) print("Download successful!") except (requests.ConnectionError, IOError): print("Download failed. If you would still like to download " "payload files, please consult our documentation about the" "'syntribos download' command or do so manually.") conf_file = create_conf_file(folders_created) else: conf_file = create_conf_file(folders_created) logging.disable(logging.NOTSET) print("\nSyntribos has been initialized!") print("Folders created:\n\t{0}".format("\n\t".join(folders_created))) print("Configuration file:\n\t{0}".format(conf_file)) print("\nYou'll need to edit your configuration file to specify the " "endpoint to test and any other configuration options you want.") print("\nBy default, syntribos does not ship with any template files, " "which are required for syntribos to run. However, we provide a\n " "'syntribos download' command to fetch template files remotely. " "Please see our documentation for this subcommand, or run\n " "'syntribos download --templates' to download our default set of " "OpenStack templates.") print(syntribos.SEP)
def run(cls): """Method sets up logger and decides on Syntribos control flow This is the method where control flow of Syntribos is decided based on the commands entered. Depending upon commands such as ```list_tests``` or ```run``` the respective method is called. """ global result cli.print_symbol() # If we are initializing, don't look for a default config file if "init" in sys.argv: cls.setup_config() else: cls.setup_config(use_file=True) try: if CONF.sub_command.name == "init": ENV.initialize_syntribos_env() exit(0) elif CONF.sub_command.name == "list_tests": cls.list_tests() exit(0) elif CONF.sub_command.name == "download": ENV.download_wrapper() exit(0) except AttributeError: print( _( "Not able to run the requested sub command, please check " "the debug logs for more information, exiting...")) exit(1) if not ENV.is_syntribos_initialized(): print(_("Syntribos was not initialized. Please run the 'init'" " command or set it up manually. See the README for" " more information about the installation process.")) exit(1) cls.setup_runtime_env() decorator = unittest.runner._WritelnDecorator(cls.output) result = syntribos.result.IssueTestResult(decorator, True, verbosity=1) cls.start_time = time.time() if CONF.sub_command.name == "run": list_of_tests = list( cls.get_tests(CONF.test_types, CONF.excluded_types)) elif CONF.sub_command.name == "dry_run": dry_run_output = {"failures": [], "successes": []} list_of_tests = list(cls.get_tests(dry_run=True)) print(_("\nRunning Tests...:")) templates_dir = CONF.syntribos.templates if templates_dir is None: print(_("Attempting to download templates from {}").format( CONF.remote.templates_uri)) templates_path = remotes.get(CONF.remote.templates_uri) try: templates_dir = ContentType("r", 0)(templates_path) except IOError: print(_("Not able to open `%s`; please verify path, " "exiting...") % templates_path) exit(1) print(_("\nPress Ctrl-C to pause or exit...\n")) meta_vars = None templates_dir = list(templates_dir) cls.meta_dir_dict = {} for file_path, file_content in templates_dir: if os.path.basename(file_path) == "meta.json": meta_path = os.path.dirname(file_path) try: cls.meta_dir_dict[meta_path] = json.loads(file_content) except Exception: print("Unable to parse %s, skipping..." % file_path) for file_path, req_str in templates_dir: if "meta.json" in file_path: continue meta_vars = cls.get_meta_vars(file_path) LOG = cls.get_logger(file_path) CONF.log_opt_values(LOG, logging.DEBUG) if not file_path.endswith(".template"): LOG.warning('file.....:%s (SKIPPED - not a .template file)', file_path) continue test_names = [t for (t, i) in list_of_tests] # noqa log_string = ''.join([ '\n{0}\nTEMPLATE FILE\n{0}\n'.format('-' * 12), 'file.......: {0}\n'.format(file_path), 'tests......: {0}\n'.format(test_names) ]) LOG.debug(log_string) print(syntribos.SEP) print("Template File...: {}".format(file_path)) print(syntribos.SEP) if CONF.sub_command.name == "run": cls.run_given_tests(list_of_tests, file_path, req_str, meta_vars) elif CONF.sub_command.name == "dry_run": cls.dry_run(list_of_tests, file_path, req_str, dry_run_output, meta_vars) if CONF.sub_command.name == "run": result.print_result(cls.start_time) cleanup.delete_temps() elif CONF.sub_command.name == "dry_run": cls.dry_run_report(dry_run_output)
def run(cls): """Method sets up logger and decides on Syntribos control flow This is the method where control flow of Syntribos is decided based on the commands entered. Depending upon commands such as ```list_tests``` or ```run``` the respective method is called. """ global result cli.print_symbol() # If we are initializing, don't look for a default config file if "init" in sys.argv: cls.setup_config() else: cls.setup_config(use_file=True) try: if CONF.sub_command.name == "init": ENV.initialize_syntribos_env() exit(0) elif CONF.sub_command.name == "list_tests": cls.list_tests() exit(0) elif CONF.sub_command.name == "download": ENV.download_wrapper() exit(0) except AttributeError: print( _( "Not able to run the requested sub command, please check " "the debug logs for more information, exiting...")) exit(1) if not ENV.is_syntribos_initialized(): print(_("Syntribos was not initialized. Please run the 'init'" " command or set it up manually. See the README for" " more information about the installation process.")) exit(1) cls.setup_runtime_env() decorator = unittest.runner._WritelnDecorator(cls.output) result = syntribos.result.IssueTestResult(decorator, True, verbosity=1) cls.start_time = time.time() if CONF.sub_command.name == "run": list_of_tests = list( cls.get_tests(CONF.test_types, CONF.excluded_types)) elif CONF.sub_command.name == "dry_run": dry_run_output = {"failures": [], "successes": []} list_of_tests = list(cls.get_tests(dry_run=True)) print(_("\nRunning Tests...:")) templates_dir = CONF.syntribos.templates if templates_dir is None: print(_("Attempting to download templates from {}").format( CONF.remote.templates_uri)) templates_path = remotes.get(CONF.remote.templates_uri) try: templates_dir = ContentType("r", 0)(templates_path) except IOError: print(_("Not able to open `%s`; please verify path, " "exiting...") % templates_path) exit(1) print(_("\nPress Ctrl-C to pause or exit...\n")) meta_vars = None templates_dir = list(templates_dir) cls.meta_dir_dict = {} for file_path, file_content in templates_dir: if os.path.basename(file_path) == "meta.json": meta_path = os.path.dirname(file_path) try: cls.meta_dir_dict[meta_path] = json.loads(file_content) except Exception: print("Unable to parse %s, skipping..." % file_path) for file_path, req_str in templates_dir: if "meta.json" in file_path: continue meta_vars = cls.get_meta_vars(file_path) LOG = cls.get_logger(file_path) CONF.log_opt_values(LOG, logging.DEBUG) if not file_path.endswith(".template"): LOG.warning( _LW('file.....:%s (SKIPPED - not a .template file)'), file_path) continue test_names = [t for (t, i) in list_of_tests] # noqa log_string = ''.join([ '\n{0}\nTEMPLATE FILE\n{0}\n'.format('-' * 12), 'file.......: {0}\n'.format(file_path), 'tests......: {0}\n'.format(test_names) ]) LOG.debug(log_string) print(syntribos.SEP) print("Template File...: {}".format(file_path)) print(syntribos.SEP) if CONF.sub_command.name == "run": cls.run_given_tests(list_of_tests, file_path, req_str, meta_vars) elif CONF.sub_command.name == "dry_run": cls.dry_run(list_of_tests, file_path, req_str, dry_run_output, meta_vars) if CONF.sub_command.name == "run": result.print_result(cls.start_time) cleanup.delete_temps() elif CONF.sub_command.name == "dry_run": cls.dry_run_report(dry_run_output)
def initialize_syntribos_env(): """Sets up payloads, config, etc. for syntribos after installation.""" def prompt_yes(prompt): answer = input(prompt).lower() return answer == "yes" or answer == "y" def prompt_yes_or_quit(prompt): prompt = ("{0}\n\tType 'yes' or 'y' to continue, anything else " "to quit: ").format(prompt) if not prompt_yes(prompt): print("Aborting syntribos initialization.") exit(0) return True def prompt_yes_or_continue(prompt): prompt = ("{0}\n\tType 'yes' or 'y' to continue, anything else " "for more options: ").format(prompt) return prompt_yes(prompt) global FILE logging.basicConfig(level=logging.DEBUG) root_dir = get_venv_root() if is_venv() else get_user_home_root() force = CONF.sub_command.force custom_root = CONF.sub_command.custom_install_root or "" if custom_root: root_dir = custom_root elif CONF.sub_command.force: pass else: # Check if we've already initalized env so we don't overwrite anything if is_syntribos_initialized(): prompt = ("It seems syntribos has already been initialized.") prompt_yes_or_quit(prompt) else: if not CONF.sub_command.no_downloads: prompt = ("Syntribos has not been initialized. By default, " "this process will create a '.syntribos' folder\n " "with a barebones configuration file, and " "sub-folders for templates, debug logs, and\n " "payloads. Syntribos will also attempt to download " "payload files, which are necessary for fuzz\n " "tests to run. To avoid this behavior, run this " "command again with the --no_downloads flag") else: prompt = ("Syntribos has not been initialized. By default, " "this process will create a '.syntribos' folder\n " "with a barebones configuration file, and " "sub-folders for templates, debug logs, and\n " "payloads. Syntribos will not attempt to download " "any files during the initialization process.") prompt_yes_or_quit(prompt) if is_venv(): prompt = "Virtual environment detected. Install to {0}?".format( get_venv_root()) if prompt_yes_or_continue(prompt): root_dir = get_venv_root() else: prompt = ("Install to your home directory ({0})?").format( get_user_home_root()) if prompt_yes_or_quit(prompt): root_dir = get_user_home_root() folders_created = create_env_dirs(root_dir, force=force) # Grab payloads logging.disable(logging.ERROR) # Don't want to log to console here... payloads_dir = folders_created[1] if not CONF.sub_command.no_downloads: print( _("\nDownloading payload files to %s...") % payloads_dir) try: remote_path = remotes.get(CONF.remote.payloads_uri, payloads_dir) conf_file = create_conf_file(folders_created, remote_path) print(_("Download successful!")) except (requests.ConnectionError, IOError): print(_("Download failed. If you would still like to download" " payload files, please consult our documentation" " about the 'syntribos download' command or do so" " manually.")) conf_file = create_conf_file(folders_created) else: conf_file = create_conf_file(folders_created) logging.disable(logging.NOTSET) print(_("\nSyntribos has been initialized!")) print( _("Folders created:\n\t%s") % "\n\t".join(folders_created)) print(_("Configuration file:\n\t%s") % conf_file) print(_( "\nYou'll need to edit your configuration file to specify the " "endpoint to test and any other configuration options you want.")) print(_( "\nBy default, syntribos does not ship with any template files, " "which are required for syntribos to run. However, we provide a\n " "'syntribos download' command to fetch template files remotely. " "Please see our documentation for this subcommand, or run\n " "'syntribos download --templates' to download our default set of " "OpenStack templates.")) print(syntribos.SEP)