예제 #1
0
    def generate(self):
        spacebridge_server = config.get_spacebridge_domain()

        url = "{}/health_check".format(spacebridge_server)

        proxies = config.get_proxies()

        # Unset proxy, if unsetProxy = True
        if not self.useProxy:
            proxies = {}

        # Load data from REST API
        try:
            response = requests.get(
                url,
                proxies=proxies,
                timeout=15
            )

            response.raise_for_status()
            healthy = {'https_sync': True}

        except requests.exceptions.HTTPError as err:
            healthy = {'https_sync': False, 'message': str(err)}
        except ProxyError as err:
            healthy = {'https_sync': False, 'message': str(err)}
        except requests.ConnectionError as err:
            healthy = {'https_sync': False, 'message': str(err)}

        yield healthy
예제 #2
0
def delete_device_from_spacebridge(device_id,
                                   system_authtoken,
                                   key_bundle=None):
    """
    Deletes device from spacebridge
    :param device_id:
    :param system_authtoken:
    :return: response from spacebridge
    """
    sodium_client = SodiumClient(LOGGER.getChild("sodium_client"))
    encryption_context = SplunkEncryptionContext(
        system_authtoken, constants.SPACEBRIDGE_APP_NAME, sodium_client)
    public_key_hash = encryption_context.sign_public_key(
        transform=encryption_context.generichash_hex)

    unregister_proto = http_pb2.DeviceUnregistrationRequest()
    unregister_proto.deviceId = b64decode(device_id)
    unregister_proto.deploymentId = encryption_context.sign_public_key(
        transform=encryption_context.generichash_raw)

    headers = {
        'Authorization': public_key_hash,
        'Content-Type': 'application/x-protobuf'
    }

    with requests_ssl_context(key_bundle):
        try:
            response = requests.delete(
                "%s/api/session" % config.get_spacebridge_domain(),
                headers=headers,
                proxies=config.get_proxies(),
                data=unregister_proto.SerializeToString())
        except Exception:
            LOGGER.exception(
                "Exception attempting sending delete device request to Spacebridge"
            )
            raise Errors.SpacebridgeServerError('Unable to reach Spacebridge',
                                                503)

    LOGGER.info(
        "Received response=%s on delete device from Spacebridge request" %
        response.status_code)

    spacebridge_response = http_pb2.DeviceUnregistrationResponse()
    spacebridge_response.ParseFromString(response.content)

    LOGGER.info('Spacebridge response: %s' % str(spacebridge_response))

    if spacebridge_response.HasField(
            'error'
    ) and spacebridge_response.error.code != http_pb2.HttpError.Code.Value(
            'ERROR_ROUTING_UNDELIVERABLE'):
        raise Errors.SpacebridgeServerError(
            "Spacebridge error on delete device request=%s" %
            spacebridge_response.error.message)

    return response
예제 #3
0
 def call_grants():
     with requests_ssl_context(key_bundle) as cert:
         return requests.post('{}/api/mdm/grants'.format(
             config.get_spacebridge_domain()),
                              headers=headers,
                              data=request_proto.SerializeToString(),
                              proxies=config.get_proxies(),
                              timeout=constants.TIMEOUT_SECONDS,
                              cert=cert.name)
    async def run(self):
        proxy = config.get_https_proxy_settings()
        uri = "{}/health_check".format(config.get_spacebridge_domain())

        if not self.useProxy:
            proxy = None

        client = AsyncClient(AioHttpClient(proxy=proxy))

        try:
            result = await client.async_get_request(uri, None)
            if result.code == 200:
                self.echo_state.ok = True
            else:
                self.echo_state.message = 'Got http {}'.format(result.code)
        except Exception as e:
            self.echo_state.message = str(e)

        return {
            'https_async': self.echo_state.ok,
            'message': self.echo_state.message
        }
예제 #5
0
def authentication_query_request(auth_code, encryption_context):
    """ Abstraction layer for the spacebridge request. This function:
        1. Makes the registration query GET request to the spacebridge endpoint
        2. Parses the protobuf response
        3. Packs the response values into a response object. Binary objects are encoded to ensure kvstore compatibility

    :param auth_code: Authorization code of the device being registered
    :return: response object containing "public_key", "device_id", and "conf_code"
    """

    # Makes the registration query GET request to the spacebridge endpoint
    try:
        headers = {
            'Authorization':
            encryption_context.sign_public_key(
                transform=encryption_context.generichash_hex)
        }
        response = requests.get('%s/api/registrations/%s' %
                                (config.get_spacebridge_domain(), auth_code),
                                headers=headers,
                                proxies=config.get_proxies())
    except Exception:
        LOGGER.exception("Exception contacting spacebridge")
        raise Errors.SpacebridgeServerError('Unable to reach Spacebridge', 503)

    # Parses the protobuf response
    spacebridge_response = http_pb2.AuthenticationQueryResponse()
    spacebridge_response.ParseFromString(response.content)

    if spacebridge_response.HasField('error'):
        if response.status_code == 500:
            raise Errors.SpacebridgeServerError(
                'Spacebridge encountered an internal error: %s' %
                spacebridge_response.error.message, 500)

        raise Errors.SpacebridgeServerError(
            'Spacebridge request error: %s' %
            spacebridge_response.error.message, response.status_code)

    if not str(response.status_code).startswith('2'):
        raise Errors.SpacebridgeServerError(
            "Spacebridge error: %s" % str(response.content),
            response.status_code)

    # Packs the response values into a response object. Binary objects are encoded to ensure kvstore compatibility
    encrypt_public_key = spacebridge_response.payload.publicKeyForEncryption
    sign_public_key = spacebridge_response.payload.publicKeyForSigning
    response = {
        'encrypt_public_key':
        py23.b64encode_to_str(encrypt_public_key),
        'sign_public_key':
        py23.b64encode_to_str(sign_public_key),
        'device_id':
        py23.b64encode_to_str(spacebridge_response.payload.deviceId),
        'conf_code':
        encryption_context.generichash_hex(sign_public_key).upper()[:8],
    }

    try:
        response[APP_TYPE_LABEL] = translate_app_name(
            http_pb2.AppType.Name(spacebridge_response.payload.appType))
    except ValueError as err:
        # When app_type is 'APPTYPE_INVALID'
        raise Errors.SpacebridgeRestError('Registration Error: %s' % str(err),
                                          501)

    return response
예제 #6
0
def device_pairing_confirmation_request(auth_header, auth_code, username,
                                        device_id, encrypt_public_key,
                                        sign_public_key,
                                        session_token_encrypted, encrypt,
                                        deployment_friendly_name):
    """ Abstraction layer for the spacebridge request. This function:
        1. Creates the encrypted_credentials_bundle
        2. Generates a protobuf object from the supplied dictionary, proto_object
        3. Makes the registration confirmation PUT request to the spacebridge endpoint
        4. Parses the protobuf response, checking for error objects

    :param auth_code: Authorization code of the device being registered
    :param proto_object: Dict containing protobuf values
    :param username: User username for the encrypted_credentials_bundle
    :param password: User password for the encrypted_credentials_bundle
    :return: None
    """

    # Creates the encrypted_credentials_bundle
    credentials_bundle_proto = http_pb2.CredentialsBundle()
    credentials_bundle_proto.sessionToken = session_token_encrypted
    credentials_bundle_proto.userName = username
    credentials_bundle_proto.deploymentName = deployment_friendly_name
    credentials_bundle = credentials_bundle_proto.SerializeToString()

    encrypted_credentials_bundle = encrypt(credentials_bundle)

    # Generates a protobuf object from the supplied dictionary, proto_object
    sb_request_proto = http_pb2.DevicePairingConfirmationRequest()
    sb_request_proto.authenticationCode = auth_code
    sb_request_proto.deviceId = device_id
    sb_request_proto.deploymentPublicKeyForEncryption = encrypt_public_key
    sb_request_proto.deploymentPublicKeyForSigning = sign_public_key
    sb_request_proto.encryptedCredentialsBundle = encrypted_credentials_bundle
    LOGGER.info("Registration Bundle deploymentPublicKey= %s" %
                str(sb_request_proto.deploymentPublicKey))
    LOGGER.info("Registration Bundle deviceId= %s" %
                str(sb_request_proto.deviceId))

    # Makes the registration confirmation PUT request to the spacebridge endpoint
    try:
        response = requests.put('%s/api/registrations/%s' %
                                (config.get_spacebridge_domain(), auth_code),
                                headers={
                                    'Content-Type': 'application/x-protobuf',
                                    'Authorization': str(auth_header)
                                },
                                data=sb_request_proto.SerializeToString(),
                                proxies=config.get_proxies())
    except Exception:
        raise Errors.SpacebridgeServerError('Unable to reach Spacebridge', 503)

    # Parses the protobuf response, checking for error objects
    sb_response_proto = http_pb2.DevicePairingConfirmationResponse()
    sb_response_proto.ParseFromString(response.content)

    if sb_response_proto.HasField('error'):
        if response.status_code == 500:
            raise Errors.SpacebridgeServerError(
                'Spacebridge encountered an internal error: %s' %
                sb_response_proto.error.message, 500)
        raise Errors.SpacebridgeServerError(
            'Spacebridge request error: %s' % sb_response_proto.error.message,
            response.status_code)

    if not (200 <= response.status_code < 300):
        raise Errors.SpacebridgeServerError(
            "Spacebridge error: %s" % str(response.content),
            response.status_code)