75 lines
3.6 KiB
Python
75 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Compare exact old/new summaries using generated data only, retain no contents."""
|
|
import base64
|
|
import hashlib
|
|
import importlib.util
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tempfile
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
BINARY = Path('/home/worsch/.local/lib/repo-manager/gitleaks/8.30.1/gitleaks')
|
|
CANDIDATE = Path('/tmp/rmgr-scanner-batch-r1/src/repo_manager/secret_scan.py')
|
|
|
|
|
|
def load(name, source):
|
|
spec = importlib.util.spec_from_file_location(name, source)
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
def main():
|
|
old = load('before', HERE / 'secret_scan.before.py')
|
|
new = load('candidate', CANDIDATE)
|
|
records = []
|
|
with tempfile.TemporaryDirectory(prefix='rmgr-parity-') as td:
|
|
root = Path(td)
|
|
env = {'PATH': '/usr/bin:/bin', 'HOME': td, 'LANG': 'C',
|
|
'GIT_CONFIG_NOSYSTEM': '1', 'GIT_CONFIG_GLOBAL': '/dev/null'}
|
|
def cmd(args, cwd):
|
|
return subprocess.check_output(args, cwd=cwd, env=env, stderr=subprocess.DEVNULL)
|
|
cmd(['ssh-keygen', '-q', '-t', 'ed25519', '-N', '', '-f', str(root / 'key')], root)
|
|
key = (root / 'key').read_bytes()
|
|
cases = [
|
|
('empty-index', []),
|
|
('clean-two-distinct', [('one', b'first clean\n'), ('two', b'second clean\n')]),
|
|
('original-ignore-path', [('vendor/modules.txt', key), ('secret.png', key)]),
|
|
('duplicate-attribution', [('key', key), ('copy', key), ('clean', b'clean\n')]),
|
|
('boundary-negative', [('left', key[:15]), ('right', key[15:])]),
|
|
('nul-prefix', [('key', b'\x00\x01\x02\n' + key)]),
|
|
('base64', [('key', base64.b64encode(key))]),
|
|
('4096-boundary', [('key', b'\n'*(4096-len(key)) + key)]),
|
|
('4097-fallback', [('key', b'\n'*(4097-len(key)) + key)]),
|
|
('100000-boundary', [('key', b'\n'*(100000-len(key)) + key)]),
|
|
('100001-boundary', [('key', b'\n'*(100001-len(key)) + key)]),
|
|
('archive-magic', [('key', b'PK\x03\x04' + b'\x00'*26 + key)]),
|
|
('inline-allow', [('key', b'# gitleaks:allow\n' + key)]),
|
|
]
|
|
for name, files in cases:
|
|
repo = root / name; repo.mkdir()
|
|
cmd(['git', '-c', 'core.hooksPath=/dev/null', 'init', '-q', str(repo)], root)
|
|
for path, content in files:
|
|
target = repo / path; target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_bytes(content)
|
|
cmd(['git', 'add', '--all'], repo)
|
|
before = old.scan_staged(repo, BINARY)
|
|
after = new.scan_staged(repo, BINARY)
|
|
if before != after:
|
|
raise RuntimeError('summary parity failed: ' + name)
|
|
records.append({'case': name, 'equal': True, 'status': after['status'],
|
|
'scanned_blobs': after['scanned_blobs'],
|
|
'blocked_blobs': len(after['blocked_blob_ids'])})
|
|
receipt = {'cases': records, 'fixtures_removed': not root.exists(),
|
|
'before_sha256': hashlib.sha256((HERE/'secret_scan.before.py').read_bytes()).hexdigest(),
|
|
'candidate_sha256': hashlib.sha256(CANDIDATE.read_bytes()).hexdigest(),
|
|
'scanner_sha256': hashlib.sha256(BINARY.read_bytes()).hexdigest(),
|
|
'provider_calls': 0, 'real_credentials_read': False}
|
|
(HERE/'parity-results.json').write_text(json.dumps(receipt, indent=2)+'\n')
|
|
print(json.dumps({'parity_cases': len(records), 'fixtures_removed': not root.exists()}))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|