def __init__(self, session, config_path=None): reset_config(filepath=config_path) try: control_config() except ValueError as e: logger.error(e) raise e self.config_path = config_path self.host = config.get(Sections.SERVER, "host") self.api_port = config.get(Sections.SERVER, "api_port") self.websocket_port = config.get(Sections.SERVER, "websocket_port") self.workspace = config.get(Sections.SERVER, "workspace") self.agent_token = config[Sections.TOKENS].get("agent", None) self.agent_name = config.get(Sections.AGENT, "agent_name") self.session = session self.websocket = None self.websocket_token = None executors_list_str = config[Sections.AGENT].get("executors", []).split(",") if "" in executors_list_str: executors_list_str.remove("") self.executors = { executor_name: Executor(executor_name, config) for executor_name in executors_list_str } ssl_cert_path = config[Sections.SERVER].get("ssl_cert", None) self.ws_ssl_enabled = self.api_ssl_enabled = config[Sections.SERVER].get("ssl", "False").lower() in ["t", "true"] self.api_kwargs = {"ssl": ssl.create_default_context(cafile=ssl_cert_path)} if self.api_ssl_enabled and ssl_cert_path else {} self.ws_kwargs = {"ssl": ssl.create_default_context(cafile=ssl_cert_path)} if self.ws_ssl_enabled and ssl_cert_path else {} self.execution_id = None
def post_url(): host = config.get('server', 'host') port = config.get('server', 'api_port') return api_url( host, port, postfix= f"/_api/v2/ws/{config.get('server', 'workspace')}/bulk_create/")
def post_url(self): host = config.get("server", "host") port = config.get("server", "api_port") return api_url( host, port, postfix="/_api/v3/ws/" f"{self.workspace}/bulk_create", secure=self.api_ssl_enabled, )
def __init__(self, session, config_path=None): reset_config(filepath=config_path) try: verify() control_config() except ValueError as e: logger.error(e) raise e self.config_path = config_path self.host = config.get(Sections.SERVER, "host") self.api_port = config.get(Sections.SERVER, "api_port") self.websocket_port = config.get(Sections.SERVER, "websocket_port") self.agent_token = config[Sections.TOKENS].get( "agent", None) if Sections.TOKENS in config else None self.agent_name = config.get(Sections.AGENT, "agent_name") self.session = session self.websocket = None self.websocket_token = None self.workspaces = _parse_list(config.get(Sections.SERVER, "workspaces")) self.executors = { executor_name: Executor(executor_name, config) for executor_name in _parse_list(config[Sections.AGENT].get( "executors", "")) } self.ws_ssl_enabled = self.api_ssl_enabled = config[ Sections.SERVER].get("ssl", "False").lower() in [ "t", "true", ] ssl_cert_path = config[Sections.SERVER].get("ssl_cert", None) if not Path(ssl_cert_path).exists(): raise ValueError( f"SSL cert does not exist in path {ssl_cert_path}") self.api_kwargs: Dict[str, object] = ({ "ssl": ssl.create_default_context(cafile=ssl_cert_path) if "HTTPS_PROXY" not in os.environ else False } if self.api_ssl_enabled and ssl_cert_path else {}) if "HTTPS_PROXY" in os.environ: logger.info("HTTPS_PROXY is set; will not do SSL verify") ws_ssl_context = ssl.create_default_context() ws_ssl_context.check_hostname = False ws_ssl_context.verify_mode = ssl.CERT_NONE else: ws_ssl_context = ssl.create_default_context(cafile=ssl_cert_path) self.ws_kwargs = {"ssl": ws_ssl_context} if self.ws_ssl_enabled else {} self.execution_id = None self.executor_tasks: Dict[str, List[Task]] = { Dispatcher.TaskLabels.EXECUTOR: [], Dispatcher.TaskLabels.CONNECTION_CHECK: [], } self.sigterm_received = False
async def register(self): if self.agent_token is None: registration_token = self.agent_token = config.get( Sections.TOKENS, "registration") assert registration_token is not None, "The registration token is mandatory" token_registration_url = api_url( self.host, self.api_port, postfix=f"/_api/v2/ws/{self.workspace}/agent_registration/") logger.info(f"token_registration_url: {token_registration_url}") try: token_response = await self.session.post( token_registration_url, json={ 'token': registration_token, 'name': self.agent_name }) assert token_response.status == 201 token = await token_response.json() self.agent_token = token["token"] config.set(Sections.TOKENS, "agent", self.agent_token) save_config(self.config_path) except ClientResponseError as e: if e.status == 404: logger.info( f'404 HTTP ERROR received: Workspace "{self.workspace}" not found' ) return else: logger.info(f"Unexpected error: {e}") raise e self.websocket_token = await self.reset_websocket_token()
async def processing(self, line): try: loaded_json = json.loads(line) print(f"{Bcolors.OKBLUE}{line}{Bcolors.ENDC}") headers = [("authorization", "agent {}".format(config.get("tokens", "agent")))] loaded_json["execution_id"] = self.execution_id res = await self.__session.post( self.post_url(), json=loaded_json, headers=headers, raise_for_status=False, ** self.api_kwargs ) if res.status == 201: logger.info("Data sent to bulk create") else: logger.error( "Invalid data supplied by the executor to the bulk create " "endpoint. Server responded: {} {}".format(res.status, await res.text()) ) except JSONDecodeError as e: logger.error("JSON Parsing error: {}".format(e)) print(f"{Bcolors.WARNING}JSON Parsing error: {e}{Bcolors.ENDC}")
def __init__(self, session, config_path=None): reset_config(filepath=config_path) self.control_config() self.config_path = config_path self.host = config.get(Sections.SERVER, "host") self.api_port = config.get(Sections.SERVER, "api_port") self.websocket_port = config.get(Sections.SERVER, "websocket_port") self.workspace = config.get(Sections.SERVER, "workspace") self.agent_token = config[Sections.TOKENS].get("agent", None) self.agent_name = config.get(Sections.AGENT, "agent_name") self.session = session self.websocket = None self.websocket_token = None self.executors = { executor_name: Executor(executor_name, config) for executor_name in config[Sections.AGENT].get("executors", []).split(",") }
def control_config(self): for section in self.__control_dict: for option in self.__control_dict[section]: if section not in config: err = f"Section {section} is an mandatory section in the config" # TODO "run config cmd" logger.error(err) raise ValueError(err) value = config.get( section, option) if option in config[section] else None self.__control_dict[section][option](option, value)
async def register(self): if self.agent_token is None: registration_token = self.agent_token = config.get(Sections.TOKENS, "registration") assert registration_token is not None, "The registration token is mandatory" token_registration_url = api_url(self.host, self.api_port, postfix=f"/_api/v2/ws/{self.workspace}/agent_registration/", secure=self.api_ssl_enabled) logger.info(f"token_registration_url: {token_registration_url}") try: token_response = await self.session.post(token_registration_url, json={'token': registration_token, 'name': self.agent_name}, **self.api_kwargs ) token = await token_response.json() self.agent_token = token["token"] config.set(Sections.TOKENS, "agent", self.agent_token) save_config(self.config_path) except ClientResponseError as e: if e.status == 404: logger.error(f'404 HTTP ERROR received: Workspace "{self.workspace}" not found') elif e.status == 401: logger.error("Invalid registration token, please reset and retry. If the error persist, you should " "try to edit the registration token with the wizard command `faraday-dispatcher " "config-wizard`") else: logger.info(f"Unexpected error: {e}") logger.debug(msg="Exception raised", exc_info=e) return try: self.websocket_token = await self.reset_websocket_token() logger.info("Registered successfully") except ClientResponseError as e: error_msg = "Invalid agent token, please reset and retry. If the error persist, you should remove " \ f"the agent token with the wizard command `faraday-dispatcher " \ f"config-wizard`" logger.error(error_msg) self.agent_token = None logger.debug(msg="Exception raised", exc_info=e) return
from faraday_agent_dispatcher.config import instance as config, reset_config, Sections,\ save_config, EXAMPLE_CONFIG_FILENAME from faraday_agent_dispatcher.utils.url_utils import api_url from tests.data.basic_executor import host_data, vuln_data from tests.utils.text_utils import fuzzy_string import os from pathlib import Path from requests import Session import subprocess import time reset_config(EXAMPLE_CONFIG_FILENAME) HOST = config.get(Sections.SERVER, "host") API_PORT = config.get(Sections.SERVER, "api_port") WS_PORT = config.get(Sections.SERVER, "websocket_port") WORKSPACE = fuzzy_string( 6).lower() # TODO FIX WHEN FARADAY ACCEPTS CAPITAL FIRST LETTER AGENT_NAME = fuzzy_string(6) EXECUTOR_NAME = fuzzy_string(6) USER = os.getenv("FARADAY_USER") EMAIL = os.getenv("FARADAY_EMAIL") PASS = os.getenv("FARADAY_PASSWORD") CONFIG_DIR = "./config_file.ini" LOGGER_DIR = "./logs" agent_ok_status_keys_set = {
def post_url(self): host = config.get('server', 'host') port = config.get('server', 'api_port') return api_url(host, port, postfix=f"/_api/v2/ws/{config.get('server', 'workspace')}/bulk_create/", secure=self.api_ssl_enabled)