- Add privacy projection (core/privacy.py), private report storage, bounded
process capture; omit identities, free text and unapproved paths
- Mask remote peer IPs: only loopback/host/wildcard stay numeric, others are
reduced to remote_scope private/public (schema + scoring updated)
- Map ss TCP states to canonical names; ASCII-only numeric fields; fix
"Microsoft Visual C++" product matching (Python and PowerShell)
- Merge 7fed3b9: -Diagnostic switch, serialization exit code 3, PS7 module
path, UI error detail; keep hardened task/certificate collectors
- Add audit docs, privacy docs and regression tests
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
50 lines
2.0 KiB
Python
50 lines
2.0 KiB
Python
import json
|
|
from pathlib import Path
|
|
import tempfile
|
|
import unittest
|
|
|
|
from samsara.collectors.demo import collect_demo, LINUX_DEMO_HOST
|
|
from samsara.analyzers.assessment import assess
|
|
try:
|
|
from samsara.collectors.importer import load_inventory
|
|
except ImportError:
|
|
load_inventory = None
|
|
|
|
|
|
@unittest.skipIf(load_inventory is None, 'jsonschema not installed')
|
|
class ImportTests(unittest.TestCase):
|
|
def load(self, data):
|
|
with tempfile.TemporaryDirectory() as folder:
|
|
path = Path(folder) / 'inventory.json'
|
|
path.write_text(json.dumps(data))
|
|
return load_inventory(path)
|
|
|
|
def test_linux_inventory_and_nfs_evidence(self):
|
|
data = self.load(collect_demo(LINUX_DEMO_HOST))
|
|
self.assertEqual(data['server']['platform'], 'linux')
|
|
result = assess(data)
|
|
self.assertTrue(any('Share-' in item['evidence'] for item in result['findings']))
|
|
self.assertTrue(any('certificates:' in item['evidence'] for item in result['findings']))
|
|
|
|
def test_report_wrapper_recomputed_and_sensitive_fields_removed(self):
|
|
data = collect_demo(LINUX_DEMO_HOST)
|
|
data['synthetic'] = False
|
|
data['inventory']['services'][0]['arguments'] = '--password=SECRET'
|
|
data['checks']['services']['message'] = 'SECRET command diagnostics'
|
|
imported = self.load({'inventory_result': data, 'assessment': {'level': 'safe'}})
|
|
self.assertFalse(imported['synthetic'])
|
|
self.assertNotIn('SECRET', json.dumps(imported))
|
|
self.assertNotEqual(assess(imported)['level'], 'safe')
|
|
|
|
def test_rejects_missing_checks_and_malformed_rows(self):
|
|
for mutation in ['check', 'row', 'version']:
|
|
data = collect_demo(LINUX_DEMO_HOST)
|
|
if mutation == 'check':
|
|
del data['checks']['services']
|
|
elif mutation == 'row':
|
|
data['inventory']['services'] = [{}]
|
|
else:
|
|
data['schema_version'] = '99'
|
|
with self.subTest(mutation=mutation), self.assertRaises(ValueError):
|
|
self.load(data)
|