Files
Samsara/tools/validate_windows_host.py
oceans2alaska 610a3bb447 Privacy hardening, remote-peer IP masking and review fixes
- 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>
2026-11-04 18:50:24 -08:00

55 lines
3.0 KiB
Python

"""Explicit real-host validation. Run manually on an authorized Windows Server only."""
import argparse
import json
from pathlib import Path
import platform
import sys
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from samsara.collectors.windows import collect_local_windows
from samsara.analyzers.assessment import assess
from samsara.core.storage import report_directory, require_local_path, write_private
from samsara.reporting.export import export_html, export_json
def main():
parser = argparse.ArgumentParser(description='Perform local read-only Windows inventory and save validation evidence. No remote connections.')
parser.add_argument('--output-dir', required=True, help='A NEW directory for sensitive host inventory and reports')
args = parser.parse_args()
if platform.system() != 'Windows':
parser.error('Real-host validation requires an authorized local Windows Server execution host.')
try:
destination = require_local_path(args.output_dir)
if destination != report_directory():
raise ValueError()
except (OSError, ValueError):
parser.error('Use the configured private report directory; existing files are never overwritten.')
try:
data = collect_local_windows(stage=lambda stage: print(stage, flush=True))
# collect_local_windows already enforces the supported Server identity and schema.
if data['synthetic']:
raise ValueError('A synthetic result cannot be used for real-host validation.')
assessment = assess(data)
export_json(destination / 'windows-assessment.json', data, assessment)
export_html(destination / 'windows-assessment.html', data, assessment)
summary = {
'real_inventory_collected': True, 'synthetic': False, 'collected_at': data['collected_at'],
'server_release': data['server']['os_version'], 'os_build': data['server']['os_build'],
'product_type': data['server']['product_type'],
'schema_validation': 'passed',
'checks': {name: {'status': check['status'], 'error_codes': [e['code'] for e in check['errors']],
'permission_limitations_reported': bool(check['permission_limitations'])}
for name, check in data['checks'].items()},
'counts': {name: len(rows) for name, rows in data['inventory'].items()},
'review_required': True,
}
write_private(destination / 'validation-summary.json',json.dumps(summary,indent=2))
print(json.dumps(summary, indent=2))
print('Review partial/failed checks. Keep full inventory/reports private; validation-summary.json omits hostnames, accounts, IPs, paths and certificate identifiers.')
except (OSError, ValueError, RuntimeError):
parser.exit(1, 'Validation did not finish. Check supported local Server OS, 64-bit Python, script policy, read permissions and a new writable destination. Raw command diagnostics are excluded.\n')
if __name__ == '__main__':
main()