def send(self, device_id, payload, request_id=None): """Send a message to a particular device using Cloud Gateway Args: device_id ([binary]): id of the device to send the message to payload ([string]): Message to be sent. Can be any format you want (json, serialized proto, etc.) request_id (str, optional): [description]. Defaults to "123". Returns: [requests.response]: response returned by requests object """ if not request_id: request_id = ServerResponse.create_rid() send_message_request = http_pb2.SendMessageRequest() recipient_info = self.message_handler.fetch_device_info(device_id) build_encrypted_payload( recipient_info, self.encryption_context, payload, request_id, self.logger, signed_envelope=send_message_request.signedEnvelope) # self.connector.factory.protocol.sendMessage(send_message_request.SerializeToString()) spacebridge_header = { 'Authorization': sb_auth_header(self.encryption_context) } with requests_ssl_context(self.key_bundle) as cert: return requests.post(sb_message_endpoint(self.config), headers=spacebridge_header, data=send_message_request.SerializeToString(), cert=cert.name)
def make_device_authentication_request(device_info, encryption_context, config, key_bundle=None): """Makes a device authentication request to Cloud Gateway. If successful, Cloud Gateway will return a DeviceAuthenticationResponse object. Args: device_info ([DeviceInfo]): device info object containing client's public keys encryption_context ([EncryptionContext]): Raises: RestException.CloudgatewayServerError Returns: [Requests.Response]: response object whose content is a serialized DeviceAuthenticationResponse proto """ with requests_ssl_context(key_bundle) as cert: request_proto = build_device_authentication_request(device_info) try: spacebridge_header = { 'Authorization': sb_auth_header(encryption_context) } return requests.post(sb_client_auth_endpoint(config), headers=spacebridge_header, data=request_proto.SerializeToString(), cert=cert.name) except Exception as e: raise RestException.CloudgatewayServerError( 'Unable to reach cloudgateway: {0}'.format(e), 503)
def make_authentication_result_request(auth_code, encryption_context, config, key_bundle=None): """ Make AuthenticationResultRequest to Cloud Gateway Args: auth_code ([string]): 10-digit auth code returned by Cloud Gateway on Device Authentication Request encryption_context ([EncryptionContext]): Raises: RestException.CloudgatewayServerError: Returns: [Requests.Response]: Response object containing serialized AuthenticationResultResponse object """ request_proto = build_authentication_result_request(auth_code) with requests_ssl_context(key_bundle) as cert: try: spacebridge_header = { 'Authorization': sb_auth_header(encryption_context) } return requests.get(sb_client_auth_result_endpoint( auth_code, config), headers=spacebridge_header, data=request_proto.SerializeToString(), cert=cert.name) except Exception as e: raise RestException.CloudgatewayServerError( 'Unable to reach cloudgateway: {0}'.format(e), 503)
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
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)
def submit_auth_code(auth_code, encryption_context, config, key_bundle=None): """ Given an auth code, submit it to cloudgateway's auth endpoint. Raise an exception if cannot reach cloudgateway :param auth_code :param encryption_context :param mtls_pkcs12: A PKCS12 object containing the certificate and private key information for mTLS :return: seriealized protobuf response from cloudgateway """ with requests_ssl_context(key_bundle) as cert: try: spacebridge_header = {'Authorization': sb_auth_header(encryption_context)} return requests.get(sb_auth_endpoint(auth_code, config), headers=spacebridge_header, proxies=config.get_proxies(), cert=cert.name ) except Exception as e: raise RestException.CloudgatewayServerError('Unable to reach cloudgateway: {0}'.format(e), 503)
def make_device_pairing_req(auth_code, auth_header, sb_request_proto, config, key_bundle=None): """ Takes an auth code, cloudgateway auth header as well as a device pairing confirmation request proto and posts the request to cloudgateway. This is the final step of the registration process :param auth_code: 10 digit auth code presented to the client device at the start of registration :param auth_header: authentication header to talk to cloudgateway :param sb_request_proto: :return: void """ with requests_ssl_context(key_bundle) as cert: try: return requests.put( url='{0}/api/registrations/{1}'.format(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(), cert=cert.name ) except Exception: raise CloudgatewayServerError('Unable to reach Spacebridge', 503)
def make_unregister_req(unregister_proto, sb_auth_header, config, key_bundle=None): """ Initiate the unregistration request to cloud gateway :param unregister_proto: DeviceUnregistrationRequest proto :param sb_auth_header: auth header to send to cloud gateway :return: either return a requests response object or if there is an exception, a CloudGatewayServerError object """ headers = { 'Content-Type': 'application/x-protobuf', 'Authorization': str(sb_auth_header) } with requests_ssl_context(key_bundle) as cert: try: return requests.delete("%s/api/session" % config.get_spacebridge_domain(), headers=headers, proxies=config.get_proxies(), data=unregister_proto.SerializeToString(), cert=cert.name) except Exception: raise CloudgatewayServerError('Unable to reach Cloudgateway', 503)
def make_mdm_authentication_request(username, password, server_info, encryption_context, mdm_sign_private_key, config, pkcs12): """ Make AuthenticationResultRequest to Cloud Gateway Args: auth_code ([string]): 10-digit auth code returned by Cloud Gateway on Device Authentication Request encryption_context ([EncryptionContext]): Raises: RestException.CloudgatewayServerError: Returns: [Requests.Response]: Response object containing serialized AuthenticationResultResponse object """ request_proto = build_mdm_authentication_request(username, password, encryption_context, server_info, mdm_sign_private_key) with requests_ssl_context(pkcs12) as cert: try: return requests.post(url='{0}/api/mdm/authenticate'.format( config.get_spacebridge_domain()), headers={ 'Content-Type': 'application/x-protobuf', 'Authorization': sb_auth_header(encryption_context) }, data=request_proto.SerializeToString(), proxies=config.get_proxies(), cert=cert) except Exception as e: raise RestException.CloudgatewayServerError( 'Unable to reach cloudgateway: {0}'.format(e), 503)