예제 #1
0
 def test_meta_machine(self):
     tree = copy.deepcopy(self.machine_snapshot)
     msc, ms = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     tree = copy.deepcopy(self.machine_snapshot2)
     msc2, ms2 = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     tree = copy.deepcopy(self.machine_snapshot3)
     msc3, ms3 = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     mm = MetaMachine(self.serial_number)
     self.assertEqual(mm.serial_number, self.serial_number)
     self.assertEqual(mm.snapshots, [ms3])
     self.assertEqual(mm.platform, MACOS)
     tag1, _ = Tag.objects.get_or_create(name="tag111")
     tag2, _ = Tag.objects.get_or_create(name="tag222")
     MachineTag.objects.create(tag=tag1, serial_number=self.serial_number)
     self.assertEqual(
         (MACOS, None, {self.meta_business_unit.id}, {tag1.id}),
         mm.get_probe_filtering_values())
     MetaBusinessUnitTag.objects.create(
         tag=tag2, meta_business_unit=self.meta_business_unit)
     self.assertEqual(
         (MACOS, None, {self.meta_business_unit.id}, {tag1.id, tag2.id}),
         mm.get_probe_filtering_values())
     mm.archive()
     mm = MetaMachine(self.serial_number)
     self.assertEqual(mm.snapshots, [])
     self.assertEqual(MachineSnapshot.objects.count(), 3)
     self.assertEqual(MachineSnapshotCommit.objects.count(), 3)
     self.assertEqual(CurrentMachineSnapshot.objects.count(), 0)
예제 #2
0
    def test_meta_machine(self):
        tree = copy.deepcopy(self.machine_snapshot)
        msc, ms, _ = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
            tree)
        tree = copy.deepcopy(self.machine_snapshot2)
        msc2, ms2, _ = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
            tree)
        tree = copy.deepcopy(self.machine_snapshot3)
        msc3, ms3, _ = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
            tree)
        mm = MetaMachine(self.serial_number)
        self.assertEqual(mm.serial_number, self.serial_number)
        self.assertEqual(mm.snapshots, [ms3])
        self.assertEqual(mm.platform, MACOS)
        tag1, _ = Tag.objects.get_or_create(name="tag111")
        tag2, _ = Tag.objects.get_or_create(name="tag222")
        MachineTag.objects.create(tag=tag1, serial_number=self.serial_number)
        self.assertEqual(
            (MACOS, None, {self.meta_business_unit.id}, {tag1.id}),
            mm.get_probe_filtering_values())
        MetaBusinessUnitTag.objects.create(
            tag=tag2, meta_business_unit=self.meta_business_unit)
        # cached
        self.assertEqual(
            (MACOS, None, {self.meta_business_unit.id}, {tag1.id}),
            mm.get_probe_filtering_values())
        # fresh
        mm = MetaMachine(self.serial_number)
        self.assertEqual(
            (MACOS, None, {self.meta_business_unit.id}, {tag1.id, tag2.id}),
            mm.get_probe_filtering_values())
        # cached with cache framework
        mm = MetaMachine(self.serial_number)
        self.assertEqual(
            (MACOS, None, {self.meta_business_unit.id}, {tag1.id, tag2.id}),
            mm.cached_probe_filtering_values)
        self.assertEqual(
            (MACOS, None, {self.meta_business_unit.id}, {tag1.id, tag2.id}),
            cache.get("mm-probe-fvs_{}".format(
                mm.get_urlsafe_serial_number())))

        mm.archive()

        mm = MetaMachine(self.serial_number)
        self.assertEqual(mm.snapshots, [])
        self.assertEqual(MachineSnapshot.objects.count(), 3)
        self.assertEqual(MachineSnapshotCommit.objects.count(), 3)
        self.assertEqual(CurrentMachineSnapshot.objects.count(), 0)
예제 #3
0
 def test_update_open_machine_incident(self):
     event_metadata = EventMetadata(event_type="test", machine_serial_number="YOLOFOMO")
     event_metadata.machine = MockMetaMachine([self.mbu1], [self.tag1],
                                              "WINDOWS", "LAPTOP",
                                              serial_number="YOLOFOMO")
     event = BaseEvent(event_metadata, {"joe": "jackson"})
     self.assertTrue(self.probe.test_event(event))
     machine_incident1, _ = update_or_create_open_machine_incident(
         self.probe_source,
         self.probe.get_matching_event_incident_severity(event),
         event.metadata.machine_serial_number,
         event.metadata.uuid
     )
     machine_incident2, event_payloads = update_or_create_open_machine_incident(
         self.probe_source,
         self.probe.get_matching_event_incident_severity(event) + 100,
         event.metadata.machine_serial_number,
         event.metadata.uuid
     )
     self.assertEqual(machine_incident1, machine_incident2)
     self.assertEqual(machine_incident2.incident, machine_incident1.incident)
     self.assertEqual(machine_incident2.incident.severity, SEVERITY_CRITICAL + 100)
     self.assertEqual(len(event_payloads), 1)
     event_payload = event_payloads[0]
     self.assertEqual(event_payload["action"], "updated")
     self.assertEqual(event_payload["diff"],
                      {"removed": {"severity": SEVERITY_CRITICAL},
                       "added": {"severity": SEVERITY_CRITICAL + 100}})
     self.assertEqual(event_payload["severity"], SEVERITY_CRITICAL + 100)
     self.assertEqual(event_payload.get("incident"), None)
     # meta machine
     self.assertEqual(MetaMachine("YOLOFOMO").max_incident_severity(), SEVERITY_CRITICAL + 100)
 def setUpTestData(cls):
     # user
     cls.user = User.objects.create_user("godzilla", "*****@*****.**",
                                         get_random_string())
     cls.group = Group.objects.create(name=get_random_string())
     cls.user.groups.set([cls.group])
     # machine
     cls.serial_number = "0123456789"
     cls.source_name = get_random_string() + "z"
     MachineSnapshotCommit.objects.commit_machine_snapshot_tree({
         "source": {
             "module": "tests.zentral.io",
             "name": cls.source_name.upper()
         },
         "serial_number":
         cls.serial_number,
         "os_version": {
             'name': 'OS X',
             'major': 10,
             'minor': 11,
             'patch': 1
         },
         "osx_app_instances": [{
             'app': {
                 'bundle_id': 'io.zentral.baller',
                 'bundle_name': 'Baller.app',
                 'bundle_version': '123',
                 'bundle_version_str': '1.2.3'
             },
             'bundle_path': "/Applications/Baller.app"
         }]
     })
     cls.source = Source.objects.get(name=cls.source_name.upper())
     cls.machine = MetaMachine(cls.serial_number)
     cls.url_msn = cls.machine.get_urlsafe_serial_number()
예제 #5
0
    def dispatch(self, request, *args, **kwargs):
        try:
            token = request.META['HTTP_X_MONOLITH_TOKEN'].strip()
            api_data = verify_secret(token, 'zentral.contrib.monolith')
        except (KeyError, ValueError, APIAuthError):
            return HttpResponseForbidden("No no no!")

        # machine serial number
        h_msn = request.META.get("HTTP_X_ZENTRAL_SERIAL_NUMBER")  # new way
        t_msn = api_data.get("machine_serial_number")  # old way
        if h_msn and t_msn and h_msn != t_msn:
            logger.warning("Serial number mismatch. header: %s, token: %s",
                           h_msn, t_msn)
        self.machine_serial_number = h_msn or t_msn  # priority to h_msn because set in preflight script

        # business unit, manifest
        self.meta_business_unit = api_data['business_unit'].meta_business_unit
        self.manifest = get_object_or_404(
            Manifest, meta_business_unit=self.meta_business_unit)

        self.user_agent, self.ip = user_agent_and_ip_address_from_request(
            request)

        # machine extra infos
        self.machine = MetaMachine(self.machine_serial_number)
        self.tags = self.machine.tags

        if not self.machine_serial_number:
            logger.warning("Missing serial number. mbu: %s %s",
                           self.meta_business_unit, self.meta_business_unit.pk)

        return super().dispatch(request, *args, **kwargs)
예제 #6
0
파일: views.py 프로젝트: dekoder/zentral
 def commit_machine_snapshot(self, max_age=3600):
     module = 'zentral.contrib.jamf_protect'
     if MetaMachine(self.serial_number).has_recent_source_snapshot(
             module, max_age):
         logger.debug(
             "Skip Jamf Protect machine snapshot commit for machine %s.",
             self.serial_number)
         return
     tree = {
         'source': {
             'module': module,
             'name': 'Jamf Protect'
         },
         'reference': self.serial_number,
         'serial_number': self.serial_number,
         'public_ip_address': self.ip
     }
     hostname = self.event.get("host", {}).get("hostname")
     if hostname:
         tree['system_info'] = {'computer_name': hostname}
     business_unit = self.enrolled_machine.enrollment.secret.get_api_enrollment_business_unit(
     )
     if business_unit:
         tree['business_unit'] = business_unit.serialize()
     commit_machine_snapshot_and_trigger_events(tree)
예제 #7
0
파일: webhook.py 프로젝트: janheise/zentral
    def _update_machine(self, client, device_type, jamf_id):
        logger.info("Update machine %s %s %s", client.source_repr, device_type,
                    jamf_id)

        try:
            machine_d, tags = client.get_machine_d_and_tags(
                device_type, jamf_id)
        except Exception:
            logger.exception("Could not get machine_d and tags. %s %s %s",
                             client.source_repr, device_type, jamf_id)
            return

        serial_number = machine_d.get("serial_number")
        if not serial_number:
            logger.warning("Machine %s %s %s without serial number",
                           client.source_repr, device_type, jamf_id)
            return

        with transaction.atomic():
            yield from commit_machine_snapshot_and_yield_events(machine_d)
            if tags:
                machine = MetaMachine(serial_number)
                for taxonomy_id, tag_names in tags.items():
                    taxonomy = self._get_taxonomy(taxonomy_id)
                    if taxonomy:
                        machine.update_taxonomy_tags(taxonomy, tag_names)
예제 #8
0
 def test_source(self):
     tree = copy.deepcopy(self.machine_snapshot3)
     msc, ms = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     tree = copy.deepcopy(self.machine_snapshot3)
     tree["serial_number"] = tree["serial_number"][::-1]
     msc2, ms2 = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     self.assertEqual(msc2.source, msc.source)
     self.assertEqual(ms2.source, ms.source)
     self.assertEqual([],
                      list(Source.objects.current_machine_group_sources()))
     self.assertEqual([ms.source],
                      list(Source.objects.current_business_unit_sources()))
     self.assertEqual(
         [ms.source],
         list(Source.objects.current_machine_snapshot_sources()))
     self.assertEqual([ms.source],
                      list(Source.objects.current_macos_apps_sources()))
     for sn in (self.serial_number, ms2.serial_number):
         mm = MetaMachine(sn)
         mm.archive()
     self.assertEqual(
         [], list(Source.objects.current_machine_snapshot_sources()))
     self.assertEqual([], list(Source.objects.current_macos_apps_sources()))
예제 #9
0
 def setUpTestData(cls):
     # user
     cls.user = User.objects.create_user("godzilla", "*****@*****.**", get_random_string())
     cls.group = Group.objects.create(name=get_random_string())
     cls.user.groups.set([cls.group])
     # probe
     cls.probe_source = ProbeSource.objects.create(
         model="BaseProbe",
         name=get_random_string(),
         status=ProbeSource.ACTIVE,
         body={"filters": {"metadata": [{"event_types": ["inventory_heartbeat"]}]}}
     )
     # machine
     cls.serial_number = "0123456789"
     MachineSnapshotCommit.objects.commit_machine_snapshot_tree({
         "source": {"module": "tests.zentral.io", "name": "Zentral Tests"},
         "serial_number": cls.serial_number,
         "os_version": {'name': 'OS X', 'major': 10, 'minor': 11, 'patch': 1},
         "osx_app_instances": [
             {'app': {'bundle_id': 'io.zentral.baller',
                      'bundle_name': 'Baller.app',
                      'bundle_version': '123',
                      'bundle_version_str': '1.2.3'},
              'bundle_path': "/Applications/Baller.app"}
         ]
     })
     cls.machine = MetaMachine(cls.serial_number)
     cls.url_msn = cls.machine.get_urlsafe_serial_number()
예제 #10
0
 def post(self, request, *args, **kwargs):
     enrolled_device = get_object_or_404(EnrolledDevice, pk=kwargs["pk"])
     send_device_notification(enrolled_device)
     messages.info(request, "Device poked!")
     return HttpResponseRedirect(
         reverse("mdm:device",
                 args=(MetaMachine(enrolled_device.serial_number).get_urlsafe_serial_number(),))
     )
예제 #11
0
 def get_context_data(self, **kwargs):
     context = super().get_context_data(**kwargs)
     context["mdm"] = True
     context["urlsafe_serial_number"] = MetaMachine(self.object.serial_number).get_urlsafe_serial_number()
     context["installed_device_artifacts"] = sorted(self.object.installeddeviceartifact_set.all(),
                                                    key=lambda ida: ida.created_at, reverse=True)
     context["device_artifact_commands"] = sorted(self.object.deviceartifactcommand_set.all(),
                                                  key=lambda dac: dac.id, reverse=True)
     return context
예제 #12
0
 def do_node_post(self, data):
     queries = {}
     if self.machine_serial_number:
         machine = MetaMachine(self.machine_serial_number)
         queries = DistributedQueryProbeMachine.objects.new_queries_for_machine(
             machine)
         inventory_query = get_distributed_inventory_query(machine, self.ms)
         if inventory_query:
             queries[DEFAULT_ZENTRAL_INVENTORY_QUERY_NAME] = inventory_query
     return {'queries': queries}
예제 #13
0
 def fetch_devices(self):
     query, args = self.build_query()
     with connection.cursor() as cursor:
         cursor.execute(query, args)
         attributes = [col.name for col in cursor.description]
         for row in cursor.fetchall():
             device = dict(zip(attributes, row))
             device["udids"] = sorted(udid for udid in device["udids"] if udid)
             device["urlsafe_serial_number"] = MetaMachine(device["serial_number"]).get_urlsafe_serial_number()
             yield device
예제 #14
0
 def authenticate(self):
     try:
         self.enrolled_machine = EnrolledMachine.objects.select_related(
             "enrollment__configuration",
             "enrollment__secret__meta_business_unit"
         ).get(node_key=self.get_node_key())
     except EnrolledMachine.DoesNotExist:
         raise PermissionDenied("Wrong node_key")
     self.machine = MetaMachine(self.enrolled_machine.serial_number)
     self.enrollment = self.enrolled_machine.enrollment
예제 #15
0
 def test_meta_machine(self):
     tree = copy.deepcopy(self.machine_snapshot)
     msc, ms = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     tree = copy.deepcopy(self.machine_snapshot2)
     msc2, ms2 = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     tree = copy.deepcopy(self.machine_snapshot3)
     msc3, ms3 = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     mm = MetaMachine(self.serial_number)
     self.assertEqual(mm.serial_number, self.serial_number)
     self.assertEqual(mm.snapshots, [ms3])
     self.assertEqual(mm.platform, MACOS)
     mm.archive()
     mm = MetaMachine(self.serial_number)
     self.assertEqual(mm.snapshots, [])
     self.assertEqual(MachineSnapshot.objects.count(), 3)
     self.assertEqual(MachineSnapshotCommit.objects.count(), 3)
     self.assertEqual(CurrentMachineSnapshot.objects.count(), 0)
예제 #16
0
 def test_machine_tag(self):
     tree = copy.deepcopy(self.machine_snapshot)
     msc, ms = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     tag = Tag.objects.create(name="tag name")
     self.assertEqual(str(tag), "tag name")
     MachineTag.objects.create(tag=tag, serial_number=self.serial_number)
     self.assertEqual(list(Tag.objects.used_in_inventory()), [(tag, 1)])
     mm = MetaMachine(self.serial_number)
     mm.archive()
     self.assertEqual(list(Tag.objects.used_in_inventory()), [])
예제 #17
0
 def do_node_post(self, data):
     queries = {}
     if self.machine_serial_number:
         machine = MetaMachine(self.machine_serial_number)
         queries = DistributedQueryProbeMachine.objects.new_queries_for_machine(machine)
         for query_name, query in get_distributed_inventory_queries(machine, self.ms):
             if query_name in queries:
                 logger.error("Conflict on the distributed query name %s", query_name)
             else:
                 queries[query_name] = query
     return {'queries': queries}
예제 #18
0
 def test_has_recent_source_snapshot(self):
     tree = copy.deepcopy(self.machine_snapshot)
     module = self.source["module"]
     age = 7200
     last_seen = datetime.utcnow() - timedelta(seconds=age)
     tree["last_seen"] = last_seen
     msc, ms = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     mm = MetaMachine(self.serial_number + "e12908e1209")
     self.assertFalse(mm.has_recent_source_snapshot(module,
                                                    max_age=2 * age))
     mm = MetaMachine(self.serial_number)
     self.assertFalse(
         mm.has_recent_source_snapshot(module + "lkjdelkwd",
                                       max_age=2 * age))
     self.assertFalse(mm.has_recent_source_snapshot(module))
     self.assertTrue(mm.has_recent_source_snapshot(module, max_age=2 * age))
     mm.archive()
     self.assertFalse(mm.has_recent_source_snapshot(module))
     self.assertFalse(mm.has_recent_source_snapshot(module,
                                                    max_age=2 * age))
예제 #19
0
 def post(self, request, *args, **kwargs):
     dep_device = get_object_or_404(DEPDevice, pk=kwargs["pk"])
     try:
         refresh_dep_device(dep_device)
     except DEPClientError as error:
         messages.error(request, str(error))
     else:
         messages.info(request, "DEP device refreshed")
     return HttpResponseRedirect("{}#dep_device".format(
         reverse("mdm:device",
                 args=(MetaMachine(dep_device.serial_number).get_urlsafe_serial_number(),))
     ))
예제 #20
0
파일: views.py 프로젝트: zbuc/zentral
 def dispatch(self, request, *args, **kwargs):
     try:
         token = request.META['HTTP_X_MONOLITH_TOKEN'].strip()
         api_data = verify_secret(token, 'zentral.contrib.monolith')
     except (KeyError, ValueError, APIAuthError):
         return HttpResponseForbidden("No no no!")
     self.machine_serial_number = api_data.get("machine_serial_number", None)
     self.user_agent, self.ip = user_agent_and_ip_address_from_request(request)
     self.machine = MetaMachine(self.machine_serial_number)
     self.tags = self.machine.tags
     self.meta_business_unit = api_data['business_unit'].meta_business_unit
     self.manifest = get_object_or_404(Manifest, meta_business_unit=self.meta_business_unit)
     return super().dispatch(request, *args, **kwargs)
예제 #21
0
파일: views.py 프로젝트: janheise/zentral
    def do_post(self, data):
        post_munki_request_event(self.machine_serial_number,
                                 self.user_agent,
                                 self.ip,
                                 request_type="job_details",
                                 enrollment={"pk": self.enrollment.pk})

        # serialize configuration
        configuration = self.enrollment.configuration
        response_d = {
            "apps_full_info_shard":
            configuration.inventory_apps_full_info_shard
        }
        if configuration.principal_user_detection_sources:
            principal_user_detection = response_d.setdefault(
                "principal_user_detection", {})
            principal_user_detection[
                "sources"] = configuration.principal_user_detection_sources
            if configuration.principal_user_detection_domains:
                principal_user_detection[
                    "domains"] = configuration.principal_user_detection_domains
        if configuration.collected_condition_keys:
            response_d[
                "collected_condition_keys"] = configuration.collected_condition_keys

        # add tags
        # TODO better cache for the machine tags
        m = MetaMachine(self.machine_serial_number)
        response_d["incidents"] = [
            mi.incident.name for mi in m.open_incidents()
        ]
        response_d["tags"] = m.tag_names()

        # last seen sha1sum
        # last managed installs sync
        try:
            munki_state = MunkiState.objects.get(
                machine_serial_number=self.machine_serial_number)
        except MunkiState.DoesNotExist:
            pass
        else:
            response_d['last_seen_sha1sum'] = munki_state.sha1sum
            response_d['managed_installs'] = (
                munki_state.last_managed_installs_sync is None or
                (datetime.utcnow() - munki_state.last_managed_installs_sync >
                 timedelta(
                     days=configuration.managed_installs_sync_interval_days)))
        return response_d
예제 #22
0
 def test_close_open_machine_incident(self):
     event_metadata = EventMetadata(event_type="test", machine_serial_number="YOLOFOMO")
     event_metadata.machine = MockMetaMachine([self.mbu1], [self.tag1],
                                              "WINDOWS", "LAPTOP",
                                              serial_number="YOLOFOMO")
     event = BaseEvent(event_metadata, {"joe": "jackson"})
     self.assertTrue(self.probe.test_event(event))
     machine_incident1, _ = update_or_create_open_machine_incident(
         self.probe_source,
         self.probe.get_matching_event_incident_severity(event),
         event.metadata.machine_serial_number,
         event.metadata.uuid
     )
     self.assertEqual(machine_incident1.status, STATUS_OPEN)
     self.assertEqual(machine_incident1.incident.status, STATUS_OPEN)
     machine_incident2, event_payloads = update_or_create_open_machine_incident(
         self.probe_source,
         0,  # severity == 0 => close
         event.metadata.machine_serial_number,
         event.metadata.uuid
     )
     self.assertEqual(machine_incident1, machine_incident2)
     self.assertEqual(machine_incident2.incident, machine_incident1.incident)
     self.assertEqual(machine_incident2.status, STATUS_CLOSED)
     incident = machine_incident2.incident
     self.assertEqual(incident.severity, SEVERITY_CRITICAL)
     self.assertEqual(incident.status, STATUS_CLOSED)
     self.assertEqual(len(event_payloads), 2)
     event_payload1, event_payload2 = event_payloads
     # machine incident event payload
     self.assertEqual(event_payload1["action"], "closed")
     self.assertEqual(event_payload1["incident"]["pk"], incident.pk)
     self.assertEqual(event_payload1["incident"]["status"], STATUS_OPEN)  # Incident still open
     self.assertEqual(event_payload1["pk"], machine_incident2.pk)
     self.assertEqual(event_payload1["status"], machine_incident2.status)
     self.assertEqual(event_payload1["event_id"], str(event.metadata.uuid))
     self.assertEqual(event_payload1["diff"], {"removed": {"status": STATUS_OPEN},
                                               "added": {"status": STATUS_CLOSED}})
     # incident event payload
     self.assertEqual(event_payload2["action"], "closed")
     self.assertEqual(event_payload2["pk"], incident.pk)
     self.assertEqual(event_payload2["status"], STATUS_CLOSED)  # Incident closed now
     self.assertEqual(event_payload2.get("incident"), None)
     self.assertEqual(event_payload2["diff"],
                      {"removed": {"status": STATUS_OPEN},
                       "added": {"status": STATUS_CLOSED}})
     # meta machine
     self.assertEqual(MetaMachine("YOLOFOMO").max_incident_severity(), None)
예제 #23
0
파일: base.py 프로젝트: stachdude/zentral
 def __init__(self, event_type, **kwargs):
     self.event_type = event_type
     self.uuid = kwargs.pop('uuid', uuid.uuid4())
     if isinstance(self.uuid, str):
         self.uuid = uuid.UUID(self.uuid)
     self.index = int(kwargs.pop('index', 0))
     self.created_at = kwargs.pop('created_at', None)
     if self.created_at is None:
         self.created_at = datetime.utcnow()
     elif isinstance(self.created_at, str):
         self.created_at = parser.parse(self.created_at)
     self.machine_serial_number = kwargs.pop('machine_serial_number', None)
     if self.machine_serial_number:
         self.machine = MetaMachine(self.machine_serial_number)
     else:
         self.machine = None
     self.request = kwargs.pop('request', None)
     self.tags = kwargs.pop('tags', [])
예제 #24
0
 def test_create_open_machine_incident(self):
     event_metadata = EventMetadata(event_type="test",
                                    machine_serial_number="YOLOFOMO")
     event_metadata.machine = MockMetaMachine([self.mbu1], [self.tag1],
                                              "WINDOWS",
                                              "LAPTOP",
                                              serial_number="YOLOFOMO")
     event = BaseEvent(event_metadata, {"joe": "jackson"})
     self.assertTrue(self.probe.test_event(event))
     machine_incident, event_payloads = update_or_create_open_machine_incident(
         self.probe_source,
         self.probe.get_matching_event_incident_severity(event),
         event.metadata.machine_serial_number, event.metadata.uuid)
     # machine incident
     self.assertEqual([machine_incident],
                      list(MachineIncident.objects.all()))
     self.assertEqual(machine_incident.status, STATUS_OPEN)
     self.assertEqual(machine_incident.event_id, event.metadata.uuid)
     # incident
     incident = machine_incident.incident
     self.assertEqual([incident], list(Incident.objects.all()))
     self.assertEqual(incident.probe_source, self.probe_source)
     self.assertEqual(incident.name, "base probe")
     self.assertEqual(incident.status, STATUS_OPEN)
     self.assertEqual(incident.severity, SEVERITY_CRITICAL)
     self.assertEqual(incident.event_id, event.metadata.uuid)
     # event payloads
     self.assertEqual(len(event_payloads), 2)
     event_payload1, event_payload2 = event_payloads
     # incident event payload
     self.assertEqual(event_payload1["action"], "created")
     self.assertEqual(event_payload1["pk"], incident.pk)
     self.assertEqual(event_payload1.get("machine_incident"), None)
     # machine incident event payload
     self.assertEqual(event_payload2["action"], "created")
     self.assertEqual(
         event_payload2["machine_incident"], {
             "pk": machine_incident.pk,
             "status": machine_incident.status,
             "event_id": str(event.metadata.uuid)
         })
     # meta machine
     self.assertEqual(
         MetaMachine("YOLOFOMO").max_incident_severity(), SEVERITY_CRITICAL)
예제 #25
0
 def test_meta_machine_update_taxonomy_tags(self):
     # one machine
     serial_number = get_random_string(13)
     # two tags from taxonomy1
     taxonomy1 = Taxonomy.objects.create(name=get_random_string(34))
     tag11 = Tag.objects.create(taxonomy=taxonomy1,
                                name=get_random_string(17))
     MachineTag.objects.get_or_create(serial_number=serial_number,
                                      tag=tag11)
     tag12 = Tag.objects.create(taxonomy=taxonomy1,
                                name=get_random_string(18))
     MachineTag.objects.get_or_create(serial_number=serial_number,
                                      tag=tag12)
     # one tag from taxonomy2
     taxonomy2 = Taxonomy.objects.create(name=get_random_string(27))
     tag21 = Tag.objects.create(taxonomy=taxonomy2,
                                name=get_random_string(20))
     MachineTag.objects.get_or_create(serial_number=serial_number,
                                      tag=tag21)
     # one detached tag
     tag31 = Tag.objects.create(name=get_random_string(21))
     MachineTag.objects.get_or_create(serial_number=serial_number,
                                      tag=tag31)
     # update the taxonomy1  tags. keep one, add two new ones, one collision, remove one.
     new_tag_names = [get_random_string(22), get_random_string(33)]
     updated_tag_names = [
         tag11.name,  # existing,
         # tag12.name  # removed
         tag31.
         name,  # collision, because we will try to add a tag with the same name, but within the taxonomy1
     ] + new_tag_names  # new ones
     mm = MetaMachine(serial_number)
     mm.update_taxonomy_tags(taxonomy1, updated_tag_names)
     # verify
     # two new tags
     new_tags = list(Tag.objects.filter(name__in=new_tag_names))
     self.assertEqual(len(new_tags), 2)
     # in the taxonomy1
     self.assertTrue(all(t.taxonomy == taxonomy1 for t in new_tags))
     # expected tags for the machine
     expected_tags = [("machine", t)
                      for t in [tag11, tag21, tag31] + new_tags]
     self.assertEqual(set(expected_tags), set(mm.tags_with_types))
예제 #26
0
 def authenticate(self):
     try:
         session_id = self.data["session_id"]
     except KeyError:
         raise SuspiciousOperation("Missing session_id")
     try:
         self.session = FileCarvingSession.objects.select_for_update().get(pk=session_id)
     except FileCarvingSession.DoesNotExist:
         raise PermissionDenied("Unknown session_id")
     # TODO: better. "There can be only one"
     try:
         self.enrolled_machine = (
             EnrolledMachine.objects.select_related("enrollment__configuration")
                                    .filter(serial_number=self.session.serial_number)
                                    .order_by("-pk")[0]
         )
     except IndexError:
         raise PermissionDenied("Unknown machine")
     self.machine = MetaMachine(self.session.serial_number)
     self.enrollment = self.enrolled_machine.enrollment
예제 #27
0
def update_osquery_enrolled_machine_platform_mask(apps, schema_editor):
    try:
        from zentral.contrib.inventory.models import MetaMachine
        from zentral.contrib.inventory.conf import LINUX, MACOS, WINDOWS
    except ImportError:
        pass
    EnrolledMachine = apps.get_model("osquery", "EnrolledMachine")
    for enrolled_machine in EnrolledMachine.objects.all():
        mm = MetaMachine(enrolled_machine.serial_number)
        if mm.platform:
            if mm.platform == LINUX:
                enrolled_machine.platform_mask = 0x01 | 0x08
            elif mm.platform == MACOS:
                enrolled_machine.platform_mask = 0x01 | 0x04 | 0x10
            elif mm.platform == WINDOWS:
                enrolled_machine.platform_mask = 0x02
            else:
                print("Unsupported osquery enrolled machine platform",
                      mm.platform)
                continue
            enrolled_machine.save()
예제 #28
0
 def _update_machine(self, client, device_type, jamf_id):
     logger.info("Update machine %s %s %s", client.source_repr, device_type,
                 jamf_id)
     try:
         machine_d, tags = client.get_machine_d_and_tags(
             device_type, jamf_id)
     except Exception:
         logger.exception("Could not get machine_d and tags. %s %s %s",
                          client.source_repr, device_type, jamf_id)
     else:
         if not machine_d.get("serial_number"):
             logger.warning("Machine %s %s %s without serial number",
                            client.source_repr, device_type, jamf_id)
             return
         try:
             with transaction.atomic():
                 msc, ms = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
                     machine_d)
         except Exception:
             logger.exception("Could not commit machine snapshot")
         else:
             if msc:
                 for idx, (event_type, created_at, payload) in enumerate(
                         inventory_events_from_machine_snapshot_commit(
                             msc)):
                     event_cls = event_cls_from_type(event_type)
                     metadata = EventMetadata(
                         event_cls.event_type,
                         machine_serial_number=ms.serial_number,
                         index=idx,
                         created_at=created_at,
                         tags=event_cls.tags)
                     event = event_cls(metadata, payload)
                     yield event
         if tags:
             machine = MetaMachine(machine_d["serial_number"])
             for taxonomy_id, tag_names in tags.items():
                 taxonomy = self._get_taxonomy(taxonomy_id)
                 if taxonomy:
                     machine.update_taxonomy_tags(taxonomy, tag_names)
예제 #29
0
파일: api.py 프로젝트: janheise/zentral
    def post(self, request, *args, **kwargs):
        # URL kwargs
        self.enrollment_secret_secret = kwargs["enrollment_secret"]
        try:
            self.hardware_uuid = str(UUID(kwargs["machine_id"]))
        except ValueError:
            raise PermissionDenied("Invalid machine id")

        self.client_cert_dn = self._get_client_cert_dn()

        self.user_agent, self.ip = user_agent_and_ip_address_from_request(
            request)

        self.request_data = self._get_json_data(request)

        self.cache_key = f"tests/santa/fixtures/{self.enrollment_secret_secret}{self.hardware_uuid}"
        self.enrolled_machine = None
        self.tag_ids = []
        if self.use_enrolled_machine_cache:
            try:
                self.enrolled_machine, self.tag_ids = cache.get(self.cache_key)
            except TypeError:
                pass
            else:
                if self.enrolled_machine.enrollment.configuration.client_certificate_auth and not self.client_cert_dn:
                    raise PermissionDenied("Missing client certificate")
        if not self.enrolled_machine:
            self.enrolled_machine = self.get_enrolled_machine()
            if not self.enrolled_machine:
                raise PermissionDenied("Machine not enrolled")
            meta_machine = MetaMachine(self.enrolled_machine.serial_number)
            self.tag_ids = [t.id for t in meta_machine.tags]
            cache.set(self.cache_key, (self.enrolled_machine, self.tag_ids),
                      600)  # TODO cache timeout hardcoded

        return JsonResponse(self.do_post())
예제 #30
0
 def test_machine_snapshot_current(self):
     tree = copy.deepcopy(self.machine_snapshot)
     msc, ms = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     tree = copy.deepcopy(self.machine_snapshot2)
     msc2, ms2 = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     tree = copy.deepcopy(self.machine_snapshot3)
     msc3, ms3 = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     self.assertEqual(MachineSnapshot.objects.count(), 3)
     self.assertEqual(MachineSnapshot.objects.current().count(), 1)
     self.assertEqual(MachineSnapshot.objects.current().get(pk=ms3.id), ms3)
     mm = MetaMachine(self.serial_number)
     mm.archive()
     self.assertEqual(CurrentMachineSnapshot.objects.count(), 0)
     tree = copy.deepcopy(self.machine_snapshot3)
     msc4, ms4 = MachineSnapshotCommit.objects.commit_machine_snapshot_tree(
         tree)
     self.assertEqual(ms3, ms4)
     self.assertEqual(CurrentMachineSnapshot.objects.count(), 1)
     cms = CurrentMachineSnapshot.objects.get(
         serial_number=self.serial_number)
     self.assertEqual(cms.machine_snapshot, ms3)