parent
2547ea25b4
commit
64c3b08740
@ -14,6 +14,7 @@ import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import socket
|
||||
import ssl
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
@ -53,6 +54,7 @@ def validate(config, expectations, exact=True):
|
||||
except ValueError as exc:
|
||||
raise VerificationError('Invalid expected exit IP') from exc
|
||||
require(len(spec['expected_country']) == 2 and spec['expected_country'].isalpha() and spec['expected_country'].isupper(), 'Expected country must be two uppercase letters')
|
||||
require(spec.get('verification', 'full') in ('full', 'tls'), 'Unsupported verification mode')
|
||||
tag = spec['tag']
|
||||
require(tag in nodes and tag not in selected, 'Missing/duplicate selected node')
|
||||
node = nodes[tag]
|
||||
@ -151,6 +153,23 @@ def run_node(config, spec, binary, port, diagnostic_dir):
|
||||
stop(proc)
|
||||
|
||||
|
||||
def run_tls(spec):
|
||||
"""Reach the relay and validate the node certificate; no exit/traffic claim."""
|
||||
context = ssl.create_default_context()
|
||||
with socket.create_connection((spec['host'], spec['port']), timeout=10) as stream:
|
||||
with context.wrap_socket(stream, server_hostname=spec['sni']) as secure:
|
||||
protocol = secure.version()
|
||||
require(protocol in ('TLSv1.2', 'TLSv1.3'), 'Unexpected TLS protocol')
|
||||
return {'tag': spec['tag'], 'strict_tls': True, 'live': True,
|
||||
'relay': spec['host'], 'relay_port': spec['port'], 'sni': spec['sni'],
|
||||
'verification': 'tls', 'node_tls': protocol}
|
||||
|
||||
|
||||
def run_specs(config, specs, binary, port, folder):
|
||||
return [run_tls(spec) if spec.get('verification', 'full') == 'tls'
|
||||
else run_node(config, spec, binary, port, folder) for spec in specs]
|
||||
|
||||
|
||||
def write_report(path, report):
|
||||
destination = Path(path)
|
||||
require(destination.parent.is_dir() and destination.parent.stat().st_mode & 0o077 == 0,
|
||||
@ -212,6 +231,7 @@ def main():
|
||||
specs = [{'tag': candidates[0]['tag'], 'host': qa.get('host'), 'port': qa.get('port'),
|
||||
'sni': qa.get('sni'), 'uuid': qa.get('uuid'), 'expected_exit': args.expected_exit,
|
||||
'expected_country': args.expected_country}]
|
||||
require(bool(args.expectations) or all(s.get('verification', 'full') == 'full' for s in specs), 'Isolated QA requires full verification')
|
||||
tags = validate(config, specs, exact=bool(args.expectations))
|
||||
results = []
|
||||
if args.run:
|
||||
@ -219,8 +239,7 @@ def main():
|
||||
binary = str(Path(args.binary).resolve())
|
||||
folder = Path(source).resolve().parent
|
||||
require(folder.stat().st_mode & 0o077 == 0, 'Live diagnostics directory must be private')
|
||||
for spec in specs:
|
||||
results.append(run_node(config, spec, binary, args.port, str(folder)))
|
||||
results = run_specs(config, specs, binary, args.port, str(folder))
|
||||
report = {'state': 'live_verified' if args.run else 'structure_validated',
|
||||
'verified_at': int(time.time()) if args.run else None,
|
||||
'qa_user_id': qa_user_id, 'selected_nodes': tags, 'results': results,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user