예제 #1
0
파일: beat.py 프로젝트: janheise/zentral
    def process_raw_event(self, raw_event):
        raw_event_d = json.loads(raw_event)

        # need to find the jamf instance
        jamf_instance = self.get_jamf_instance(raw_event_d)

        zentral_log_type = raw_event_d["zentral_log_type"]
        event = None
        if zentral_log_type == "zentral.contrib.jamf.jamf_change_management":
            event = self.build_change_management_event(raw_event_d,
                                                       jamf_instance)
        elif zentral_log_type == "zentral.contrib.jamf.jamf_software_server":
            event = self.build_software_server_event(raw_event_d)
        elif zentral_log_type == "zentral.contrib.jamf.jss_access":
            event = self.build_access_event(raw_event_d)
        elif zentral_log_type == "zentral.contrib.jamf.client":
            event = self.build_client_event(raw_event_d)
        else:
            logger.warning("Unknown zentral_log_type %s", zentral_log_type)
            return

        if event:
            # add EventRequest
            user_agent, ip_address = get_user_agent_and_ip_address_from_raw_event(
                raw_event_d)
            event.metadata.request = EventRequest(user_agent, ip_address)
            # if possible add jamf instance as EventObserver
            if jamf_instance:
                event.metadata.observer = EventObserver.deserialize(
                    jamf_instance.observer_dict())
            yield event
예제 #2
0
def user_login_failed_callback(sender, credentials, **kwargs):
    request = kwargs.get("request")  # introduced in django 1.11
    if request:
        request = EventRequest.build_from_request(request)
    metadata = EventMetadata(request=request)
    event = FailedLoginEvent(metadata, {"user": {k: str(v) for k, v in credentials.items() if k in ("username",)}})
    event.post()
예제 #3
0
def post_results(msn, user_agent, ip, results):
    event_uuid = uuid.uuid4()
    if user_agent or ip:
        request = EventRequest(user_agent, ip)
    else:
        request = None
    cc_status_agg = ComplianceCheckStatusAggregator(msn)
    for index, result in enumerate(_iter_cleaned_up_records(results)):
        try:
            event_time = _get_record_created_at(result)
        except Exception:
            logger.exception("Could not extract osquery result time")
            event_time = None
        metadata = EventMetadata(uuid=event_uuid,
                                 index=index,
                                 machine_serial_number=msn,
                                 request=request,
                                 created_at=event_time)
        event = OsqueryResultEvent(metadata, result)
        event.post()
        snapshot = event.payload.get("snapshot")
        if snapshot is None:
            # no snapshot, cannot be a compliance check
            continue
        try:
            _, query_pk, query_version = event.parse_result_name()
        except ValueError as e:
            logger.warning(str(e))
            continue
        cc_status_agg.add_result(query_pk, query_version, event_time, snapshot)
    cc_status_agg.commit_and_post_events()
예제 #4
0
def post_group_membership_updates(request, added_groups, removed_groups, user=None):
    event_request = EventRequest.build_from_request(request)
    created_at = datetime.utcnow()
    event_uuid = uuid.uuid4()
    event_index = 0
    base_payload = {}
    if user:
        base_payload["user"] = {
            "pk": user.pk, "username": user.username,
            "is_service_account": user.is_service_account
        }
    if added_groups:
        for added_group in added_groups:
            event_metadata = EventMetadata(request=event_request,
                                           uuid=event_uuid, index=event_index,
                                           created_at=created_at)
            payload = base_payload.copy()
            payload["group"] = {"pk": added_group.pk, "name": added_group.name}
            event = AddUserToGroupEvent(event_metadata, payload)
            event.post()
            event_index += 1
    if removed_groups:
        for removed_group in removed_groups:
            event_metadata = EventMetadata(request=event_request,
                                           uuid=event_uuid, index=event_index,
                                           created_at=created_at)
            payload = base_payload.copy()
            payload["group"] = {"pk": removed_group.pk, "name": removed_group.name}
            event = RemoveUserFromGroupEvent(event_metadata, payload)
            event.post()
            event_index += 1
예제 #5
0
def post_event(event_cls, request, user, payload=None):
    if payload is None:
        payload = {}
    metadata = EventMetadata(request=EventRequest.build_from_request(request))
    if user and user != request.user:
        payload["user"] = {"pk": user.pk, "username": user.username}
    event = event_cls(metadata, payload)
    event.post()
예제 #6
0
def post_sync_started_event(instance, serialized_event_request):
    request = None
    if serialized_event_request:
        request = EventRequest.deserialize(serialized_event_request)
    metadata = EventMetadata(request=request)
    event = WSOneInstanceSyncStarted(
        metadata, {"instance": instance.serialize_for_event()})
    event.post()
예제 #7
0
def post_munki_request_event(msn, user_agent, ip, **kwargs):
    metadata = EventMetadata(
        machine_serial_number=msn,
        request=EventRequest(user_agent, ip),
        incident_updates=kwargs.pop("incident_updates", [])
    )
    event = MunkiRequestEvent(metadata, kwargs)
    event.post()
예제 #8
0
파일: __init__.py 프로젝트: zbuc/zentral
def user_login_failed_callback(sender, credentials, **kwargs):
    request = kwargs.get("request")  # introduced in django 1.11
    if request:
        request = EventRequest.build_from_request(request)
    metadata = EventMetadata(FailedLoginEvent.event_type,
                             request=request,
                             tags=FailedLoginEvent.tags)
    event = FailedLoginEvent(metadata, credentials)
    event.post()
예제 #9
0
def post_enrollment_secret_verification_success(request, model):
    obj = getattr(request.enrollment_secret, model)
    event_cls = EnrollmentSecretVerificationEvent
    metadata = EventMetadata(machine_serial_number=request.serial_number,
                             request=EventRequest(request.user_agent, request.public_ip_address))
    payload = {"status": "success",
               "type": model}
    payload.update(obj.serialize_for_event())
    event = event_cls(metadata, payload)
    event.post()
예제 #10
0
def post_monolith_sync_catalogs_request(user_agent, ip):
    event_class = MonolithSyncCatalogsRequestEvent
    if user_agent or ip:
        request = EventRequest(user_agent, ip)
    else:
        request = None
    metadata = EventMetadata(event_class.event_type,
                             request=request,
                             tags=event_class.tags)
    event = event_class(metadata, {})
    event.post()
예제 #11
0
def post_sync_finished_event(instance, serialized_event_request, result):
    request = None
    if serialized_event_request:
        request = EventRequest.deserialize(serialized_event_request)
    metadata = EventMetadata(request=request)
    event = WSOneInstanceSyncFinished(
        metadata, {
            "instance": instance.serialize_for_event(),
            "sync": result
        })
    event.post()
예제 #12
0
def post_monolith_repository_updates(repository, payloads, request=None):
    event_class = MonolithRepositoryUpdateEvent
    repository_serialized_info = repository.serialize_for_event()
    if request:
        request = EventRequest.build_from_request(request)
    event_uuid = uuid.uuid4()
    for index, payload in enumerate(payloads):
        metadata = EventMetadata(uuid=event_uuid, index=index, request=request)
        payload.update({"repository": repository_serialized_info})
        event = event_class(metadata, payload)
        event.post()
예제 #13
0
def make_event(ip=None, ua=None, with_msn=True):
    msn = request = None
    if with_msn:
        msn = "0123456789"
    if ip or ua:
        request = EventRequest(user_agent=ua, ip=ip)
    else:
        request = None
    return TestEvent3(
        EventMetadata(machine_serial_number=msn, request=request),
        {"godzilla": "yo"})
예제 #14
0
 def _deserialize_event(self, doc):
     doc.pop('stored_at')
     event_type = doc.pop('event_type')
     payload = doc.pop('payload')
     user_agent, ip = doc.pop('user_agent'), doc.pop('ip')
     if user_agent or ip:
         doc['request'] = EventRequest(user_agent, ip)
     else:
         doc['request'] = None
     event_cls = event_cls_from_type(event_type)
     event = event_cls(EventMetadata(event_type, **doc), payload)
     return event
예제 #15
0
파일: __init__.py 프로젝트: zbuc/zentral
def post_event(event_cls, request, user):
    request = EventRequest.build_from_request(request)
    payload = {}
    # TODO: check if user can be different than request.user
    # remove the following bit if not
    eru = EventRequestUser.build_from_user(user)
    if eru:
        payload["user"] = eru.serialize()
    metadata = EventMetadata(event_cls.event_type,
                             request=request,
                             tags=event_cls.tags)
    event = event_cls(metadata, payload)
    event.post()
예제 #16
0
파일: __init__.py 프로젝트: zbuc/zentral
def post_munki_events(msn, user_agent, ip, data):
    for report in data:
        events = report.pop('events')
        metadata = EventMetadata(MunkiEvent.event_type,
                                 machine_serial_number=msn,
                                 request=EventRequest(user_agent, ip),
                                 tags=MunkiEvent.tags)
        for index, (created_at, payload) in enumerate(events):
            metadata.index = index
            metadata.created_at = parser.parse(created_at)
            payload.update(report)
            event = MunkiEvent(metadata, payload)
            event.post()
예제 #17
0
def make_event(idx=0, first_type=True, with_request=True):
    if first_type:
        event_cls = TestEvent1
    else:
        event_cls = TestEvent2
    if with_request:
        request = EventRequest("python_unittest_useragent", "10.0.0.1")
    else:
        request = None
    return event_cls(
        EventMetadata(event_cls.event_type,
                      machine_serial_number='012356789',
                      request=request), {'idx': idx})
예제 #18
0
 def post(self, request, *args, **kwargs):
     instance = get_object_or_404(Instance, pk=self.kwargs["pk"])
     event_request = EventRequest.build_from_request(request)
     result = sync_inventory.apply_async(
         (instance.pk, event_request.serialize()))
     return Response(
         {
             "task_id":
             result.id,
             "task_result_url":
             reverse("base_api:task_result", args=(result.id, ))
         },
         status=status.HTTP_201_CREATED)
예제 #19
0
def post_osquery_pack_update_events(request, pack_data, pack_queries_data):
    event_request = EventRequest.build_from_request(request)
    pack_update_event_metadata = EventMetadata(request=event_request)
    pack_update_event = OsqueryPackUpdateEvent(pack_update_event_metadata,
                                               pack_data)
    pack_update_event.post()
    for idx, pack_query_data in enumerate(pack_queries_data):
        pack_query_update_event_metadata = EventMetadata(
            request=event_request,
            uuid=pack_update_event_metadata.uuid,
            index=idx + 1)
        pack_query_update_event = OsqueryPackQueryUpdateEvent(
            pack_query_update_event_metadata, pack_query_data)
        pack_query_update_event.post()
예제 #20
0
def post_santa_ruleset_update_events(request, ruleset_data, rules_data):
    event_request = EventRequest.build_from_request(request)
    ruleset_update_event_metadata = EventMetadata(request=event_request)
    ruleset_update_event = SantaRuleSetUpdateEvent(
        ruleset_update_event_metadata, ruleset_data)
    ruleset_update_event.post()
    for idx, rule_data in enumerate(rules_data):
        rule_update_event_metadata = EventMetadata(
            request=event_request,
            uuid=ruleset_update_event_metadata.uuid,
            index=idx + 1)
        rule_update_event = SantaRuleUpdateEvent(rule_update_event_metadata,
                                                 rule_data)
        rule_update_event.post()
예제 #21
0
def post_enrollment_secret_verification_failure(model,
                                                user_agent, public_ip_address, serial_number,
                                                err_msg, enrollment_secret):
    event_cls = EnrollmentSecretVerificationEvent
    metadata = EventMetadata(machine_serial_number=serial_number,
                             request=EventRequest(user_agent, public_ip_address))
    payload = {"status": "failure",
               "reason": err_msg,
               "type": model}
    if enrollment_secret:
        obj = getattr(enrollment_secret, model)
        payload.update(obj.serialize_for_event())
    event = event_cls(metadata, payload)
    event.post()
예제 #22
0
파일: __init__.py 프로젝트: dekoder/zentral
def post_event(event_cls, request, user, payload=None):
    if payload is None:
        payload = {}

    # TODO: check if user can be different than request.user
    # remove the following bit if not
    eru = EventRequestUser.build_from_user(user)
    if eru:
        payload["user"] = eru.serialize()
        seabc = request.session.get_expire_at_browser_close()
        payload["session"] = {"expire_at_browser_close": seabc}
        if not seabc:
            payload["session"].update(
                {"expiry_age": request.session.get_expiry_age()})

    # realm user
    payload["realm_session"] = False
    ras_uuid = request.session.get("_realm_authentication_session")
    if ras_uuid:
        try:
            ras = RealmAuthenticationSession.objects.select_related(
                "realm", "user").get(uuid=ras_uuid)
        except RealmAuthenticationSession.DoesNotExist:
            logger.error("Could not find realm authentication session %s",
                         ras_uuid)
        else:
            realm = ras.realm
            payload["realm_session"] = True
            payload["realm_user"] = {
                "realm": {
                    "uuid": realm.uuid,
                    "name": str(realm),
                    "backend": realm.backend
                },
                "session": {
                    "uuid": ras.uuid,
                    "created_at": ras.created_at,
                    "updated_at": ras.updated_at,
                    "expires": ras.expires_at is not None,
                    "expires_at": ras.expires_at
                },
                "uuid": ras.user.uuid
            }

    event_request = EventRequest.build_from_request(request)
    metadata = EventMetadata(event_cls.event_type,
                             request=event_request,
                             tags=event_cls.tags)
    event = event_cls(metadata, payload)
    event.post()
예제 #23
0
def post_okta_events(event_hook, data):
    event_observer = EventObserver(**event_hook.observer_dict())
    for event in data["data"]["events"]:
        event_type = event["eventType"]
        if event_type == "user.session.start":
            event_cls = OktaUserSessionStart
        elif event_type == "user.session.end":
            event_cls = OktaUserSessionEnd
        else:
            logger.error("Unknown Okta event type '%s'", event_type)
            continue
        client_d = event.get("client")
        client_ip = client_d.get("ipAddress")
        client_user_agent = client_d.get("userAgent", {}).get("rawUserAgent")
        client_geo = client_d.get("geographicalContext", {})
        if client_geo:
            event_request_geo = EventRequestGeo(
                country_name=client_geo.get("country"),
                city_name=client_geo.get("city"),
                region_name=client_geo.get("state"),
                location=client_geo.get("geolocation"))
        else:
            event_request_geo = None
        payload = {}
        event_actor = event.get("actor")
        if event_actor:
            payload["actor"] = event_actor
        event_outcome = event.get("outcome")
        if event_outcome:
            payload["outcome"] = event_outcome
        if not payload:
            logger.error("Empty event payload from Okta event")
            continue
        # event
        try:
            created_at = parser.parse(event["published"])
        except (KeyError, TypeError, ValueError):
            logger.error("Could not parse datetime from Okta event")
            created_at = None
        event_metadata = EventMetadata(event_cls.event_type,
                                       request=EventRequest(
                                           client_user_agent,
                                           client_ip,
                                           geo=event_request_geo),
                                       observer=event_observer,
                                       created_at=created_at,
                                       tags=event_cls.tags)
        event = event_cls(event_metadata, payload)
        event.post()
예제 #24
0
 def _deserialize_event(self, doc):
     doc.pop('stored_at')
     event_type = doc.pop('event_type')
     payload = doc.pop('payload')
     request_d = {
         k: v
         for k, v in ((a, doc.pop(a)) for a in ('user_agent', 'ip', 'user'))
         if v
     }
     if request_d:
         doc['request'] = EventRequest.deserialize(request_d)
     else:
         doc['request'] = None
     event_cls = event_cls_from_type(event_type)
     event = event_cls(EventMetadata(event_type, **doc), payload)
     return event
예제 #25
0
def post_monolith_cache_server_update_request(request,
                                              cache_server=None,
                                              errors=None):
    event_class = MonolithUpdateCacheServerRequestEvent
    event_request = EventRequest.build_from_request(request)
    metadata = EventMetadata(request=event_request)
    if cache_server:
        payload = cache_server.serialize()
        payload["status"] = 0
    else:
        # flatten errors
        payload = {
            "errors": {attr: ", ".join(err)
                       for attr, err in errors.items()}
        }
        payload["status"] = 1
    event = event_class(metadata, payload)
    event.post()
예제 #26
0
def post_monolith_cache_server_update_request(user_agent, ip, cache_server=None, errors=None):
    event_class = MonolithUpdateCacheServerRequestEvent
    if user_agent or ip:
        request = EventRequest(user_agent, ip)
    else:
        request = None
    metadata = EventMetadata(event_class.event_type,
                             request=request,
                             tags=event_class.tags)
    if cache_server:
        payload = cache_server.serialize()
        payload["status"] = 0
    else:
        # flatten errors
        payload = {"errors": {attr: ", ".join(err) for attr, err in errors.items()}}
        payload["status"] = 1
    event = event_class(metadata, payload)
    event.post()
예제 #27
0
def post_munki_events(msn, user_agent, ip, data):
    for report in data:
        events = report.pop('events')
        event_uuid = uuid.uuid4()
        for event_index, (created_at, payload) in enumerate(events):
            # event type
            try:
                failed = int(payload["status"]) != 0
            except (KeyError, ValueError):
                failed = True
            payload_type = payload.get("type")
            if payload_type == "install":
                if failed:
                    event_cls = MunkiInstallFailedEvent
                else:
                    event_cls = MunkiInstallEvent
            elif payload_type == "removal":
                if failed:
                    event_cls = MunkiRemovalFailedEvent
                else:
                    event_cls = MunkiRemovalEvent
            elif payload_type == "warning":
                event_cls = MunkiWarningEvent
            elif payload_type == "error":
                event_cls = MunkiErrorEvent
            elif payload_type == "start":
                event_cls = MunkiStartEvent
            else:
                logger.error("Unknown munki event payload type %s", payload_type)
                continue

            # build event
            metadata = EventMetadata(
                uuid=event_uuid,
                index=event_index,
                machine_serial_number=msn,
                request=EventRequest(user_agent, ip),
                created_at=parser.parse(created_at),
                incident_updates=payload.pop("incident_updates", []),
            )
            payload.update(report)
            event = event_cls(metadata, payload)
            event.post()
예제 #28
0
 def post(self, request, *args, **kwargs):
     serializer = CleanupInventorySerializer(data=request.data)
     if serializer.is_valid():
         event_request = EventRequest.build_from_request(request)
         result = cleanup_inventory.apply_async((
             serializer.data["days"],
             event_request.serialize(),
         ))
         return Response(
             {
                 "task_id":
                 result.id,
                 "task_result_url":
                 reverse("base_api:task_result", args=(result.id, ))
             },
             status=status.HTTP_201_CREATED)
     else:
         return Response(serializer.errors,
                         status=status.HTTP_400_BAD_REQUEST)
예제 #29
0
파일: utils.py 프로젝트: janheise/zentral
def update_incident_status(incident, new_status, request):
    incident = Incident.objects.select_for_update().get(pk=incident.pk)
    if new_status not in incident.get_next_statuses():
        return incident, None
    previous_status = {
        "status": incident.status,
        "status_time": incident.status_time
    }
    incident.status = new_status.value
    incident.status_time = datetime.utcnow()
    incident.save()

    # build event
    event_payload = incident.serialize_for_event()
    event_payload["previous_status"] = previous_status
    event = IncidentStatusUpdatedEvent(
        EventMetadata(request=EventRequest.build_from_request(request)),
        event_payload)

    return incident, event
예제 #30
0
파일: utils.py 프로젝트: janheise/zentral
def update_machine_incident_status(machine_incident, new_status, request):
    machine_incident = (MachineIncident.objects.select_for_update().
                        select_related("incident").get(pk=machine_incident.pk))
    if new_status not in machine_incident.get_next_statuses():
        return machine_incident, None
    previous_status = {
        "status": machine_incident.status,
        "status_time": machine_incident.status_time
    }
    machine_incident.status = new_status.value
    machine_incident.status_time = datetime.utcnow()
    machine_incident.save()

    # build event
    event_payload = machine_incident.serialize_for_event()
    event_payload["machine_incident"]["previous_status"] = previous_status
    event = MachineIncidentStatusUpdatedEvent(
        EventMetadata(request=EventRequest.build_from_request(request)),
        event_payload)

    return machine_incident, event