Example #1
0
from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type

logger = logging.getLogger('zentral.contrib.osquery.events')

__all__ = ['OsqueryEnrollmentEvent', 'OsqueryResultEvent', 'OsqueryStatusEvent']


class OsqueryEvent(BaseEvent):
    pass


class OsqueryEnrollmentEvent(OsqueryEvent):
    event_type = "osquery_enrollment"


register_event_type(OsqueryEnrollmentEvent)


class OsqueryRequestEvent(OsqueryEvent):
    event_type = "osquery_request"

register_event_type(OsqueryRequestEvent)


class OsqueryResultEvent(OsqueryEvent):
    event_type = "osquery_result"

    def __init__(self, *args, **kwargs):
        super(OsqueryResultEvent, self).__init__(*args, **kwargs)
        self._set_probe_and_query_from_payload()
Example #2
0
from zentral.contrib.santa import probes_lookup_dict
from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type

logger = logging.getLogger('zentral.contrib.santa.events')

__all__ = ['post_santa_events', 'post_santa_preflight', 'SantaEventEvent', 'SantaPreflightEvent']


class SantaBaseEvent(BaseEvent):
    pass


class SantaPreflightEvent(SantaBaseEvent):
    event_type = "santa_preflight"

register_event_type(SantaPreflightEvent)


class SantaEventEvent(SantaBaseEvent):
    event_type = "santa_event"

    def __init__(self, *args, **kwargs):
        super(SantaBaseEvent, self).__init__(*args, **kwargs)
        self.rule_probes = self._get_rule_probes()

    def _get_rule_probes(self):
        """Find the probes that could have triggered the event."""
        # TODO: the whole zentral contrib app works only with sha256
        # TODO: we could do a better job and try to match the policy
        #       with the santa event "decision" attr and remove some extra matching probes
Example #3
0
import logging
from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type

logger = logging.getLogger('zentral.contrib.jss.events')


class JSSEvent(BaseEvent):
    event_type = "jss_event"

register_event_type(JSSEvent)


def post_jss_event(msn, user_agent, ip, data):
    metadata = EventMetadata(JSSEvent.event_type,
                             machine_serial_number=msn,
                             request=EventRequest(user_agent, ip))
    event = JSSEvent(metadata, data)
    event.post()
Example #4
0
logger = logging.getLogger('zentral.contrib.nagios.events')


ALL_EVENTS_SEARCH_DICT = {"tag": "nagios"}


class NagiosEvent(BaseEvent):
    tags = ["nagios"]


class NagiosHostEvent(NagiosEvent):
    event_type = "nagios_host_event"


register_event_type(NagiosHostEvent)


class NagiosServiceEvent(NagiosEvent):
    event_type = "nagios_service_event"


register_event_type(NagiosServiceEvent)


def post_nagios_event(nagios_instance, user_agent, ip, data):
    event_type = data.pop("event_type", None)
    if not event_type:
        logger.warning("Missing event_type in nagios event payload")
        return
    elif event_type not in ['nagios_host_event', 'nagios_service_event']:
Example #5
0
import logging
from zentral.core.events import event_cls_from_type, register_event_type
from zentral.core.events.base import BaseEvent, EventMetadata

logger = logging.getLogger('zentral.contrib.inventory.events')

ALL_EVENTS_SEARCH_DICT = {"tag": "inventory_update"}


class InventoryMachineAdded(BaseEvent):
    event_type = 'inventory_machine_added'


register_event_type(InventoryMachineAdded)


class InventoryHeartbeat(BaseEvent):
    event_type = 'inventory_heartbeat'
    tags = ['heartbeat']


register_event_type(InventoryHeartbeat)

# Inventory update events
for attr in ('reference', 'machine', 'link', 'business_unit', 'group',
             'os_version', 'system_info', 'network_interface',
             'osx_app_instance', 'deb_package', 'teamviewer',
             'puppetdb_inventory'):
    event_type = 'inventory_{}_update'.format(attr)
    event_class_name = "".join(s.title() for s in event_type.split('_'))
    event_class = type(event_class_name, (BaseEvent, ), {
Example #6
0
}

for jamf_event, (event_subtype, is_heartbeat,
                 heartbeat_timeout) in JAMF_EVENTS.items():
    event_type = 'jamf_{}'.format(event_subtype)
    event_class_name = "".join(s.title() for s in event_type.split('_'))
    tags = ['jamf', 'jamf_webhook']
    if is_heartbeat:
        tags.append('heartbeat')
    event_class = type(
        event_class_name, (BaseEvent, ), {
            'event_type': event_type,
            'tags': tags,
            'heartbeat_timeout': heartbeat_timeout
        })
    register_event_type(event_class)


class JAMFChangeManagementEvent(BaseEvent):
    event_type = "jamf_change_management"
    tags = ["jamf", "jamf_beat"]
    payload_aggregations = [
        ("jamf_instance.host", {
            "type": "terms",
            "bucket_number": 10,
            "label": "Hosts"
        }),
        ("action", {
            "type": "terms",
            "bucket_number": 10,
            "label": "Actions"
Example #7
0
    "RestAPIOperation": ("rest_api_operation", False, None),
    "SCEPChallenge": ("scep_challenge", False, None),
    "SmartGroupComputerMembershipChange":
    ("smart_group_computer_membership_change", False, None),
    "SmartGroupMobileDeviceMembershipChange":
    ("smart_group_mobile_device_membership_change", False, None)
}

for jss_event, (event_subtype, is_heartbeat,
                heartbeat_timeout) in JSS_EVENTS.items():
    event_type = 'jss_{}'.format(event_subtype)
    event_class_name = "".join(s.title() for s in event_type.split('_'))
    tags = ['jss']
    if is_heartbeat:
        tags.append('heartbeat')
    event_class = type(
        event_class_name, (BaseEvent, ), {
            'event_type': event_type,
            'tags': tags,
            'heartbeat_timeout': heartbeat_timeout
        })
    register_event_type(event_class)


def post_jss_event(user_agent, ip, data):
    event_cls = event_cls_from_type('jss_{}'.format(
        JSS_EVENTS[data["webhook"]["webhookEvent"]][0]))
    payload = data["event"]
    msn = payload.get("serialNumber", None)
    event_cls.post_machine_request_payloads(msn, user_agent, ip, [payload])
Example #8
0
import logging
from dateutil import parser
from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type

logger = logging.getLogger("zentral.contrib.munki.events")


class MunkiEvent(BaseEvent):
    event_type = "munki_event"


register_event_type(MunkiEvent)


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))
        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()
Example #9
0
import logging
from zentral.core.events import register_event_type
from zentral.core.events.base import BaseEvent

logger = logging.getLogger('zentral.contrib.mdm.events')

ALL_EVENTS_SEARCH_DICT = {"tag": "mdm"}


class OTAEnrollmentRequestEvent(BaseEvent):
    event_type = "ota_enrollment_request"
    tags = ["mdm", "heartbeat"]


register_event_type(OTAEnrollmentRequestEvent)


class MDMRequestEvent(BaseEvent):
    event_type = "mdm_request"
    tags = ["mdm", "heartbeat"]


register_event_type(MDMRequestEvent)
Example #10
0
import logging
import re
from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type, CommandEvent

COMMAND_RE = re.compile(r"zentral\$(?P<command>[a-zA-Z_]+)\$"
                        "(?P<serial_numbers>(?:[a-zA-Z0-9]+\$)+)+"
                        "(?P<arg>[a-zA-Z0-9]+)")

logger = logging.getLogger('zentral.contrib.zendesk.events')


class ZendeskTicketCreationEvent(BaseEvent):
    event_type = "zendesk_ticket_creation"

register_event_type(ZendeskTicketCreationEvent)


class ZendeskCommentCreationEvent(BaseEvent):
    event_type = "zendesk_comment_creation"

register_event_type(ZendeskCommentCreationEvent)


def post_zendesk_event(user_agent, ip, data):
    data_type = data['type']
    data = data['data']
    if data_type == 'ticket':
        event_class = ZendeskTicketCreationEvent
    elif data_type == 'comment':
        event_class = ZendeskCommentCreationEvent
        if not data['is_public']:
Example #11
0
        keys = {}
        pk = self.payload.get("pk")
        if pk:
            keys["incident"] = [(pk, )]
        machine_incident_pk = self.payload.get("machine_incident",
                                               {}).get("pk")
        if machine_incident_pk:
            keys["machine_incident"] = [(machine_incident_pk, )]
        return keys


class IncidentCreatedEvent(BaseIncidentEvent):
    event_type = 'incident_created'


register_event_type(IncidentCreatedEvent)


class IncidentSeverityUpdatedEvent(BaseIncidentEvent):
    event_type = 'incident_severity_updated'


register_event_type(IncidentSeverityUpdatedEvent)


class IncidentStatusUpdatedEvent(BaseIncidentEvent):
    event_type = 'incident_status_updated'


register_event_type(IncidentStatusUpdatedEvent)
Example #12
0
    "ComputerPolicyFinished": "computer_policy_finished",
    "ComputerPushCapabilityChanged": "computer_push_capability_changed",
    "JSSShutdown": "shutdown",
    "JSSStartup": "startup",
    "MobileDeviceCheckIn": "mobile_device_checkin",
    "MobileDeviceCommandCompleted": "mobile_device_command_completed",
    "MobileDeviceEnrolled": "mobile_device_enrolled",
    "MobileDevicePushSent": "mobile_device_push_sent",
    "MobileDeviceUnEnrolled": "mobile_device_unenrolled",
    "PatchSoftwareTitleUpdated": "patch_software_title_updated",
    "PushSent": "push_sent",
    "RestAPIOperation": "rest_api_operation",
    "SCEPChallenge": "scep_challenge",
    "SmartGroupComputerMembershipChange": "smart_group_computer_membership_change",
    "SmartGroupMobileDeviceMembershipChange": "smart_group_mobile_device_membership_change",
}


for jss_event, event_subtype in JSS_EVENTS.items():
    event_type = "jss_{}".format(event_subtype)
    event_class_name = "".join(s.title() for s in event_type.split("_"))
    event_class = type(event_class_name, (BaseEvent,), {"event_type": event_type, "tags": ["jss"]})
    register_event_type(event_class)


def post_jss_event(user_agent, ip, data):
    event_cls = event_cls_from_type("jss_{}".format(JSS_EVENTS[data["webhook"]["webhookEvent"]]))
    payload = data["event"]
    msn = payload.get("serialNumber", None)
    event_cls.post_machine_request_payloads(msn, user_agent, ip, [payload])
Example #13
0
    namespace = "wsone_event"
    tags = ["wsone", "wsone_event"]

    def get_linked_objects_keys(self):
        keys = {}
        observer = self.metadata.observer
        if observer and observer.content_type == "wsone.instance" and observer.pk:
            keys["wsone_instance"] = [(observer.pk, )]
        return keys


class WSOneComplianceStatusChanged(BaseWSOneEvent):
    event_type = "wsone_compliance_status_changed"


register_event_type(WSOneComplianceStatusChanged)


class WSOneCompromisedStatusChanged(BaseWSOneEvent):
    event_type = "wsone_compromised_status_changed"


register_event_type(WSOneCompromisedStatusChanged)


class WSOneMDMEnrollmentComplete(BaseWSOneEvent):
    event_type = "wsone_mdm_enrollment_complete"


register_event_type(WSOneMDMEnrollmentComplete)
Example #14
0
import logging
from zentral.core.events import BaseEvent, EventMetadata, event_cls_from_type, register_event_type

logger = logging.getLogger('zentral.contrib.inventory.events')


class InventoryMachineAdded(BaseEvent):
    event_type = 'inventory_machine_added'


register_event_type(InventoryMachineAdded)


# Inventory update events
for attr in ('reference',
             'machine',
             'link',
             'business_unit',
             'group',
             'os_version',
             'system_info',
             'osx_app_instance',
             'teamviewer'):
    event_type = 'inventory_{}_update'.format(attr)
    event_class_name = "".join(s.title() for s in event_type.split('_'))
    event_class = type(event_class_name, (BaseEvent,), {'event_type': event_type})
    register_event_type(event_class)


def post_inventory_events(msn, events, uuid, index):
    for event_type, data in events:
Example #15
0
from zentral.core.events import register_event_type
from zentral.core.events.base import BaseEvent, EventMetadata, EventObserver, EventRequest, EventRequestGeo


logger = logging.getLogger('zentral.contrib.okta.events')


ALL_EVENTS_SEARCH_DICT = {"tag": "okta"}


class OktaUserSessionStart(BaseEvent):
    event_type = "okta_user_session_start"
    tags = ["okta"]


register_event_type(OktaUserSessionStart)


class OktaUserSessionEnd(BaseEvent):
    event_type = "okta_user_session_end"
    tags = ["okta"]


register_event_type(OktaUserSessionEnd)


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":
Example #16
0
               "SCEPChallenge": ("scep_challenge", False, None),
               "SmartGroupComputerMembershipChange": ("smart_group_computer_membership_change", False, None),
               "SmartGroupMobileDeviceMembershipChange": ("smart_group_mobile_device_membership_change", False, None)}


for jamf_event, (event_subtype, is_heartbeat, heartbeat_timeout) in JAMF_EVENTS.items():
    event_type = 'jamf_{}'.format(event_subtype)
    event_class_name = "".join(s.title() for s in event_type.split('_'))
    tags = ['jamf', 'jamf_webhook']
    if is_heartbeat:
        tags.append('heartbeat')
    event_class = type(event_class_name, (BaseEvent,),
                       {'event_type': event_type,
                        'tags': tags,
                        'heartbeat_timeout': heartbeat_timeout})
    register_event_type(event_class)


class JAMFChangeManagementEvent(BaseEvent):
    event_type = "jamf_change_management"
    tags = ["jamf", "jamf_beat"]
    payload_aggregations = [
        ("jamf_instance.host", {"type": "terms", "bucket_number": 10, "label": "Hosts"}),
        ("action", {"type": "terms", "bucket_number": 10, "label": "Actions"}),
        ("object.type", {"type": "terms", "bucket_number": 10, "label": "Object types"}),
    ]


register_event_type(JAMFChangeManagementEvent)

Example #17
0
from zentral.core.events.base import BaseEvent

logger = logging.getLogger('zentral.contrib.nagios.events')

ALL_EVENTS_SEARCH_DICT = {"tag": "nagios"}


class NagiosEvent(BaseEvent):
    tags = ["nagios"]


class NagiosHostEvent(NagiosEvent):
    event_type = "nagios_host_event"


register_event_type(NagiosHostEvent)


class NagiosServiceEvent(NagiosEvent):
    event_type = "nagios_service_event"


register_event_type(NagiosServiceEvent)


def post_nagios_event(nagios_instance, user_agent, ip, data):
    event_type = data.pop("event_type", None)
    if not event_type:
        logger.warning("Missing event_type in nagios event payload")
        return
    elif event_type not in ['nagios_host_event', 'nagios_service_event']:
Example #18
0
import json
import unittest
import redis
from zentral.core.events import EventMetadata, EventRequest, BaseEvent, register_event_type
from zentral.core.queues.backends.redisq import EventQueues


class TestQueueEvent(BaseEvent):
    event_type = "event_test_queue"

register_event_type(TestQueueEvent)


class TestEventQueues(unittest.TestCase):
    CONFIG = {'db': 1,
              'host': 'redis',
              'stores': ['postgres']}
    EVENT = TestQueueEvent(EventMetadata(TestQueueEvent.event_type,
                                         machine_serial_number='012356789',
                                         request=EventRequest("python_unittest_useragent",
                                                              "10.0.0.1")),
                           {'payload': 'ok'})

    def setUp(self):
        self.r = redis.Redis(host='redis', port=6379, db=self.CONFIG['db'])
        self.rq = EventQueues(self.CONFIG)

    def test_post_event(self):
        event_id = self.rq.post_event(self.EVENT)

        self.assertEqual(json.loads(self.r.get(event_id).decode('utf-8')), self.EVENT.serialize())
Example #19
0
logger = logging.getLogger('zentral.contrib.inventory.events')


ALL_EVENTS_SEARCH_DICT = {"tag": "machine"}


# Inventory update events


class InventoryHeartbeat(BaseEvent):
    event_type = 'inventory_heartbeat'
    namespace = "inventory"
    tags = ['heartbeat', 'machine']


register_event_type(InventoryHeartbeat)


class AddMachine(BaseEvent):
    event_type = 'add_machine'
    namespace = "inventory"
    tags = ['machine']


register_event_type(AddMachine)


for attr in ('link',
             'business_unit',
             'group',
             'os_version',
Example #20
0
from zentral.core.events import BaseEvent, EventMetadata, register_event_type


class InventoryUpdateEvent(BaseEvent):
    event_type = "inventory_update"

register_event_type(InventoryUpdateEvent)


def post_inventory_event(msn, data, uuid, index):
    event_cls = InventoryUpdateEvent
    metadata = EventMetadata(event_cls.event_type,
                             machine_serial_number=msn,
                             uuid=uuid,
                             index=index)
    event = event_cls(metadata, data)
    event.post()
Example #21
0
import logging
from zentral.core.events import register_event_type
from zentral.core.events.base import BaseEvent
from zentral.core.queues import queues

logger = logging.getLogger('zentral.contrib.puppet.events')

ALL_EVENTS_SEARCH_DICT = {"tag": "puppet"}


class PuppetReportEvent(BaseEvent):
    event_type = "puppet_report"
    tags = ["puppet"]


register_event_type(PuppetReportEvent)


def post_puppet_report(instance, user_agent, ip, report):
    raw_event = {
        "request": {
            "user_agent": user_agent,
            "ip": ip
        },
        "event_type": PuppetReportEvent.event_type,
        "puppet_instance": instance,
        "puppet_report": report
    }
    queues.post_raw_event("puppet_reports", raw_event)
Example #22
0
import logging
from zentral.core.events import register_event_type
from zentral.core.events.base import BaseEvent

logger = logging.getLogger('zentral.contrib.mdm.events')

ALL_EVENTS_SEARCH_DICT = {"tag": "mdm"}


class DEPEnrollmentRequestEvent(BaseEvent):
    event_type = "dep_enrollment_request"
    tags = ["mdm", "dep", "heartbeat"]


register_event_type(DEPEnrollmentRequestEvent)


class OTAEnrollmentRequestEvent(BaseEvent):
    event_type = "ota_enrollment_request"
    tags = ["mdm", "ota", "heartbeat"]


register_event_type(OTAEnrollmentRequestEvent)


class UserEnrollmentRequestEvent(BaseEvent):
    event_type = "user_enrollment_request"
    tags = ["mdm"]


register_event_type(UserEnrollmentRequestEvent)
Example #23
0
from zentral.core.events import EventMetadata, EventRequest, BaseEvent, register_event_type


class TestEvent1(BaseEvent):
    event_type = "event_type_1"

register_event_type(TestEvent1)


class TestEvent2(BaseEvent):
    event_type = "event_type_2"

register_event_type(TestEvent2)


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})

Example #24
0
import logging
import uuid
from zentral.core.events import register_event_type
from zentral.core.events.base import BaseEvent, EventMetadata

logger = logging.getLogger('zentral.contrib.incidents.events')

ALL_EVENTS_SEARCH_DICT = {"tag": "incident"}


class IncidentEvent(BaseEvent):
    event_type = 'incident'
    tags = ["incident"]


register_event_type(IncidentEvent)


class MachineIncidentEvent(BaseEvent):
    event_type = 'machine_incident'
    tags = ["incident"]


register_event_type(MachineIncidentEvent)


def build_incident_events(incident_event_payloads,
                          machine_serial_number=None,
                          request=None):
    incident_events_uuid = uuid.uuid4()
    for incident_event_index, incident_event_payload in enumerate(
Example #25
0
import logging
from zentral.core.events import event_cls_from_type, register_event_type
from zentral.core.events.base import BaseEvent, EventMetadata, EventRequest

logger = logging.getLogger('zentral.contrib.inventory.events')


ALL_EVENTS_SEARCH_DICT = {"tag": "inventory_update"}


class InventoryMachineAdded(BaseEvent):
    event_type = 'inventory_machine_added'


register_event_type(InventoryMachineAdded)


class InventoryHeartbeat(BaseEvent):
    event_type = 'inventory_heartbeat'
    tags = ['heartbeat']


register_event_type(InventoryHeartbeat)


class EnrollmentSecretVerificationEvent(BaseEvent):
    event_type = 'enrollment_secret_verification'


register_event_type(EnrollmentSecretVerificationEvent)