Ejemplo n.º 1
0
def fetch_sensitive_data(session_key, key, app_name=None):
    """
    :param session_key: A raw system auth token
    :param key: the string key to fetch the sensitive data for
    :param app_name: Optional name of splunk app
    :return: string representation of the secret
    """
    base_uri = rest.makeSplunkdUri()
    if app_name:
        uri = '{}servicesNS/nobody/{}/storage/passwords/{}'.format(base_uri, app_name, key)
    else:
        uri = '%s/services/storage/passwords/%s' % (base_uri, key)

    params = {
        'output_mode': 'json'
    }

    r, content = rest.simpleRequest(
        uri,
        sessionKey=session_key,
        getargs=params,
        method='GET',
        raiseAllErrors=True
    )

    parsed = json.loads(content)
    clear_password = parsed['entry'][0]['content']['clear_password']
    return clear_password
Ejemplo n.º 2
0
 def handleList(self, confInfo):
     helper = KVStoreHelper(self.getSessionKey())
     uri = rest.makeSplunkdUri()
     content = helper.get_cluster_info(uri + 'servicesNS/nobody/splunk-checker/storage/collections/data/clusterinfo')
     # TODO: transform to confInfo
     for cluster_info in content:
         confInfo[cluster_info['cluster_id']]['cluster_info'] = json.dumps(cluster_info)
Ejemplo n.º 3
0
    def do_run(self, inputs):
        """
        The entry point for the modular input.

        :param inputs: The command line arguments used when running this modular input. See the parent method definition
                       for more details.
        """
        # noinspection PyBroadException
        try:
            if not modular_input_should_run(self.session_key, LOGGER):
                LOGGER.debug('The AR modular input will not run on this host.')
                return

            uri = rest.makeSplunkdUri()
            _wait_for_kvstore_to_start(uri=uri,
                                       session_key=self.session_key,
                                       timeout_seconds=30)

            task.react(self._run_initialization, [AsyncClientFactory(uri)])
        except SystemExit as e:
            if e.code != 0:
                LOGGER.exception(
                    'Exited AR modular input with non-zero exit_code=%d message=%s',
                    e.code, e.message)
            else:
                LOGGER.debug(
                    'Successfully ran the AR initialization modular input.')
        except Exception:
            LOGGER.exception(
                'Unhandled exception while running AR modular input.')
def get_all_secure_gateway_tokens(authtoken, user):
    """
    Returns all Splunk tokens
    :return: String
    """
    LOGGER.debug("Getting Splunk tokens")
    query_args = {
        'output_mode': 'json',
        'sort_key': 'claims.exp',
        'sort_dir': 'desc',
        'username': user
    }
    request_url = "{}services/authorization/tokens".format(
        rest.makeSplunkdUri())
    _, content = rest.simpleRequest(request_url,
                                    sessionKey=authtoken,
                                    method='GET',
                                    getargs=query_args,
                                    raiseAllErrors=True)

    all_tokens = json.loads(content)['entry']
    cloudgateway_tokens = [
        token for token in all_tokens
        if token['content']['claims']['aud'] == constants.CLOUDGATEWAY
        and token['content']['claims']['exp'] != 0
    ]
    return cloudgateway_tokens
Ejemplo n.º 5
0
def authenticate_splunk_credentials(username, password):
    """
    Checks whether a supplied username/password pair are valid Splunk credentials. Throws an error otherwise.

    :param username: User-supplied username
    :param password: User-supplied password
    :return: None
    """
    request_url = '{}/services/auth/login'.format(rest.makeSplunkdUri())
    body = {'username': username, 'password': password}
    response, c = rest.simpleRequest(request_url,
                                     postargs=body,
                                     rawResult=True)
    exception = requests.RequestException()
    exception.statusCode = response.status

    if response.status == 200:
        return

    elif response.status == 401:
        exception.msg = 'Error: Supplied username or password is incorrect'
    else:
        exception.msg = 'Error: unable to authenticate client'

    raise exception
Ejemplo n.º 6
0
    def handleCreate(self, confInfo):
        post_data = self.callerArgs.data
        cluster_id = post_data['cluster_id'][0]
        branch = post_data['branch'][0]
        build = post_data['build'][0]
        package_type = post_data['package_type'][0]

        # Use another subprocess to make the upgrade happen.
        _NEW_PYTHON_PATH = read_conf_item('cluster_upgrade', 'general',
                                          'pythonPath')
        _SPLUNK_PYTHON_PATH = os.environ['PYTHONPATH']

        os.environ['PYTHONPATH'] = _NEW_PYTHON_PATH
        my_process = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                  'upgrade_cluster.py')

        # Read cache build server info.
        _CACHE_BUILD_SERVER = read_conf_item('cluster_upgrade', 'general',
                                             'cacheBuildServer')

        # Pass the splunk python path as a argument of the subprocess.
        p = subprocess.Popen([
            os.environ['PYTHONPATH'], my_process, _SPLUNK_PYTHON_PATH,
            _CACHE_BUILD_SERVER,
            rest.makeSplunkdUri(),
            self.getSessionKey(), cluster_id, branch, build, package_type
        ],
                             stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)
        output = p.communicate()[0]
        logging.info(str(output))
        confInfo['upgrade']['progress'] = str(output)
def get_telemetry_uri():
    rest_uri = rest.makeSplunkdUri()
    return '%sservicesNS/%s/%s/telemetry-metric' % (
        rest_uri,
        NOBODY,
        SPACEBRIDGE_APP_NAME
    )
Ejemplo n.º 8
0
 def get_api_key_uri(self):
     """
     Helper method to get uri for snl's api key api
     :return: [string]
     """
     rest_uri = rest.makeSplunkdUri()
     return '%sservicesNS/nobody/snl/snl/api_key/backend_api_key?output_mode=json' % rest_uri
Ejemplo n.º 9
0
 def get_hostname_uri(self):
     """
     Helper method to get uri for snl's hostname api
     :return: [string]
     """
     rest_uri = rest.makeSplunkdUri()
     return '%sservicesNS/nobody/snl/snl/settings/backend_settings?output_mode=json' % rest_uri
    def __init__(self, uri=None, proxy=None, verify_ssl=True):
        if not uri:
            uri = rest.makeSplunkdUri()

        self.uri = uri
        super(AioServerInfoClient, self).__init__(proxy=proxy,
                                                  verify_ssl=verify_ssl)
Ejemplo n.º 11
0
 def async_get_shc_captain_info(self, auth_header):
     """
     Async api call to get /shcluster/captain/info
     """
     uri = '%s/services/shcluster/captain/info' % rest.makeSplunkdUri()
     return self.async_get_request(uri=uri,
                                   auth_header=auth_header,
                                   params={'output_mode': 'json'})
 def async_get_server_info(self, auth_header):
     """
     Async api call to get /server/info
     :param auth_header:
     :return:
     """
     uri = '%s/services/server/info' % rest.makeSplunkdUri()
     return self.async_get_request(uri=uri, auth_header=auth_header, params={'output_mode': 'json'})
async def get_telemetry_instance_id(async_client, auth_header):
    rest_uri = rest.makeSplunkdUri()
    instance_id_uri = "{}services/properties/telemetry/general/deploymentID".format(rest_uri)
    r = await async_client.async_get_request(instance_id_uri, auth_header=auth_header)
    if r.code != HTTPStatus.OK:
        error_text = await r.text()
        LOGGER.info("Could not get telemetry instance id with error={} and status={}".format(error_text, r.code))
    instance_id = await r.text()
    return instance_id
 def makeRequestURL(self):
     user, app = self.user_app()
     eid = (None if self.callerArgs.id is None else quote(
         self.callerArgs.id.encode("utf-8"), safe=""))
     actions = (admin.ACTION_EDIT, admin.ACTION_LIST, admin.ACTION_REMOVE)
     name = ((self.requestedAction in actions
              and self.callerArgs.id is not None) and ("/" + eid) or "")
     return (rest.makeSplunkdUri() + "servicesNS/" + user + "/" + app +
             "/data/inputs/" + self.dataInputName + name +
             "?output_mode=json&count=-1")
def get_all_collections(session_key, app_name=constants.SPACEBRIDGE_APP_NAME):
    uri = encode_whitespace(
        '{}/servicesNS/nobody/{}/storage/collections/config'.format(
            rest.makeSplunkdUri(), app_name))
    params = {'output_mode': 'json'}
    return rest.simpleRequest(uri,
                              sessionKey=session_key,
                              method='GET',
                              getargs=params,
                              raiseAllErrors=True)
Ejemplo n.º 16
0
 def makeRequestURL(self):
     user, app = self.user_app()
     eid = None if self.callerArgs.id is None \
         else quote(self.callerArgs.id.encode('utf-8'), safe='')
     actions = (admin.ACTION_EDIT, admin.ACTION_LIST, admin.ACTION_REMOVE)
     name = (self.requestedAction in actions
             and self.callerArgs.id is not None) and ('/' + eid) or ''
     return (rest.makeSplunkdUri() + 'servicesNS/' + user + '/' + app +
             '/data/inputs/' + self.dataInputName + name +
             '?output_mode=json&count=0')
Ejemplo n.º 17
0
async def do_trigger(alert_payload):
    auth_header = SplunkAuthHeader(alert_payload[SESSION_KEY])

    # Use default URI for alerts
    try:
        uri = rest.makeSplunkdUri()
    except Exception as e:
        LOGGER.exception("Failed to generate default URI")

    if not uri:
        return

    mtls_spacebridge_client = None
    mtls_enabled = config.get_mtls_enabled()
    if mtls_enabled:
        mtls_spacebridge_client = build_mtls_spacebridge_client(alert_payload[SESSION_KEY])

    async_client_factory = AsyncClientFactory(uri, spacebridge_client=mtls_spacebridge_client)
    async_kvstore_client = async_client_factory.kvstore_client()
    async_splunk_client = async_client_factory.splunk_client()
    async_spacebridge_client = async_client_factory.spacebridge_client()

    alert_sid = alert_payload[SEARCH_ID]
    preprocess_payload(alert_payload)

    # Default to empty string so urllib.quote doesn't fail if user doesn't exist
    user = alert_payload[RESULT].get(USER, '')
    request_context = RequestContext(auth_header=auth_header, is_alert=True, current_user=user)

    LOGGER.info("get_registered_devices alert_sid=%s", alert_sid)
    registered_devices = await get_registered_devices(request_context, async_kvstore_client, alert_payload)
    LOGGER.info("get_registered_devices ok alert_sid=%s", alert_sid)

    alert = await build_alert(request_context, alert_payload, async_splunk_client, async_kvstore_client)
    LOGGER.info("persist_alert alert_id=%s", alert_sid)
    response = persist_alert(alert, auth_header.session_token)
    LOGGER.info("persist_alert ok succeeded alert_id=%s", alert_sid)

    # If we get a proper response from KV Store, then we get the key of the stored alert
    # and create a (device_id, alert_id, timestamp) triplet for each device that should
    # receive the alert

    if response is not None and "_key" in response.keys():
        alert_id = response["_key"]
        alert.notification.alert_id = alert_id

        # Persisting (recipient device, alert id) pairs and sending push notifications happens simultaneously via async
        LOGGER.info("persist_recipient_devices alert_id=%s", alert_id)
        await persist_recipient_devices(request_context, alert_id, registered_devices, alert_payload,
                                        async_kvstore_client)
        LOGGER.info("persist_recipient_devices ok alert_id=%s", alert_id)
        LOGGER.info("send_push_notifications starting registered_devices=%s", len(registered_devices))
        await send_push_notifications(
            request_context, alert.notification, registered_devices, async_kvstore_client, async_spacebridge_client,
            async_splunk_client)
Ejemplo n.º 18
0
 def __init__(self):
     self.logger = log()
     self.session = requestsbak.Session()
     self.session.trust_env = False
     self.kvstoreUri = entity.buildEndpoint(
         entityClass=["storage", "collections", "data"],
         entityName="credentials",
         owner="nobody",
         namespace="SplunkAppForWazuh",
         hostPath=rest.makeSplunkdUri().strip("/"))
     self.sessionKey = splunk.getSessionKey()
Ejemplo n.º 19
0
def do_trigger(reactor, alert_payload):
    auth_header = SplunkAuthHeader(alert_payload[SESSION_KEY])

    # Use default URI for alerts
    try:
        uri = rest.makeSplunkdUri()
    except Exception as e:
        LOGGER.exception("Failed to generate default URI. {}".format(e))

    if not uri:
        return

    async_client_factory = AsyncClientFactory(uri)
    async_kvstore_client = async_client_factory.kvstore_client()
    async_splunk_client = async_client_factory.splunk_client()
    async_spacebridge_client = async_client_factory.spacebridge_client()

    alert_sid = alert_payload[SEARCH_ID]
    preprocess_payload(alert_payload)

    request_context = RequestContext(auth_header=auth_header, is_alert=True)

    LOGGER.info("get_registered_devices alert_sid=%s" % alert_sid)
    registered_devices = yield get_registered_devices(request_context,
                                                      async_kvstore_client,
                                                      alert_payload)
    LOGGER.info("get_registered_devices ok alert_sid=%s" % alert_sid)

    alert = yield build_alert(request_context, alert_payload,
                              async_splunk_client, async_kvstore_client)
    LOGGER.info("persist_alert alert_id=%s" % alert_sid)
    response = persist_alert(alert, auth_header.session_token)
    LOGGER.info("persist_alert ok succeeded alert_id=%s" % alert_sid)

    # If we get a proper response from KV Store, then we get the key of the stored alert
    # and create a (device_id, alert_id, timestamp) triplet for each device that should
    # receive the alert

    if response is not None and "_key" in response.keys():
        alert_id = response["_key"]
        alert.notification.alert_id = alert_id

        # Persisting (recipient device, alert id) pairs and sending push notifications happens simultaneously via async
        LOGGER.info("persist_recipient_devices alert_id=%s" % alert_id)
        persist_recipient_devices(request_context, alert_id,
                                  registered_devices, alert_payload,
                                  async_kvstore_client)
        LOGGER.info("persist_recipient_devices ok alert_id=%s" % alert_id)
        LOGGER.info("send_push_notifications starting registered_devices=%s" %
                    len(registered_devices))
        yield send_push_notifications(request_context, alert.notification,
                                      registered_devices, async_kvstore_client,
                                      async_spacebridge_client,
                                      async_splunk_client)
 def __init__(self,
              collection=None,
              session_key=None,
              app=constants.SPACEBRIDGE_APP_NAME,
              owner=NOBODY,
              timestamp_attribute_name='timestamp'):
     rest_uri = rest.makeSplunkdUri()
     path = f'servicesNS/{owner}/{app}/storage/collections/data/{collection}'
     self.uri = append_path_to_uri(rest_uri, path)
     self.session_key = session_key
     self.timestamp_attribute_name = timestamp_attribute_name
async def get_installation_environment(async_client, auth_header):
    rest_uri = rest.makeSplunkdUri()
    on_cloud_instance_uri = "{}services/properties/telemetry/general/onCloudInstance".format(rest_uri)
    r = await async_client.async_get_request(on_cloud_instance_uri, auth_header=auth_header)
    if r.code != HTTPStatus.OK:
        error_text = await r.text()
        LOGGER.info("Could not get telemetry instance id with error={} and status={}".format(error_text, r.code))
    installation_environment_response = await r.text()
    installation_environment = InstallationEnvironment.CLOUD \
        if installation_environment_response.lower().strip() == "true" \
        else InstallationEnvironment.ENTERPRISE
    return installation_environment
 def make_uri(self, endpoint, entry=None):
     user, app = self.user_app()
     endpoint = endpoint.strip("/ ")
     entry = "" if entry is None else "/" + quote(entry.strip("/"), safe="")
     uri = "{splunkd_uri}servicesNS/{user}/{app}/{endpoint}{entry}" "".format(
         splunkd_uri=rest.makeSplunkdUri(),
         user=user,
         app=app,
         endpoint=endpoint,
         entry=entry,
     )
     return uri
def get_uri(session_key):
    """
    Construct URI for REST API calls using the load balancer address or the Splunkd URI if not provided
    :param session_key:
    :return: URI string
    """
    uri = config.get_config(stanza=config.SETUP,
                            key=config.LOAD_BALANCER_ADDRESS,
                            default=rest.makeSplunkdUri())
    if not uri:
        raise GetConfigError(
            "Failed to get load balancer address from cloudgateway.conf")

    # If load balancer address is given, verify that it is correct
    if uri != rest.makeSplunkdUri():
        if not uri.endswith('/'):
            uri += '/'
        if not verify_load_balancer_address(uri, session_key):
            raise AddressVerificationError(
                "Failed to verify load balancer address={}".format(uri))
    return uri
Ejemplo n.º 24
0
 def __init__(self,
              collection=None,
              session_key=None,
              owner=NOBODY,
              timestamp_attribute_name='timestamp'):
     rest_uri = rest.makeSplunkdUri()
     self.uri = unicode(
         encode_whitespace(
             '{}servicesNS/{}/{}/storage/collections/data/{}'.format(
                 rest_uri, owner, constants.SPACEBRIDGE_APP_NAME,
                 collection)))
     self.session_key = session_key
     self.timestamp_attribute_name = timestamp_attribute_name
Ejemplo n.º 25
0
 def make_uri(self, endpoint, entry=None):
     user, app = self.user_app()
     endpoint = endpoint.strip('/ ')
     entry = '' if entry is None \
             else '/' + quote(entry.strip('/'), safe='')
     uri = '{splunkd_uri}servicesNS/{user}/{app}/{endpoint}{entry}' \
           ''.format(splunkd_uri=rest.makeSplunkdUri(),
                     user=user,
                     app=app,
                     endpoint=endpoint,
                     entry=entry
                     )
     return uri
Ejemplo n.º 26
0
    def handleList(self, confInfo):
        """
        List the progress of upgrading from kvstore.
        """
        helper = KVStoreHelper(self.getSessionKey())
        uri = rest.makeSplunkdUri()
        content = helper.get_upgrade_progress(
            uri +
            'servicesNS/nobody/splunk-checker/storage/collections/data/upgrade_progress'
        )

        for cluster_progress in content:
            confInfo[cluster_progress['cluster_id']][
                'upgrade_progress'] = json.dumps(cluster_progress)
Ejemplo n.º 27
0
    def handleEdit(self, confInfo):
        user, app = self.user_app()
        proxy_info = self.getProxyInfo(
            splunkdMgmtUri=rest.makeSplunkdUri(),
            sessionKey=self.getSessionKey(),
            user=user,
            app=app,
        )
        proxy_enabled = proxy_info.get("proxy_enabled", False)
        proxy_uri = util.get_proxy_uri(proxy_info if proxy_enabled else {})
        proxies = {"http": proxy_uri, "https": proxy_uri}
        try:
            url = self.callerArgs.data["splunk_poster_url"][0]
            for regex in self.allowedURLs:
                if re.match(regex, url):
                    break
            else:
                RH_Err.ctl(1104, msgx="Unsupported url to be posted")

            method = self.callerArgs.data["splunk_poster_method"][0]
            if method not in self.allowedMethods:
                RH_Err.ctl(1104, msgx="Unsupported method to be posted")

            payload = {
                key: val[0]
                for key, val in self.callerArgs.data.items()
                if key in self.retransmittedArgs
            }
            headers = {
                "Content-Type": "application/x-www-form-urlencoded",
            }

            resp = requests.request(  # nosemgrep: python.requests.best-practice.use-raise-for-status.use-raise-for-status  # noqa: E501
                method=method,
                url=url,
                headers=headers,
                data=urllib.parse.urlencode(payload),
                timeout=120,
                proxies=proxies,
                verify=True,
            )
            content = resp.json()
            if resp.status_code not in (200, 201):
                RH_Err.ctl(resp.status_code, msgx=content)

            for key, val in content.items():
                confInfo[self.callerArgs.id][key] = val
        except Exception as exc:
            RH_Err.ctl(1104, msgx=exc)
Ejemplo n.º 28
0
    def getDeploymentID(self, cookie):
        if not self.deploymentID:
            self.getToken(cookie)
            self.server_uri = rest.makeSplunkdUri()
            splunkd = Splunkd(token=self.token, server_uri=self.server_uri)

            telemetry_conf_service = TelemetryConfService(splunkd,
                                                          is_read_only=True)
            telemetry_conf_service.fetch()

            deployment_id_manager = DeploymentIdManager(
                splunkd, telemetry_conf_service=telemetry_conf_service)

            self.deploymentID = deployment_id_manager.get_deployment_id()
        return self.deploymentID
Ejemplo n.º 29
0
def update_sensitive_data(session_key, key, data):
    """
    :param session_key: A raw system auth token
    :param key: the string key to fetch the sensitive data for
    :param data: String data representing the secret
    :return:
    """
    LOGGER.debug("Updating sensitive data, key={}".format(key))
    base_uri = rest.makeSplunkdUri()
    uri = '{}servicesNS/nobody/{}/storage/passwords/{}'.format(
        base_uri, constants.SPACEBRIDGE_APP_NAME, key)

    form_data = {constants.PASSWORD: data}

    return _mutate_sensitive_data(session_key, uri, form_data)
Ejemplo n.º 30
0
 def __init__(self):
     """Constructor."""
     try:
         self.logger = log()
         self.session = requestsbak.Session()
         self.session.trust_env = False
         self.kvstoreUri = entity.buildEndpoint(
             entityClass=["storage", "collections", "data"],
             entityName="jobs",
             owner="nobody",
             namespace="SplunkAppForWazuh",
             hostPath=rest.makeSplunkdUri().strip("/")
         )
         self.sessionKey = splunk.getSessionKey()
     except Exception as e:
         self.logger.error("bin.jobs_queu: Error in queue module constructor: %s" % (e))