def wrapper(wrapped_self, user_id, *args, **kwargs): """Will always send a notification.""" target = resource.Resource(typeURI=taxonomy.ACCOUNT_USER) initiator = build_audit_initiator() initiator.user_id = user_id initiator.id = utils.resource_uuid(user_id) try: result = f(wrapped_self, user_id, *args, **kwargs) except (exception.AccountLocked, exception.PasswordExpired) as ex: # Send a CADF event with a reason for PCI-DSS related # authentication failures audit_reason = reason.Reason(str(ex), str(ex.code)) _send_audit_notification(self.action, initiator, taxonomy.OUTCOME_FAILURE, target, self.event_type, reason=audit_reason) raise except Exception: # For authentication failure send a CADF event as well _send_audit_notification(self.action, initiator, taxonomy.OUTCOME_FAILURE, target, self.event_type) raise else: _send_audit_notification(self.action, initiator, taxonomy.OUTCOME_SUCCESS, target, self.event_type) return result
def mod_audit_event(self, req, response): """Modifies CADF event in request based on response. If no event exists, a new event is created. """ if response: if response.status_int >= 200 and response.status_int < 400: result = taxonomy.OUTCOME_SUCCESS else: result = taxonomy.OUTCOME_FAILURE else: result = taxonomy.UNKNOWN if hasattr(req, 'cadf_model'): req.cadf_model.add_reporterstep( reporterstep.Reporterstep( role=cadftype.REPORTER_ROLE_MODIFIER, reporter=resource.Resource(id='target'), reporterTime=timestamp.get_utc_now())) else: self.append_audit_event(req) req.cadf_model.outcome = result if response: req.cadf_model.reason = \ reason.Reason(reasonType='HTTP', reasonCode=str(response.status_int)) req.environ['CADF_EVENT'] = req.cadf_model.as_dict()
def _process_response(self, request, response=None): # NOTE(gordc): handle case where error processing request if 'cadf_event' not in request.environ: self._create_event(request) event = request.environ['cadf_event'] if response: if response.status_int >= 200 and response.status_int < 400: result = taxonomy.OUTCOME_SUCCESS else: result = taxonomy.OUTCOME_FAILURE event.reason = reason.Reason( reasonType='HTTP', reasonCode=str(response.status_int)) else: result = taxonomy.UNKNOWN event.outcome = result event.add_reporterstep( reporterstep.Reporterstep( role=cadftype.REPORTER_ROLE_MODIFIER, reporter=resource.Resource(id='target'), reporterTime=timestamp.get_utc_now())) self._notifier.notify(request.context, 'audit.http.response', event.as_dict())
def test_reason(self): reason_val = reason.Reason(reasonType='HTTP', reasonCode='200', policyType='poltype', policyId=identifier.generate_uuid()) self.assertEqual(reason_val.is_valid(), True) dict_reason_val = reason_val.as_dict() for key in reason.REASON_KEYNAMES: self.assertIn(key, dict_reason_val)
def _validate_and_normalize_auth_data(self, auth_payload): if 'user' not in auth_payload: raise exception.ValidationError(attribute='user', target=self.METHOD_NAME) user_info = auth_payload['user'] user_id = user_info.get('id') user_name = user_info.get('name') domain_ref = {} if not user_id and not user_name: raise exception.ValidationError(attribute='id or name', target='user') try: if user_name: if 'domain' not in user_info: raise exception.ValidationError(attribute='domain', target='user') domain_ref = self._lookup_domain(user_info['domain']) user_ref = PROVIDERS.identity_api.get_user_by_name( user_name, domain_ref['id']) else: user_ref = PROVIDERS.identity_api.get_user(user_id) domain_ref = PROVIDERS.resource_api.get_domain( user_ref['domain_id']) self._assert_domain_is_enabled(domain_ref) except exception.UserNotFound as e: LOG.warning(six.text_type(e)) # We need to special case USER NOT FOUND here for CADF # notifications as the normal path for notification(s) come from # `identity_api.authenticate` and we are a bit before dropping into # that method. audit_reason = reason.Reason(str(e), str(e.code)) audit_initiator = notifications.build_audit_initiator() # build an appropriate audit initiator with relevant information # for the failed request. This will catch invalid user_name and # invalid user_id. if user_name: audit_initiator.user_name = user_name else: audit_initiator.user_id = user_id audit_initiator.domain_id = domain_ref.get('id') audit_initiator.domain_name = domain_ref.get('name') notifications._send_audit_notification( action=_NOTIFY_OP, initiator=audit_initiator, outcome=taxonomy.OUTCOME_FAILURE, target=resource.Resource(typeURI=taxonomy.ACCOUNT_USER), event_type=_NOTIFY_EVENT, reason=audit_reason) raise exception.Unauthorized(e) self._assert_user_is_enabled(user_ref) self.user_ref = user_ref self.user_id = user_ref['id'] self.domain_id = domain_ref['id']
def test_event(self): ev = event.Event(eventType='activity', id=identifier.generate_uuid(), eventTime=timestamp.get_utc_now(), initiator=resource.Resource(typeURI='storage'), initiatorId=identifier.generate_uuid(), action='read', target=resource.Resource(typeURI='storage'), targetId=identifier.generate_uuid(), observer=resource.Resource(id='target'), observerId=identifier.generate_uuid(), outcome='success', reason=reason.Reason(reasonType='HTTP', reasonCode='200'), severity='high') ev.add_measurement( measurement.Measurement(result='100', metricId=identifier.generate_uuid())), ev.add_tag(tag.generate_name_value_tag('name', 'val')) ev.add_attachment(attachment.Attachment(typeURI='attachURI', content='content', name='attachment_name')) ev.observer = resource.Resource(typeURI='service/security') ev.add_reporterstep(reporterstep.Reporterstep( role='observer', reporter=resource.Resource(typeURI='service/security'))) ev.add_reporterstep(reporterstep.Reporterstep( reporterId=identifier.generate_uuid())) self.assertEqual(ev.is_valid(), False) dict_ev = ev.as_dict() for key in event.EVENT_KEYNAMES: self.assertIn(key, dict_ev) ev = event.Event(eventType='activity', id=identifier.generate_uuid(), eventTime=timestamp.get_utc_now(), initiator=resource.Resource(typeURI='storage'), action='read', target=resource.Resource(typeURI='storage'), observer=resource.Resource(id='target'), outcome='success') self.assertEqual(ev.is_valid(), True) ev = event.Event(eventType='activity', id=identifier.generate_uuid(), eventTime=timestamp.get_utc_now(), initiatorId=identifier.generate_uuid(), action='read', targetId=identifier.generate_uuid(), observerId=identifier.generate_uuid(), outcome='success') self.assertEqual(ev.is_valid(), True) ev = event.Event(eventType='activity', id=identifier.generate_uuid(), eventTime=timestamp.get_utc_now(), initiator=resource.Resource(typeURI='storage'), action='read', targetId=identifier.generate_uuid(), observer=resource.Resource(id='target'), outcome='success') self.assertEqual(ev.is_valid(), True)
def _create_cadf_event(self, project, res_spec, res_id, res_parent_id, request, response, suffix): action, key = self._get_action_and_key(res_spec, res_id, request, suffix) if not action: return None project_id = request.environ.get('HTTP_X_PROJECT_ID') domain_id = request.environ.get('HTTP_X_DOMAIN_ID') initiator = OpenStackResource( project_id=project_id, domain_id=domain_id, typeURI=taxonomy.ACCOUNT_USER, id=request.environ.get('HTTP_X_USER_ID', taxonomy.UNKNOWN), name=request.environ.get('HTTP_X_USER_NAME', taxonomy.UNKNOWN), domain=request.environ.get('HTTP_X_USER_DOMAIN_NAME', taxonomy.UNKNOWN), host=host.Host(address=request.client_addr, agent=request.user_agent)) action_result = None event_reason = None if response: if 200 <= response.status_int < 400: action_result = taxonomy.OUTCOME_SUCCESS else: action_result = taxonomy.OUTCOME_FAILURE event_reason = reason.Reason(reasonType='HTTP', reasonCode=str(response.status_int)) else: action_result = taxonomy.UNKNOWN target = None if res_id or res_parent_id: target = self._create_target_resource(project, res_spec, res_id, res_parent_id, key=key) else: target = self._create_target_resource(project, res_spec, None, self._service_id, key=key) target.name = self._service_name observer = self._create_observer_resource() event = eventfactory.EventFactory().new_event( eventType=cadftype.EVENTTYPE_ACTIVITY, outcome=action_result, action=action, initiator=initiator, observer=observer, reason=event_reason, target=target) event.requestPath = request.path_qs # add reporter step again? # event.add_reporterstep( # reporterstep.Reporterstep( # role=cadftype.REPORTER_ROLE_MODIFIER, # reporter=resource.Resource(id='observer'), # reporterTime=timestamp.get_utc_now())) return event
def _create_cadf_event(self, project, res_spec, res_id, res_parent_id, request, response, suffix): action = self._get_action(res_spec, res_id, request, suffix) key = None if not action: # ignored unknown actions if suffix == 'action': return None # suffix must be a key key = suffix # determine action from method (never None) action = self._get_action(res_spec, res_id, request, None) action += action_suffix_map[action] project_id = request.environ.get('HTTP_X_PROJECT_ID') domain_id = request.environ.get('HTTP_X_DOMAIN_ID') initiator = OpenStackResource( project_id=project_id, domain_id=domain_id, typeURI=taxonomy.ACCOUNT_USER, id=request.environ.get('HTTP_X_USER_ID', taxonomy.UNKNOWN), name=request.environ.get('HTTP_X_USER_NAME', taxonomy.UNKNOWN), domain=request.environ.get('HTTP_X_USER_DOMAIN_NAME', taxonomy.UNKNOWN), host=host.Host(address=request.client_addr, agent=request.user_agent)) action_result = None event_reason = None if response: if 200 <= response.status_int < 400: action_result = taxonomy.OUTCOME_SUCCESS else: action_result = taxonomy.OUTCOME_FAILURE event_reason = reason.Reason(reasonType='HTTP', reasonCode=str(response.status_int)) else: action_result = taxonomy.UNKNOWN target = None if res_id or res_parent_id: target = self._create_target_resource(project, res_spec, res_id, res_parent_id, key=key) else: target = self._create_target_resource(project, res_spec, None, self._service_id, key=key) target.name = self._service_name observer = self._create_observer_resource(request) event = eventfactory.EventFactory().new_event( eventType=cadftype.EVENTTYPE_ACTIVITY, outcome=action_result, action=action, initiator=initiator, observer=observer, reason=event_reason, target=target) event.requestPath = request.path_qs # if key and request.method[0] == 'P' and self._payloads_enabled and \ res_spec.payloads['enabled']: req_pl = request.json # remove possible wrapper elements req_pl = req_pl.get(res_spec.el_type_name, req_pl) self._attach_payload(event, req_pl, res_spec) # TODO add reporter step again? # event.add_reporterstep( # reporterstep.Reporterstep( # role=cadftype.REPORTER_ROLE_MODIFIER, # reporter=resource.Resource(id='observer'), # reporterTime=timestamp.get_utc_now())) return event