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
Beispiel #2
0
 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()
Beispiel #3
0
    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)
Beispiel #5
0
    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