class SubscriptionCleanUpModularInput(modular_input.ModularInput): title = 'Splunk Cloud Gateway Subscription Clean Up' description = 'Clean up expired subscriptions' app = 'Splunk App Cloud Gateway' name = 'splunkappcloudgateway' use_kvstore_checkpointer = False use_hec_event_writer = False logger = setup_logging(SPACEBRIDGE_APP_NAME + '.log', 'subscription_clean_up_modular_input.app') input_config_key = "subscription_clean_up_modular_input://default" config_key_cleanup_threashold_seconds = "cleanup_threshold_seconds" def do_run(self, input_config): """ Executes the modular input :param input_config: :return: """ if not modular_input_should_run(self.session_key, logger=self.logger): self.logger.debug("Modular input will not run on this node.") return self.logger.debug( "Running Subscription Clean Up modular input on search captain node" ) cleanup_time_seconds = input_config[self.input_config_key][ self.config_key_cleanup_threashold_seconds] subscription_clean_up = SubscriptionCleanUp(self.session_key, int(cleanup_time_seconds)) try: subscription_clean_up.run() except: self.logger.exception( "Failure encountered while running Subscription Clean Up")
class MetricsModularInput(modular_input.ModularInput): """ Modular input to periodically collect cloudgateway metrics """ title = 'Splunk Cloud Gateway Metrics Collector' description = 'Collects metrics for Splunk Cloud Gateway' app = 'Splunk App Cloud Gateway' name = 'splunkappcloudgateway' use_kvstore_checkpointer = False use_hec_event_writer = False logger = setup_logging(constants.SPACEBRIDGE_APP_NAME + '_metrics.log', 'cloudgateway_metrics.app') def do_run(self, input_config): """ Main entry path for input """ self.logger.info("Running cloud gateway metrics modular input") if not modular_input_should_run(self.session_key, logger=self.logger): self.logger.debug("Modular input will not run on this node.") return try: time.sleep(30) collector = SpacebridgeaAppMetricsCollector( self.logger, self.session_key) collector.run() except: self.logger.exception("Exception calculating cloudgateway metrics")
class DroneModeSubscriptionModularInput(modular_input.ModularInput): """ Main entry for processing Drone Mode Subscriptions """ title = 'Splunk Cloud Gateway Drone Mode Subscription Processor' description = ('Clean up expired subscriptions, and ' 'send data through Splunk Cloud Gateway send message api') app = 'Splunk App Cloud Gateway' name = 'splunkappcloudgateway' use_kvstore_checkpointer = False use_hec_event_writer = False logger = setup_logging( SPACEBRIDGE_APP_NAME + '_drone_mode_modular_input.log', 'drone_mode_modular_input.app') def do_run(self, input_config): """ This will spin up a drone mode subscription manager and begins the reactor loop :param input_config: :return: """ try: sodium_client = SodiumClient(self.logger.getChild('sodium_client')) encryption_context = SplunkEncryptionContext( self.session_key, SPACEBRIDGE_APP_NAME, sodium_client) self.logger.debug( "Running Drone Mode Subscription Manager modular input") # Fetch load balancer address if configured, otherwise use default URI try: uri = get_uri(self.session_key) self.logger.debug( "Successfully verified load_balancer_address=%s", uri) except Exception: self.logger.exception( "Failed to verify load_balancer_address.") if not uri: return subscription_manager = DroneModeSubscriptionManager( input_config=input_config, encryption_context=encryption_context, session_key=self.session_key, async_splunk_client=AsyncSplunkClient(uri), parent_process_monitor=ParentProcessMonitor(), cluster_monitor=ClusterMonitor( self.logger, interval=config.get_cluster_monitor_interval())) subscription_manager.run() except Exception as e: self.logger.exception( 'An error occurred running the drone mode subscription modular input' ) raise e
class DeviceRolesMappingModularInput(modular_input.ModularInput): """ """ title = 'Splunk Secure Gateway Role Based Notification Manager' description = 'Used for sending mobile alerts to users by role' app = 'Splunk Secure Gateway' name = 'splunk_secure_gateway' use_kvstore_checkpointer = False use_hec_event_writer = False logger = setup_logging(SPACEBRIDGE_APP_NAME + '_modular_input.log', 'ssg_device_role_mapping.app') input_config_key = "ssg_device_role_modular_input://default" def do_run(self, input_config): """ This will update the Device Role Mapping table in KV Store with the new mapping of a device to role :param input_config: :return: """ if not modular_input_should_run(self.session_key, logger=self.logger): self.logger.debug("Modular input will not run on this node.") return # Use default URI for Device Role Mapping try: uri = rest.makeSplunkdUri() except Exception as e: self.logger.exception( "Failed to generate default URI. {}".format(e)) if not uri: return try: async_client_factory = AsyncClientFactory(uri) kvstore_client = async_client_factory.kvstore_client() splunk_client = async_client_factory.splunk_client() asyncio.run(update(self.session_key, kvstore_client, splunk_client)) except SystemExit as e: if e.code == 0: self.logger.debug( "device to role mapping updated successfully with code={}". format(str(e.code))) else: self.logger.error( "device to role mapping update failed with error={}". format(str(e))) except: self.logger.exception( "Unexpected exception in device to role mapping")
class AlertsTTLModularInput(modular_input.ModularInput): title = 'Splunk Cloud Gateway Mobile Alerts TTL' description = 'Cleans up storage of old mobile alerts' app = 'Splunk App Cloud Gateway' name = 'splunkappcloudgateway' use_kvstore_checkpointer = False use_hec_event_writer = False logger = setup_logging(constants.SPACEBRIDGE_APP_NAME + '.log', 'alerts_ttl_modular_input.app') ttl_days = "ttl_days" input_config_key = "alerts_ttl_modular_input://default" def construct_ttl_list(self, ttl_days): return [] def do_run(self, input_config): """ Executes the modular input using the input config which specifies TTL for alerts """ if not modular_input_should_run(self.session_key, logger=self.logger): self.logger.debug("Modular input will not run on this node.") return self.logger.info("Running Alerts TTL modular input with input=%s" % str(input_config)) alerts_ttl_utility = AlertsTtlUtility( self.session_key, float(input_config[self.input_config_key][self.ttl_days])) alerts_ttl_utility.run() def extra_arguments(self): """ Override extra_arguments list for modular_input scheme :return: """ return [{ 'name': 'ttl_days', 'title': 'TTL in Days', 'description': 'Alert ttl specified in days' }]
class RegisteredUsersListModularInput(modular_input.ModularInput): title = 'Splunk Secure Gateway Registered Users List' description = 'Sync the list of registered gateway users' app = 'Splunk Secure Gateway' name = 'splunk_secure_gateway' use_kvstore_checkpointer = False use_hec_event_writer = False logger = setup_logging(SPACEBRIDGE_APP_NAME + '.log', 'ssg_registered_users_list_modular_input.app') input_config_key = "ssg_registered_users_list_modular_input://default" def do_run(self, input_config): """ Executes the modular input :param input_config: :return: """ if not modular_input_should_run(self.session_key, logger=self.logger): self.logger.debug("Modular input will not run on this node.") return if get_splunk_auth_type(authtoken=self.session_key) == constants.SAML: self.logger.debug( "Registered Users List modular input should not run on SAML environment" ) return self.logger.info( "Running Registered Users List modular input on search captain node" ) registered_users_sync = RegisteredUsersSync(self.session_key) try: registered_users_sync.run() except: self.logger.exception( "Failure encountered while running Registered Users List sync")
warnings.filterwarnings('ignore', '.*service_identity.*', UserWarning) from spacebridgeapp.util import py23 import fileinput import sys from cloudgateway.device import EncryptionKeys from cloudgateway.splunk.encryption import EncryptionContext from cloudgateway.private.sodium_client import SodiumClient from spacebridgeapp.logging import setup_logging from spacebridgeapp.rest.clients.async_client_factory import AsyncClientFactory from spacebridgeapp.subscriptions.subscription_processor import process_pubsub_subscription from spacebridgeapp.util.constants import SPACEBRIDGE_APP_NAME from twisted.internet import reactor, task, defer LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + "_subscription_subprocess.log", "subscription_subprocess") @defer.inlineCallbacks def _run(job_contexts, sodium_client): errors = [] LOGGER.debug("Running search process, searches=%s", len(job_contexts)) for job in job_contexts: LOGGER.debug("Processing search job. search_key=%s", job.search_context.search.key()) encryption_keys = EncryptionKeys.from_json(job.encryption_keys) encryption_context = EncryptionContext(encryption_keys, sodium_client) async_client_factory = AsyncClientFactory(job.splunk_uri) try:
from cloudgateway.auth import SimpleUserCredentials from cloudgateway.splunk.auth import SplunkJWTCredentials, SplunkAuthHeader from cloudgateway.splunk.encryption import SplunkEncryptionContext from spacebridgeapp.logging import setup_logging from spacebridgeapp.util import constants from spacebridgeapp.util.config import cloudgateway_config as config from spacebridgeapp.rest.base_endpoint import BaseRestHandler from spacebridgeapp.rest.services.kvstore_service import KVStoreCollectionAccessObject as KvStore from spacebridgeapp.rest.services.splunk_service import authenticate_splunk_credentials from spacebridgeapp.rest.config.app import retrieve_state_of_app from spacebridgeapp.rest.util.helper import extract_parameter from spacebridgeapp.rest.config.deployment_info import get_deployment_friendly_name from spacebridgeapp.request.request_processor import BasicAuthHeader LOGGER = setup_logging(constants.SPACEBRIDGE_APP_NAME + ".log", "rest_registration_confirmation") BODY_LABEL = 'body' QUERY_LABEL = 'query' AUTH_CODE_LABEL = 'auth_code' USERNAME_LABEL = 'username' PASSWORD_LABEL = 'password' DEVICE_NAME_LABEL = 'device_name' DEVICE_ID_LABEL = 'device_id' DEVICE_TYPE_LABEL = 'device_type' KVSTORE_TEMPORARY_ID_LABEL = 'temp_key' DEVICE_REGISTRATION_ATTRS = ['device_name', 'device_type', 'device_id', 'app_id'] DEVICE_PUBLIC_KEYS_ATTRS = ['encrypt_public_key', 'sign_public_key']
from splunk.clilib.bundle_paths import make_splunkhome_path sys.path.append( make_splunkhome_path(['etc', 'apps', 'splunk_secure_gateway', 'bin'])) from spacebridgeapp.util import py23 from spacebridgeapp.logging import setup_logging from spacebridgeapp.util import constants from spacebridgeapp.rest.base_endpoint import BaseRestHandler from spacebridgeapp.rest.util.helper import extract_parameter from spacebridgeapp.rest.util import errors as Errors from spacebridgeapp.rest.services.qr_code_service import generate_qr_code from spacebridgeapp.rest.services.qr_code_service import get_valid_file_types from spacebridgeapp.dashboard.dashboard_helpers import shorten_dashboard_id_from_url LOGGER = setup_logging(constants.SPACEBRIDGE_APP_NAME + ".log", "rest_qr_code_for_dashboard") DASHBOARD_ID_LABEL = 'dashboard_id' QR_CODE_DASHBOARD_VERSION = '1' class QrCodeForDashboard(BaseRestHandler, PersistentServerConnectionApplication): """ Main class for handling the devices_user endpoint. Subclasses the spacebridge_app BaseRestHandler. """ def __init__(self, command_line, command_arg): BaseRestHandler.__init__(self) def get(self, request):
from splunk.clilib.bundle_paths import make_splunkhome_path sys.path.append( make_splunkhome_path(['etc', 'apps', 'splunk_app_cloudgateway', 'bin'])) from spacebridgeapp.util import py23 from twisted.web import http from spacebridgeapp.logging import setup_logging from spacebridgeapp.rest.util import errors as Errors from spacebridgeapp.rest.base_endpoint import BaseRestHandler from spacebridgeapp.rest.services.splunk_service import get_app_list_request from spacebridgeapp.rest.services.kvstore_service import KVStoreCollectionAccessObject as KvStore from spacebridgeapp.util.constants import USER_META_COLLECTION_NAME, SPACEBRIDGE_APP_NAME, AUTHTOKEN, \ SESSION, USER, DASHBOARD_APP_LIST, APP_LIST, APP_NAMES, KEY LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + ".log", "rest_app_list") class AppList(BaseRestHandler, PersistentServerConnectionApplication): """ Main class for handling the app_list endpoint. Subclasses the spacebridge_app BaseRestHandler. """ def __init__(self, command_line, command_arg): BaseRestHandler.__init__(self) def get(self, request): """ Handler which retrieves kvstore app_list data for the current user """
""" Copyright (C) 2009-2020 Splunk Inc. All Rights Reserved. """ import splunk import sys from spacebridgeapp.util.constants import OR_OPERATOR, AND_OPERATOR, NOT_EQUAL from spacebridgeapp.util.splunk_utils.statestore import StateStore import splunk.rest as rest from spacebridgeapp.util import constants from spacebridgeapp.logging import setup_logging logger = setup_logging(constants.SPACEBRIDGE_APP_NAME + '_kvstore_writer.log', 'kvstore_writer.app') def build_containedin_clause(key, values): return {OR_OPERATOR: [{key: value} for value in values]} def build_not_containedin_clause(key, values): return {AND_OPERATOR: [{key: {NOT_EQUAL: value}} for value in values]} class KVStoreBatchWriter(StateStore): """ Class extending ITSI's KV Store batch writer but customizing it to support injecting our own app name """ def __init__(self, **kwargs): super(KVStoreBatchWriter, self).__init__(**kwargs)
sys.path.append( make_splunkhome_path(['etc', 'apps', 'splunk_secure_gateway', 'bin'])) from spacebridgeapp.util import py23 from spacebridgeapp.logging import setup_logging from spacebridgeapp.util import constants from spacebridgeapp.util.config import secure_gateway_config as config from spacebridgeapp.util.mtls import build_key_bundle from spacebridgeapp.rest.base_endpoint import BaseRestHandler from spacebridgeapp.rest.util.helper import extract_parameter from spacebridgeapp.rest.services.kvstore_service import KVStoreCollectionAccessObject as KvStore from spacebridgeapp.rest.services.spacebridge_service import delete_device_from_spacebridge from spacebridgeapp.rest.services.splunk_service import get_devices_for_user, user_has_registered_devices LOGGER = setup_logging(constants.SPACEBRIDGE_APP_NAME + ".log", "rest_delete_device") DEVICE_KEY_LABEL = 'device_key' class DeleteDevice(BaseRestHandler, PersistentServerConnectionApplication): """ Main rest handler class for the delete device functionality """ def __init__(self, command_line, command_arg): BaseRestHandler.__init__(self) def post(self, request): """ Deletes the specified device from the kvstore. Parses necessary data and credentials out of the request object, validates permissions, and makes the deletion request.
from spacebridgeapp.ar.ar_util import is_non_string_iterable from spacebridgeapp.ar.data.asset_data import AssetData from spacebridgeapp.ar.permissions.async_permissions_client import Capabilities, AccessQuantity, ARObjectType from spacebridgeapp.ar.storage.queries import get_query_matching_keys from spacebridgeapp.exceptions.spacebridge_exceptions import SpacebridgeApiRequestError, SpacebridgeARPermissionError from spacebridgeapp.logging import setup_logging from spacebridgeapp.util.constants import (KEY, ASSETS_COLLECTION_NAME, SPACEBRIDGE_APP_NAME, ASSET_OBJECTS, ASSET_GROUP, AND_OPERATOR, OR_OPERATOR, ASSET_GROUP_OBJECTS, ASSET_GROUPS_COLLECTION_NAME, QUERY, MANAGE_PERMISSION_REQUIRED) from twisted.internet import defer from twisted.web import http LOGGER = setup_logging('{}_assets.log'.format(SPACEBRIDGE_APP_NAME), "assets") ASSET_MANAGE_PERMISSION_REQUIRED = MANAGE_PERMISSION_REQUIRED.format( object_type='asset') class MissingAssetIDException(SpacebridgeApiRequestError): def __init__(self, message): super(MissingAssetIDException, self).__init__(message, status_code=http.BAD_REQUEST) class NoSuchAssetException(SpacebridgeApiRequestError): def __init__(self, asset_id): super(NoSuchAssetException, self).__init__( message='asset_id={} does not exist'.format(asset_id), status_code=http.NOT_FOUND)
class SpacebridgeModularInput(modular_input.ModularInput): """ Main entry path for launching the Spacebridge Application Modular Input Arguments: modular_input {[type]} -- [description] """ title = 'Splunk Cloud Gateway' description = 'Initializes the Splunk Cloud Gateway application to talk to mobile clients over websockets' app = 'Splunk App Cloud Gateway' name = 'splunkappcloudgateway' use_kvstore_checkpointer = False use_hec_event_writer = False health_check_rerun_seconds = 60 logger = setup_logging( constants.SPACEBRIDGE_APP_NAME + '_modular_input.log', 'cloudgateway_modular_input.app') def do_run(self, input_config): """ Spins up a websocket connection Spacebridge and begins the reactor loops """ shard_id = default_shard_id() self.logger.info("Starting libsodium child process") sodium_logger = self.logger.getChild('sodium_client') sodium_logger.setLevel(logging.WARN) sodium_client = SodiumClient(sodium_logger) encryption_context = SplunkEncryptionContext( self.session_key, constants.SPACEBRIDGE_APP_NAME, sodium_client) self.logger.info( "Running Splunk Cloud Gateway modular input on search head, shard_id=%s", shard_id) # Fetch load balancer address if configured, otherwise use default URI try: uri = get_uri(self.session_key) self.logger.debug( "Successfully verified load_balancer_address={}".format(uri)) except Exception as e: self.logger.exception( "Failed to verify load_balancer_address. {}".format(e)) if not uri: return try: ensure_deployment_friendly_name(self.session_key) async_client_factory = AsyncClientFactory(uri) cloudgateway_message_handler = CloudgatewayMessageHandler( SplunkAuthHeader(self.session_key), logger=self.logger, encryption_context=encryption_context, async_client_factory=async_client_factory, shard_id=shard_id) client = CloudGatewayWsClient( encryption_context, message_handler=cloudgateway_message_handler, mode=WebsocketMode.ASYNC, logger=self.logger, config=config, shard_id=shard_id) client.connect() except Exception as e: self.logger.exception( "Exception connecting to cloud gateway={0}".format(e))
DASHBOARD_LIST_REQUEST = 'dashboard_list' APP_LIST_REQUEST = 'app_list' ALL_APPS_REQUEST = 'all_apps' TV_LIST_REQUEST = 'tv_list' TV_CONFIG_REQUEST = 'tv_config' TV_CONFIG_BULK_REQUEST = 'tv_config_bulk' TV_BOOKMARK_REQUEST = 'tv_bookmark' ACTIVATE_TV_BOOKMARK_REQUEST = 'activate_tv_bookmark' DRONE_MODE_TV_SUBSCRIBE_REQUEST = 'drone_mode_tv_subscribe' DRONE_MODE_IPAD_SUBSCRIBE_REQUEST = 'drone_mode_ipad_subscribe' MPC_BROADCAST_REQUEST = 'mpc_broadcast' TV_INTERACTION_REQUEST = 'tv_interaction' TV_CAPTAIN_URL_REQUEST = 'captain_url' SUBSCRIPTION_PING = 'subscription_ping' LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + ".log", "rest_async_bridge") VALID_GET_REQUESTS = { DASHBOARD_LIST_REQUEST, APP_LIST_REQUEST, ALL_APPS_REQUEST, TV_LIST_REQUEST, TV_BOOKMARK_REQUEST } VALID_POST_REQUESTS = { APP_LIST_REQUEST, TV_CONFIG_REQUEST, TV_CONFIG_BULK_REQUEST, TV_BOOKMARK_REQUEST, ACTIVATE_TV_BOOKMARK_REQUEST, DRONE_MODE_TV_SUBSCRIBE_REQUEST, DRONE_MODE_IPAD_SUBSCRIBE_REQUEST, MPC_BROADCAST_REQUEST, TV_INTERACTION_REQUEST, TV_CAPTAIN_URL_REQUEST, SUBSCRIPTION_PING } VALID_DELETE_REQUESTS = {TV_BOOKMARK_REQUEST, TV_CONFIG_REQUEST} class AsyncBridge(BaseRestHandler, PersistentServerConnectionApplication):
from cloudgateway.private.encryption.encryption_handler import sign_detached from twisted.internet import defer from twisted.web import http from spacebridge_protocol import http_pb2 from spacebridgeapp.dashboard.udf_util import parse_hosted_resource_path, HostedResourceType, \ build_encrypted_resource, get_collection_from_resource_type from spacebridgeapp.exceptions.spacebridge_exceptions import SpacebridgeApiRequestError from spacebridgeapp.util import constants from spacebridgeapp.logging import setup_logging from spacebridgeapp.messages.util import fetch_device_info from spacebridgeapp.request.request_processor import SpacebridgeAuthHeader LOGGER = setup_logging(constants.SPACEBRIDGE_APP_NAME + "_udf_request_processor", "udf_request_processor") @defer.inlineCallbacks def process_udf_hosted_resource_get(request_context, client_single_request, server_single_response, async_kvstore_client=None, async_spacebridge_client=None, encryption_context=None): """ Process a UDF hosted resource get request. This used for fetching assets which are used within UDF dashboards such as images. :param request_context: :param client_single_request: :param server_single_response: :param async_kvstore_client: :param async_spacebridge_client: :param encryption_context:
Copyright (C) 2009-2020 Splunk Inc. All Rights Reserved. """ import json import time import splunk import splunk.rest as rest from spacebridgeapp.util import py23 from spacebridgeapp.util import constants from spacebridgeapp.logging import setup_logging from spacebridgeapp.util.constants import NOBODY from spacebridgeapp.util.string_utils import encode_whitespace, append_path_to_uri import urllib.parse as urllib LOGGER = setup_logging(constants.SPACEBRIDGE_APP_NAME + "_kvstore_service.log", "kvstore_service") class KVStoreCollectionAccessObject(object): 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
""" (C) 2019 Splunk Inc. All rights reserved. REST endpoint handler for accessing and setting kvstore records """ import splunk.rest as rest from spacebridgeapp.logging import setup_logging from spacebridgeapp.exceptions.load_balancer_exceptions import GetConfigError, AddressVerificationError from spacebridgeapp.util import constants from spacebridgeapp.util.config import cloudgateway_config as config LOGGER = setup_logging(constants.SPACEBRIDGE_APP_NAME + ".log", "load_balancer_verification") from spacebridgeapp.util import py23 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
import json from collections import defaultdict from spacebridgeapp.data.subscription_data import Subscription, SearchUpdate, SubscriptionCredential from spacebridgeapp.exceptions.spacebridge_exceptions import SpacebridgeApiRequestError from spacebridgeapp.logging import setup_logging from spacebridgeapp.subscriptions.subscription_requests import fetch_searches_for_shard from spacebridgeapp.util.constants import SEARCH_KEY, SUBSCRIPTION_KEY, KEY, QUERY, SPACEBRIDGE_APP_NAME, NOBODY, \ SUBSCRIPTIONS_COLLECTION_NAME, SEARCH_UPDATES_COLLECTION_NAME, SUBSCRIPTION_CREDENTIALS_COLLECTION_NAME from spacebridgeapp.util.kvstore import build_containedin_clause from splapp_protocol.common_pb2 import Error from twisted.internet import defer from twisted.web import http LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + "_subscription_loader.log", "subscription_loader") def _noop(arg): return arg def _collect(arr, grouping_key): grouped = defaultdict(list) for item in arr: value = getattr(item, grouping_key) grouped[value].append(item) return grouped @defer.inlineCallbacks
import sys import json from splunk.persistconn.application import PersistentServerConnectionApplication from splunk.clilib.bundle_paths import make_splunkhome_path sys.path.append( make_splunkhome_path(['etc', 'apps', 'splunk_secure_gateway', 'bin'])) from spacebridgeapp.util import py23 from spacebridgeapp.logging import setup_logging from spacebridgeapp.util import constants from spacebridgeapp.rest.base_endpoint import BaseRestHandler from spacebridgeapp.rest.services import splunk_service from spacebridgeapp.util.constants import ENCRYPTION_KEYS LOGGER = setup_logging(constants.SPACEBRIDGE_APP_NAME + ".log", "sign_credentials_handler") class SignCredentialsHandler(BaseRestHandler, PersistentServerConnectionApplication): def __init__(self, command_line, command_arg): BaseRestHandler.__init__(self) def get(self, request): """ Fetch public and private keys for signing messages from the passwords endpoint :param request: :return: """ LOGGER.info('Received request for fetching encrypted credentials') system_authtoken = request['system_authtoken']
import json from twisted.internet import defer from twisted.web import http from cloudgateway.splunk.auth import SplunkAuthHeader from spacebridgeapp.util.constants import SPACEBRIDGE_APP_NAME, SEARCHES_COLLECTION_NAME, \ SUBSCRIPTIONS_COLLECTION_NAME, SEARCH_KEY, QUERY, NOBODY, \ SUBSCRIPTION_CREDENTIALS_COLLECTION_NAME, FIELDS, KEY, PARENT_SEARCH_KEY, SHARD_ID, VERSION, SUBSCRIPTION_VERSION_2, \ SEARCH, AND_OPERATOR, SUBSCRIPTION_TYPE, SUBSCRIPTION_KEY from spacebridgeapp.exceptions.spacebridge_exceptions import SpacebridgeApiRequestError from spacebridgeapp.request.dashboard_request_processor import fetch_dashboard_description from spacebridgeapp.data.subscription_data import SubscriptionSearch, Subscription, SubscriptionCredential from spacebridgeapp.data.search_type import SearchType from spacebridgeapp.logging import setup_logging LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + "_subscription_requests.log", "subscription_requests") @defer.inlineCallbacks def fetch_searches_for_shard(auth_header, shard_id, async_kvstore_client): query = {SHARD_ID: shard_id, VERSION: SUBSCRIPTION_VERSION_2} params = {QUERY: json.dumps(query)} LOGGER.debug("Querying for searches, params=%s", params) searches = yield fetch_searches(auth_header=auth_header, params=params, async_kvstore_client=async_kvstore_client) LOGGER.debug("Found active searches count=%d", len(searches))
""" (C) 2019 Splunk Inc. All rights reserved. Separate module to capture send methods """ from twisted.internet import defer from spacebridgeapp.logging import setup_logging from spacebridgeapp.util.constants import SPACEBRIDGE_APP_NAME from spacebridge_protocol import websocket_pb2, sb_common_pb2 LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + "_send_processor.log", "send_processor") @defer.inlineCallbacks def send_response(request_context, message_sender, server_application_response, websocket_protocol, encrypt, sign, generichash): if not server_application_response.WhichOneof('app_message'): LOGGER.info("No response necessary") defer.returnValue(None) # Take server payload and wrap in an envelope payload = server_application_response.SerializeToString() encrypted_payload = encrypt(payload) signed_envelope = yield build_envelope(encrypted_payload, message_sender, websocket_protocol, request_context.request_id, sign, generichash)
"""Copyright (C) 2009-2020 Splunk Inc. All Rights Reserved.""" import random from spacebridgeapp.logging import setup_logging from spacebridgeapp.rest.clients.async_client_factory import AsyncClientFactory from spacebridgeapp.subscriptions.job_result import JobResult from spacebridgeapp.subscriptions.subscription_processor import process_pubsub_subscription from spacebridgeapp.util.constants import SPACEBRIDGE_APP_NAME from spacebridgeapp.util.mtls import build_mtls_spacebridge_client from spacebridgeapp.util.config import secure_gateway_config as config from multiprocessing import Pool import asyncio LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + '_process_manager.log', 'process_manager') class JobContext(object): def __init__(self, auth_header, splunk_uri, encryption_context, search_context=None, subscription_update_ids=None): self.auth_header = auth_header self.splunk_uri = splunk_uri self.encryption_context = encryption_context self.search_context = search_context if subscription_update_ids is None: subscription_update_ids = {}
import sys from functools import reduce from splunk.clilib.bundle_paths import make_splunkhome_path from splunk.persistconn.application import PersistentServerConnectionApplication sys.path.append( make_splunkhome_path(['etc', 'apps', 'splunk_secure_gateway', 'bin'])) from spacebridgeapp.util import py23 from spacebridgeapp.logging import setup_logging from spacebridgeapp.util import constants from spacebridgeapp.rest.base_endpoint import BaseRestHandler from spacebridgeapp.rest.services.splunk_service import get_all_mobile_users, get_all_users, get_devices_for_user LOGGER = setup_logging(constants.SPACEBRIDGE_APP_NAME + ".log", "rest_users_devices") class DevicesForUser(BaseRestHandler, PersistentServerConnectionApplication): """ Main class for handling the devices_user endpoint. Subclasses the spacebridge_app BaseRestHandler. """ def __init__(self, command_line, command_arg): BaseRestHandler.__init__(self) def get(self, request): """ Handler which retrieves all devices in the kvstore belonging to all users. """ # Retrieves all devices from that user's devices kvstore collection
(C) 2020 Splunk Inc. All rights reserved. Module for representation of data objects for event_handler """ import json import os os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python' from splapp_protocol import event_handler_pb2, common_pb2 from spacebridgeapp.data.base import SpacebridgeAppBase from spacebridgeapp.util.constants import SPACEBRIDGE_APP_NAME, VALUE, LABEL, MATCH from spacebridgeapp.logging import setup_logging LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + "_event_handler.log", "event_handler") class Change(SpacebridgeAppBase): """ Container for data for change element. A change element contains set, unset, eval, link and conditions """ def __init__(self, link=None, sets=None, evals=None, unsets=None, conditions=None): self.link = link self.sets = sets or [] self.evals = evals or [] self.unsets = unsets or [] self.conditions = conditions or [] def set_protobuf(self, proto):
from spacebridgeapp.dashboard.dashboard_request_json import fetch_dashboard_list_json from spacebridgeapp.data.dashboard_data import DashboardData from spacebridgeapp.data.dashboard_data import DashboardVisualizationId from spacebridgeapp.data.dashboard_data import UserDashboardMeta from spacebridgeapp.util.config import secure_gateway_config as config from spacebridgeapp.metrics.dashboard_request_metrics import send_dashboard_list_request_metrics_to_telemetry from spacebridgeapp.request.app_list_request_processor import fetch_dashboard_app_list_with_default if sys.version_info < (3, 0): import urllib else: import urllib.parse as urllib LOGGER = setup_logging( constants.SPACEBRIDGE_APP_NAME + "_dashboard_request_processor.log", "dashboard_request_processor") # API Name Constants DASHBOARD_LIST_REQUEST = "DASHBOARD_LIST_REQUEST" async def process_dashboard_list_request(request_context, client_single_request, server_single_response, async_client_factory): """ This method will process dashboard list requests :param request_context: :param client_single_request:
import sys from twisted.internet import defer from spacebridgeapp.util.constants import SPACEBRIDGE_APP_NAME from spacebridgeapp.logging import setup_logging from spacebridgeapp.exceptions.spacebridge_exceptions import SpacebridgeApiRequestError from spacebridgeapp.dashboard.dashboard_request_json import fetch_dashboard_list_json from spacebridgeapp.dashboard.dashboard_helpers import shorten_dashboard_id_from_url, parse_dashboard_id, \ generate_dashboard_id if sys.version_info < (3, 0): from urlparse import urlparse, parse_qsl else: from urllib.parse import urlparse, parse_qsl LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + "_drilldown_helpers.log", "drilldown_helpers") FORM_PREFIX = "form." SPLUNK_URL_PREFIX = '/app/' def parse_dashboard_link(url=None): """ Helper to parse dashboard_id and input_map from drilldown link :param url: :return: """ dashboard_id = '' input_map = {} if url and url.startswith(SPLUNK_URL_PREFIX):
from spacebridgeapp.util.kvstore import build_containedin_clause from spacebridgeapp.util.time_utils import get_current_timestamp_str from spacebridgeapp.logging import setup_logging from spacebridgeapp.messages.request_context import RequestContext from spacebridgeapp.drone_mode.data.drone_mode_data import TVConfig, TVList from spacebridgeapp.drone_mode.data.enums import TVEventType, IPadEventType from spacebridgeapp.data.subscription_data import Subscription, SubscriptionCredential, DroneModeTVEvent, DroneModeiPadEvent from spacebridgeapp.request.request_processor import SpacebridgeAuthHeader from spacebridgeapp.rest.devices.user_devices import public_keys_for_device from spacebridgeapp.drone_mode.drone_mode_subscription_update_message import build_drone_mode_subscription_update from spacebridgeapp.subscriptions.subscription_update_message import build_send_subscription_update_request from spacebridgeapp.drone_mode.drone_mode_utils import get_drone_mode_tvs, get_registered_tvs, has_grid from spacebridgeapp.request.request_processor import get_splunk_cookie, JWTAuthHeader LOGGER = setup_logging( constants.SPACEBRIDGE_APP_NAME + "_drone_mode_subscription_requests.log", "drone_mode_subscription_requests") @defer.inlineCallbacks def fetch_valid_tvs(request_context, async_kvstore_client, user=None, tv_ids=None): """ Function to fetch valid tvs for drone mode :param request_context: request context used to make kvstore requests :param async_kvstore_client: async client used to make kvstore requests :param device_id: optional device id to filter on """ # fetch list of all registered tvs
""" Copyright (C) 2009-2020 Splunk Inc. All Rights Reserved. """ import os os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python' from spacebridge_protocol import http_pb2 from spacebridge_protocol import sb_common_pb2 from splapp_protocol import envelope_pb2 from spacebridgeapp.util import constants TTL_SECONDS = 259200 from spacebridgeapp.logging import setup_logging LOGGER = setup_logging(constants.SPACEBRIDGE_APP_NAME + '_mobile_alert.log', 'ssg_mobile_alert') def build_notification_request(device_id, device_id_raw, sender_id, notification, encrypt, sign): """ :param device_id: A string representation of the device id :param device_id_raw: A byte representation of the device id :param sender_id: A byte representation of the sender :param notification: A Notification proto object :param encrypt: a 1 argument function that encrypts some plaintext :param sign: a 1 argument function that will calculate a signature for some byte input :return: A proto notification message if encryption and signing succeed, None otherwise """ LOGGER.info("Building notification alert_id=%s, device_id=%s" % (notification.alert_id, device_id))
import jsonpickle import sys from http import HTTPStatus from spacebridgeapp.data.dashboard_data import UserDashboardMeta from spacebridgeapp.exceptions.spacebridge_exceptions import SpacebridgeApiRequestError from spacebridgeapp.util.constants import SPACEBRIDGE_APP_NAME, DASHBOARD_META_COLLECTION_NAME from spacebridgeapp.logging import setup_logging if sys.version_info < (3, 0): import urllib else: import urllib.parse as urllib LOGGER = setup_logging(SPACEBRIDGE_APP_NAME + "_dashboard_meta.log", "dashboard_meta") async def fetch_dashboard_meta(request_context, dashboard_id=None, async_kvstore_client=None): """ Helper to fetch dashboard_meta :param request_context: :param dashboard_id: :param async_kvstore_client: :return: """ # Only set the key_id if a dashboard_id is provided key_id = urllib.quote_plus(dashboard_id) if dashboard_id else None response = await async_kvstore_client.async_kvstore_get_request(