Skip to content

Commit d571aa1

Browse files
committed
Preserve Osquery inventory snapshot result time
1 parent ce13674 commit d571aa1

File tree

3 files changed

+25
-9
lines changed

3 files changed

+25
-9
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ Add blueprint option to distribute the legacy profiles via DDM.
2424

2525
Add Digicert - Trust Lifecycle Manager SCEP issuer backend. Support for dynamic enrollment codes.
2626

27+
#### Osquery
28+
29+
Preserve Osquery inventory result time.
30+
2731
#### Core
2832

2933
Add mechanism to link background tasks to users.

tests/osquery/test_osquery_api.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,10 @@ def test_log_default_inventory_query(self):
10991099
json_response = response.json()
11001100
self.assertEqual(json_response, {})
11011101
ms = MachineSnapshot.objects.current().get(serial_number=em.serial_number, reference=em.node_key)
1102+
self.assertTrue(
1103+
all(msc.last_seen == datetime(2016, 12, 1, 15, 22, 17)
1104+
for msc in ms.machinesnapshotcommit_set.all())
1105+
)
11021106
self.assertEqual(ms.os_version.name, "macOS")
11031107
self.assertEqual(ms.os_version.major, 10)
11041108
self.assertEqual(ms.os_version.minor, 15)

zentral/contrib/osquery/public_views.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
from itertools import chain, islice
55
import json
66
import logging
7+
import pytz
78
from django.core.exceptions import SuspiciousOperation, PermissionDenied
89
from django.core.files.uploadedfile import SimpleUploadedFile
910
from django.db import transaction
1011
from django.http import Http404, JsonResponse
1112
from django.utils.crypto import get_random_string
13+
from django.utils.timezone import make_naive
1214
from django.views.generic import View
1315
from zentral.contrib.inventory.events import post_machine_snapshot_raw_event
1416
from zentral.contrib.inventory.exceptions import EnrollmentSecretVerificationFailed
@@ -446,10 +448,10 @@ def do_node_post(self):
446448
log_type = self.data.get("log_type")
447449
if log_type == "result":
448450
results = []
449-
last_inventory_snapshot = None
451+
last_inventory_snapshot_record = None
450452
for record in records:
451453
if record.get("name") == INVENTORY_QUERY_NAME:
452-
last_inventory_snapshot = record.get("snapshot")
454+
last_inventory_snapshot_record = record
453455
else:
454456
results.append(record)
455457
# file carving ?
@@ -476,16 +478,22 @@ def do_node_post(self):
476478
post_file_carve_events(self.machine.serial_number, self.user_agent, self.ip,
477479
[{"action": "schedule",
478480
"session_id": str(file_carving_session.pk)}])
479-
if last_inventory_snapshot:
480-
tree = {"source": {"module": "zentral.contrib.osquery",
481-
"name": "osquery"},
482-
"serial_number": self.machine.serial_number,
483-
"reference": self.enrolled_machine.node_key,
484-
"public_ip_address": self.ip}
481+
if last_inventory_snapshot_record:
482+
tree = {
483+
"source": {"module": "zentral.contrib.osquery",
484+
"name": "osquery"},
485+
"serial_number": self.machine.serial_number,
486+
"reference": self.enrolled_machine.node_key,
487+
"public_ip_address": self.ip,
488+
"last_seen": make_naive(
489+
datetime.fromtimestamp(int(last_inventory_snapshot_record["unixTime"]), pytz.UTC),
490+
timezone=pytz.UTC,
491+
)
492+
}
485493
business_unit = self.enrollment.secret.get_api_enrollment_business_unit()
486494
if business_unit:
487495
tree["business_unit"] = business_unit.serialize()
488-
update_tree_with_inventory_query_snapshot(tree, last_inventory_snapshot)
496+
update_tree_with_inventory_query_snapshot(tree, last_inventory_snapshot_record["snapshot"])
489497
# use the raw events queue to process this in the background
490498
post_machine_snapshot_raw_event(tree)
491499
post_results(self.machine.serial_number, results, self.request)

0 commit comments

Comments
 (0)