def test_set_config_basic(set_vars_mock, conf_get_mock): set_vars_mock.return_value = None conf_get_mock.return_value = None Config() assert conf_get_mock.call_count == 53
def read_agent_info(): json_file_path = Config().agent_json try: if os.path.isfile(json_file_path): with open(json_file_path, 'r') as json_file: try: data = json.load(json_file) except json.decoder.JSONDecodeError: data = {} json_file.close() else: data = {} if 'fortify_build_id' not in data: data['fortify_build_id'] = None if 'git_url' not in data: data['git_url'] = None if 'fortify_pv_url' not in data: data['fortify_pv_url'] = None if 'git_emails' not in data: data['git_emails'] = None AgentVerifier(json_file_path) return data except json.decoder.JSONDecodeError: Logger.console.error("Error reading from agent.json") exit(1)
def test_set_path_install_success(set_config_mock, set_vars_mock): set_vars_mock.return_value = None set_config_mock.return_value = None result = Config().set_path(install='/test/install') assert set_vars_mock.call_count == 1 assert set_config_mock.call_count == 1 assert result == 1
def test_set_path_dir_success(makedirs_mock, set_config_mock, set_vars_mock): set_vars_mock.return_value = None set_config_mock.return_value = None result = Config().set_path(install='/test/install', dir_path='test_dir') assert makedirs_mock.call_count == 1 assert result == '/test/install/test_dir'
def write_secret(self, overwrite=False): secret_path = Config().secret if self.secret_exists() and overwrite: os.chmod(secret_path, 0o200) key = Fernet.generate_key() with open(secret_path, 'w') as secret_file: secret_file.write(key.decode()) os.chmod(secret_path, 0o400) print("New secret has been set.")
def __read_fernet_secret__(self): self.verify_secret() try: with open(Config().secret, 'r') as secret_file: fernet_key = secret_file.readline().strip() return fernet_key except IOError: Logger.console.error("Error retrieving Fernet key.") sys.exit(1)
def test_set_path_file_success(open_mock, makedirs_mock, set_config_mock, set_vars_mock): set_vars_mock.return_value = None set_config_mock.return_value = None result = Config().set_path(install='/test/install', file_name='test.file') assert makedirs_mock.call_count == 1 assert open_mock.call_count == 1 assert result == '/test/install/test.file'
def __get_webinspect_settings__(self): Logger.app.debug("Getting webinspect settings from config file") webinspect_dict = {} wb_config = Config() webinspect_setting = wb_config.config try: config.read(webinspect_setting) endpoints = [] sizes = [] endpoint = re.compile('endpoint_\d*') size = re.compile('size_') for option in config.items('webinspect'): if endpoint.match(option[0]): endpoints.append([option[0], option[1]]) elif size.match(option[0]): sizes.append([option[0], option[1]]) webinspect_dict['git'] = wb_config.conf_get( 'webinspect', 'git_repo') webinspect_dict['default_size'] = wb_config.conf_get( 'webinspect', 'default_size') webinspect_dict['endpoints'] = [[ endpoint[1].split('|')[0], endpoint[1].split('|')[1] ] for endpoint in endpoints] webinspect_dict['size_list'] = sizes webinspect_dict['mapped_policies'] = [[ option, config.get('webinspect_policy', option) ] for option in config.options('webinspect_policy')] except (configparser.NoOptionError, CalledProcessError) as e: Logger.app.error("{} has incorrect or missing values {}".format( webinspect_setting, e)) except configparser.Error as e: Logger.app.error("Error reading webinspect settings {} {}".format( webinspect_setting, e)) Logger.app.debug("Initializing webinspect settings from config.ini") return webinspect_dict
def test_set_path_exists(open_mock, makedirs_mock, exist_mock, set_config_mock, set_vars_mock): set_vars_mock.return_value = None set_config_mock.return_value = None exist_mock.return_value = True result = Config().set_path(install='/test/install', dir_path='test_dir') assert exist_mock.call_count == 1 assert makedirs_mock.call_count == 0 assert result == '/test/install/test_dir'
def test_conf_get_success(get_mock, read_mock, set_config_mock, set_vars_mock): set_vars_mock.return_value = None set_config_mock.return_value = None read_mock.return_value = True get_mock.return_value = 'new_test_value' result = Config().conf_get('test_section', 'test_option', 'test_value') assert read_mock.call_count == 1 assert get_mock.call_count == 1 assert result == 'new_test_value'
def test_set_path_file_exception(open_mock, makedirs_mock, set_config_mock, set_vars_mock): set_vars_mock.return_value = None set_config_mock.return_value = None e = IOError("Test Error") open_mock.side_effect = e result = Config().set_path(install='/test/install', file_name='test.file') assert makedirs_mock.call_count == 1 assert open_mock.call_count == 1 assert result == 1
def __init__(self): config_file = Config().config try: config.read(config_file) self.api_key = config.get("threadfix", "api_key") self.host = config.get("threadfix", "host") if len(self.host) and self.host[-1] != '/': self.host = self.host + '/' except (configparser.NoOptionError, CalledProcessError) as noe: Logger.app.error("{} has incorrect or missing values {}".format( config_file, noe)) except (configparser.Error) as e: Logger.app.error("Error reading {} {}".format(config_file, e))
def test_conf_get_option_exec(open_mock, write_mock, set_mock, read_mock, set_config_mock, set_vars_mock): set_vars_mock.return_value = None set_config_mock.return_value = None e = configparser.NoOptionError("Test Error", "Error Section") read_mock.side_effect = e result = Config().conf_get('test_section', 'test_option', 'test_value') assert read_mock.call_count == 1 assert set_mock.call_count == 1 assert open_mock.call_count == 1 assert write_mock.call_count == 1 assert result == 'test_value'
def test_config_init_variables(set_vars_mock, set_config_mock): set_vars_mock.return_value = None set_config_mock.return_value = None test_obj = Config() assert os.path.exists(test_obj.home) assert test_obj.install is None assert test_obj.config is None assert test_obj.etc is None assert test_obj.git is None assert test_obj.log is None assert test_obj.agent_json is None assert test_obj.secret is None assert set_config_mock.call_count == 1
def __read_agent_settings__(self): settings_file = Config().config try: config.read(settings_file) self.smtp_host = config.get("agent_emailer", "smtp_host") self.smtp_port = config.get("agent_emailer", "smtp_port") self.from_address = config.get("agent_emailer", "from_address") self.email_template = config.get("agent_emailer", "email_template") self.default_to_address = config.get("agent_emailer", "default_to_address") self.chatroom = config.get("agent_emailer", "chatroom") except (configparser.NoOptionError, CalledProcessError) as noe: Logger.console.error("{} has incorrect or missing values {}".format(settings_file, noe)) except configparser.Error as e: Logger.app.error("Error reading {} {}".format(settings_file, e))
def parse_emailer_settings(self): emailer_dict = {} config.read(Config().config) try: emailer_dict['smtp_host'] = config.get('emailer', 'smtp_host') emailer_dict['smtp_port'] = config.get('emailer', 'smtp_port') emailer_dict['from_address'] = config.get('emailer', 'from_address') emailer_dict['to_address'] = config.get('emailer', 'to_address') emailer_dict['email_template'] = config.get('emailer', 'email_template') except configparser.NoOptionError: Logger.console.error("{} has incorrect or missing values!".format(self.config)) Logger.console.info("Your scan email notifier is not configured: {}".format(self.config)) return emailer_dict
def get_cert_proxy(self): path = Config().cert api = webinspectapi.WebInspectApi(self.host, verify_ssl=False) response = api.cert_proxy() if response.success: try: with open(path, 'wb') as f: f.write(response.data) Logger.app.info( 'Cert has downloaded to\t:\t{}'.format(path)) except UnboundLocalError as e: Logger.app.error('Error saving cert locally {}'.format(e)) else: Logger.app.error('Unable to retrieve cert.\n ERROR: {} '.format( response.message))
def __init__(self): config_file = Config().config try: config.read(config_file) self.ssc_url = config.get("fortify", "ssc_url") self.project_template = config.get("fortify", "project_template") self.application_name = config.get("fortify", "application_name") secret_client = SecretClient() self.username = secret_client.get('fortify', 'username') self.password = secret_client.get('fortify', 'password') except (configparser.NoOptionError, CalledProcessError) as noe: Logger.app.error("{} has incorrect or missing values {}".format( config_file, noe)) except configparser.Error as e: Logger.app.error("Error reading {} {}".format(config_file, e))
def get_cert_proxy(self): path = Config().cert api = webinspectapi.WebInspectApi(self.host, verify_ssl=False, username=self.username, password=self.password) response = api.cert_proxy() if response.response_code == 401: Logger.app.critical("An Authorization Error occured.") exit(1) if response.success: try: with open(path, 'wb') as f: f.write(response.data) Logger.app.info('Cert has downloaded to\t:\t{}'.format(path)) except UnboundLocalError as e: Logger.app.error('Error saving cert locally {}'.format(e)) else: Logger.app.error('Unable to retrieve cert.\n ERROR: {} '.format(response.message))
def write_agent_info(name, value): json_file_path = Config().agent_json try: if os.path.isfile(json_file_path): with open(json_file_path, 'r') as json_file: try: data = json.load(json_file) except json.decoder.JSONDecodeError: data = {} json_file.close() else: data = {} data[name] = value with open(json_file_path, 'w') as json_file: json.dump(data, json_file) except json.decoder.JSONDecodeError: Logger.console.error("Error writing {} to agent.json".format(name)) exit(1)
def __init__(self): config_file = Config().config try: config.read(config_file) self.authenticate = config.get("webinspect", "authenticate") if self.authenticate.lower() == 'true': self.authenticate = True else: self.authenticate = False secret_client = SecretClient() self.username = secret_client.get('webinspect', 'username') self.password = secret_client.get('webinspect', 'password') except (configparser.NoOptionError, CalledProcessError) as noe: Logger.app.error("{} has incorrect or missing values {}".format( config_file, noe)) except configparser.Error as e: Logger.app.error("Error reading {} {}".format(config_file, e))
def fetch_webinspect_configs(self, options): config_helper = Config() etc_dir = config_helper.etc git_dir = os.path.join(config_helper.git, '.git') try: if options['settings'] == 'Default': Logger.app.debug("Default settings were used") elif os.path.exists(git_dir): Logger.app.info( "Updating your WebInspect configurations from {}".format( etc_dir)) check_output(['git', 'init', etc_dir]) check_output([ 'git', '--git-dir=' + git_dir, '--work-tree=' + str(config_helper.git), 'reset', '--hard' ]) check_output([ 'git', '--git-dir=' + git_dir, '--work-tree=' + str(config_helper.git), 'pull', '--rebase' ]) sys.stdout.flush() elif not os.path.exists(git_dir): Logger.app.info( "Cloning your specified WebInspect configurations to {}". format(config_helper.git)) check_output( ['git', 'clone', self.webinspect_git, config_helper.git]) else: Logger.app.error( "No GIT Repo was declared in your config.ini, therefore nothing will be cloned!" ) except (CalledProcessError, AttributeError) as e: logexceptionhelper.LogWebInspectConfigIssue(e) raise except GitCommandError as e: logexceptionhelper.LogGitAccessError(self.webinspect_git, e) raise Exception(logexceptionhelper.fetch_webinspect_configs) except IndexError as e: logexceptionhelper.LogConfigFileUnavailable(e) raise Exception(logexceptionhelper.fetch_webinspect_configs) Logger.app.debug("Completed webinspect config fetch")
def __init__(self): self.fernet_key = self.__read_fernet_secret__() self.config_file = Config().config
def secret_exists(self): return os.path.isfile(Config().secret)
def __init__(self, agent_url=None): self.upload_log = UploadJSON(Config().agent_json) self.agent_url = agent_url if not agent_url: self.agent_url = self.read_config()
def read_config(self): config.read(Config().config) return config.get("agent", "webbreaker_agent")
def get_token(self): config.read(Config().config) return config.get("git", "token")
#!/usr/bin/env python # -*-coding:utf-8-*- import logging.config import logging import datetime import sys import os from webbreaker.confighelper import Config LOG_PATH = Config().log FORMATTER = logging.Formatter('%(message)s') DATETIME_SUFFIX = datetime.datetime.now().strftime("%m-%d-%Y") APP_LOG = os.path.abspath( os.path.join(LOG_PATH, 'webbreaker-' + DATETIME_SUFFIX + '.log')) DEBUG_LOG = os.path.abspath( os.path.join(LOG_PATH, 'webbreaker-debug-' + DATETIME_SUFFIX + '.log')) STOUT_LOG = os.path.abspath( os.path.join(LOG_PATH, 'webbreaker-out' + DATETIME_SUFFIX + '.log')) def singleton(cls): instances = {} def get_instance(): if cls not in instances: instances[cls] = cls() return instances[cls] return get_instance()
def parse_webinspect_options(self, options): webinspect_dir = Config().git webinspect_dict = {} # Trim .xml options['settings'] = self.trim_ext(options['settings']) # Trim .webmacro options['upload_webmacros'] = self.trim_ext( options['upload_webmacros']) options['workflow_macros'] = self.trim_ext(options['workflow_macros']) options['login_macro'] = self.trim_ext(options['login_macro']) # Trim .policy options['upload_policy'] = self.trim_ext(options['upload_policy']) # Trim .policy options['scan_policy'] = self.trim_ext(options['scan_policy']) # Trim .xml options['upload_settings'] = self.trim_ext(options['upload_settings']) if not options['scan_name']: try: if runenv == "jenkins": if "/" in os.getenv("JOB_NAME"): options['scan_name'] = os.getenv("BUILD_TAG") else: options['scan_name'] = os.getenv("JOB_NAME") else: options['scan_name'] = "webinspect" + "-" + "".join( random.choice(string.ascii_uppercase + string.digits) for _ in range(5)) except AttributeError as e: Logger.app.error("The {0} is unable to be created! {1}".format( options['scan_name'], e)) if options['upload_settings']: if os.path.isfile(options['upload_settings'] + '.xml'): options[ 'upload_settings'] = options['upload_settings'] + '.xml' if os.path.isfile(options['upload_settings']): options['upload_scan_settings'] = options['upload_settings'] else: try: options['upload_scan_settings'] = os.path.join( webinspect_dir, 'settings', options['upload_settings'] + '.xml') except (AttributeError, TypeError) as e: Logger.app.error( "The {0} is unable to be assigned! {1}".format( options['upload_settings'], e)) else: if os.path.isfile(options['settings']): options['settings'] = options['settings'] + '.xml' if not os.path.isfile( options['settings']) and options['settings'] != 'Default': options['upload_settings'] = os.path.join( webinspect_dir, 'settings', options['settings'] + '.xml') elif options['settings'] == 'Default': # All WebInspect servers come with a Default.xml settings file, no need to upload it options['upload_settings'] = None else: options['upload_settings'] = options['settings'] # if login macro has been specified, ensure it's uploaded. if options['login_macro']: if options['upload_webmacros']: # add macro to existing list. options['upload_webmacros'].append(options['login_macro']) else: # add macro to new list options['upload_webmacros'] = [] options['upload_webmacros'].append(options['login_macro']) # if workflow macros have been provided, ensure they are uploaded if options['workflow_macros']: if options['upload_webmacros']: # add macros to existing list options['upload_webmacros'].extend(options['workflow_macros']) else: # add macro to new list options['upload_webmacros'] = list(options['workflow_macros']) if options['upload_webmacros']: try: # trying to be clever, remove any duplicates from our upload list options['upload_webmacros'] = list( set(options['upload_webmacros'])) corrected_paths = [] for webmacro in options['upload_webmacros']: if os.path.isfile(webmacro + '.webmacro'): webmacro = webmacro + '.webmacro' if not os.path.isfile(webmacro): corrected_paths.append( os.path.join(webinspect_dir, 'webmacros', webmacro + '.webmacro')) else: corrected_paths.append(webmacro) options['upload_webmacros'] = corrected_paths except (AttributeError, TypeError) as e: Logger.app.error( "The {0} is unable to be assigned! {1}".format( options['upload_webmacros'], e)) # if upload_policy provided explicitly, follow that. otherwise, default to scan_policy if provided try: if options['upload_policy']: if os.path.isfile(options['upload_policy'] + '.policy'): options[ 'upload_policy'] = options['upload_policy'] + '.policy' if not os.path.isfile(options['upload_policy']): options['upload_policy'] = os.path.join( webinspect_dir, 'policies', options['upload_policy'] + '.policy') elif options['scan_policy']: if os.path.isfile(options['scan_policy'] + '.policy'): options['scan_policy'] = options['scan_policy'] + '.policy' if not os.path.isfile(options['scan_policy']): options['upload_policy'] = os.path.join( webinspect_dir, 'policies', options['scan_policy'] + '.policy') else: options['upload_policy'] = options['scan_policy'] except TypeError as e: Logger.app.error( "There was an error with the policy provided from --scan_policy option! " .format(e)) # Determine the targets specified in a settings file try: if options['upload_settings']: targets = self.__getScanTargets__(options['upload_settings']) else: targets = None except NameError as e: Logger.app.error("The setting file does not exist: {}".format(e)) # Unless explicitly stated --allowed_hosts by default will use all values from --start_urls if not options['allowed_hosts']: options['allowed_hosts'] = options['start_urls'] try: webinspect_dict['webinspect_settings'] = options['settings'] webinspect_dict['webinspect_scan_name'] = options['scan_name'] webinspect_dict['webinspect_upload_settings'] = options[ 'upload_settings'] webinspect_dict['webinspect_upload_policy'] = options[ 'upload_policy'] webinspect_dict['webinspect_upload_webmacros'] = options[ 'upload_webmacros'] webinspect_dict['webinspect_overrides_scan_mode'] = options[ 'scan_mode'] webinspect_dict['webinspect_overrides_scan_scope'] = options[ 'scan_scope'] webinspect_dict['webinspect_overrides_login_macro'] = options[ 'login_macro'] webinspect_dict['webinspect_overrides_scan_policy'] = options[ 'scan_policy'] webinspect_dict['webinspect_overrides_scan_start'] = options[ 'scan_start'] webinspect_dict['webinspect_overrides_start_urls'] = options[ 'start_urls'] webinspect_dict['webinspect_scan_targets'] = targets webinspect_dict['webinspect_workflow_macros'] = options[ 'workflow_macros'] webinspect_dict['webinspect_allowed_hosts'] = options[ 'allowed_hosts'] webinspect_dict['webinspect_scan_size'] = 'size_' + options[ 'size'] if options['size'] else self.default_size webinspect_dict['fortify_user'] = options['fortify_user'] except argparse.ArgumentError as e: Logger.app.error( "There was an error in the options provided!: ".format(e)) Logger.app.debug("Completed webinspect settings parse") return webinspect_dict