示例#1
0
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
示例#2
0
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)
示例#3
0
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
示例#4
0
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'
示例#5
0
 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.")
示例#6
0
 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)
示例#7
0
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'
示例#8
0
    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
示例#9
0
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'
示例#10
0
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'
示例#11
0
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
示例#12
0
    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))
示例#13
0
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'
示例#14
0
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
示例#15
0
    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))
示例#16
0
    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
示例#17
0
    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))
示例#18
0
    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))
示例#19
0
    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))
示例#20
0
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)
示例#21
0
    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))
示例#22
0
    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")
示例#23
0
 def __init__(self):
     self.fernet_key = self.__read_fernet_secret__()
     self.config_file = Config().config
示例#24
0
 def secret_exists(self):
     return os.path.isfile(Config().secret)
示例#25
0
 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()
示例#26
0
 def read_config(self):
     config.read(Config().config)
     return config.get("agent", "webbreaker_agent")
示例#27
0
 def get_token(self):
     config.read(Config().config)
     return config.get("git", "token")
示例#28
0
#!/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()
示例#29
0
    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