Improvements
This commit is contained in:
parent
d11d95aafe
commit
6f3207f02e
4 changed files with 241 additions and 104 deletions
|
|
@ -8,6 +8,7 @@ import requests
|
|||
from stem.control import Controller
|
||||
from stem.util.tor_tools import *
|
||||
from urllib.parse import urlparse
|
||||
from urllib3.util.retry import Retry
|
||||
|
||||
try:
|
||||
# unbound is not on pypi
|
||||
|
|
@ -29,13 +30,8 @@ try:
|
|||
except:
|
||||
TorContactInfoParser = None
|
||||
|
||||
# for now we support max_depth = 0 only
|
||||
# this PoC version has no support for recursion
|
||||
# https://github.com/nusenu/tor-relay-operator-ids-trust-information#trust-information-consumers
|
||||
supported_max_depths = ['0']
|
||||
|
||||
# https://github.com/nusenu/ContactInfo-Information-Sharing-Specification#ciissversion
|
||||
accepted_ciissversions = ['2']
|
||||
class TrustorError(Exception): pass
|
||||
|
||||
# https://stackoverflow.com/questions/2532053/validate-a-hostname-string
|
||||
# FIXME this check allows non-fqdn names
|
||||
|
|
@ -47,7 +43,6 @@ def is_valid_hostname(hostname):
|
|||
allowed = re.compile("(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)
|
||||
return all(allowed.match(x) for x in hostname.split("."))
|
||||
|
||||
|
||||
def read_local_trust_config(trust_config):
|
||||
'''
|
||||
reads a local configuration file containing trusted domains
|
||||
|
|
@ -55,6 +50,12 @@ def read_local_trust_config(trust_config):
|
|||
'''
|
||||
|
||||
result = []
|
||||
|
||||
# for now we support max_depth = 0 only
|
||||
# this PoC version has no support for recursion
|
||||
# https://github.com/nusenu/tor-relay-operator-ids-trust-information#trust-information-consumers
|
||||
supported_max_depths = ['0']
|
||||
|
||||
if (os.path.isfile(trust_config)):
|
||||
f = open(trust_config)
|
||||
for line in f:
|
||||
|
|
@ -150,6 +151,8 @@ def find_validation_candidates(controller, trusted_domains=[],validation_cache=[
|
|||
# https://github.com/nusenu/ContactInfo-Information-Sharing-Specification#proof
|
||||
accepted_proof_types = ['uri-rsa','dns-rsa']
|
||||
|
||||
# https://github.com/nusenu/ContactInfo-Information-Sharing-Specification#ciissversion
|
||||
accepted_ciissversions = ['2']
|
||||
|
||||
result = {}
|
||||
|
||||
|
|
@ -202,7 +205,7 @@ def find_validation_candidates(controller, trusted_domains=[],validation_cache=[
|
|||
result[domain] = {prooftype : [fingerprint]}
|
||||
return result
|
||||
|
||||
def lDownloadUrlFps(domain, sCAfile, timeout=30, host='127.0.0.1', port=9050):
|
||||
def oDownloadUrl(domain, sCAfile, timeout=30, host='127.0.0.1', port=9050):
|
||||
uri="https://"+domain+"/.well-known/tor-relay/rsa-fingerprint.txt"
|
||||
# socks proxy used for outbound web requests (for validation of proofs)
|
||||
proxy = {'https': 'socks5h://' +host +':' +str(port)}
|
||||
|
|
@ -216,28 +219,28 @@ def lDownloadUrlFps(domain, sCAfile, timeout=30, host='127.0.0.1', port=9050):
|
|||
# urllib3.connection WARNING Certificate did not match expected hostname:
|
||||
head = requests.head(uri, timeout=timeout, proxies=proxy, headers=headers)
|
||||
except Exception as e:
|
||||
LOG.warn(f"HTTP HEAD request failed for {uri} {e}")
|
||||
head = None
|
||||
return []
|
||||
if head.status_code != 200:
|
||||
return []
|
||||
raise TrustorError(f"HTTP HEAD request failed for {uri} {e}")
|
||||
|
||||
if head.status_code >= 300:
|
||||
raise TrustorError(f"HTTP Errorcode {head.status_code}")
|
||||
if not head.headers['Content-Type'].startswith('text/plain'):
|
||||
return []
|
||||
|
||||
assert os.path.exists(sCAfile), sCAfile
|
||||
raise TrustorError(f"HTTP Content-Type != text/plain")
|
||||
if not os.path.exists(sCAfile):
|
||||
raise TrustorError(f"File not found CAfile {sCAfile}")
|
||||
try:
|
||||
from https_adapter import HTTPSAdapter
|
||||
except Exception as e:
|
||||
LOG.warn(f"Could not import HTTPSAdapter {e}")
|
||||
HTTPSAdapter = None
|
||||
HTTPSAdapter = None
|
||||
|
||||
try:
|
||||
with requests.sessions.Session() as session:
|
||||
if HTTPSAdapter:
|
||||
retries = Retry(connect=3, read=2, redirect=0)
|
||||
# FixMe: upgrade to TLS1.3
|
||||
session.mount("https://", HTTPSAdapter(pool_maxsize=1,
|
||||
max_retries=3,))
|
||||
fullfile = session.request(method="get", url=uri,
|
||||
max_retries=retries,))
|
||||
oReqResp = session.request(method="get", url=uri,
|
||||
proxies=proxy, timeout=timeout,
|
||||
headers=headers,
|
||||
allow_redirects=False,
|
||||
|
|
@ -245,16 +248,21 @@ def lDownloadUrlFps(domain, sCAfile, timeout=30, host='127.0.0.1', port=9050):
|
|||
)
|
||||
except:
|
||||
LOG.warn("HTTP GET request failed for %s" % uri)
|
||||
return []
|
||||
if fullfile.status_code != 200 or not fullfile.headers['Content-Type'].startswith('text/plain'):
|
||||
return []
|
||||
raise
|
||||
if oReqResp.status_code != 200:
|
||||
raise TrustorError(f"HTTP Errorcode {head.status_code}")
|
||||
if not oReqResp.headers['Content-Type'].startswith('text/plain'):
|
||||
raise TrustorError(f"HTTP Content-Type != text/plain")
|
||||
|
||||
#check for redirects (not allowed as per spec)
|
||||
if fullfile.url != uri:
|
||||
LOG.error('Redirect detected %s vs %s (final)' % (uri, fullfile.url))
|
||||
return []
|
||||
if oReqResp.url != uri:
|
||||
LOG.error(f'Redirect detected %s vs %s (final)' % (uri, oReqResp.url))
|
||||
raise TrustorError(f'Redirect detected %s vs %s (final)' % (uri, oReqResp.url))
|
||||
return oReqResp
|
||||
|
||||
well_known_content = fullfile.text.upper().strip().split('\n')
|
||||
def lDownloadUrlFps(domain, sCAfile, timeout=30, host='127.0.0.1', port=9050):
|
||||
o = oDownloadUrl(domain, sCAfile, timeout=timeout, host=host, port=port)
|
||||
well_known_content = o.text.upper().strip().split('\n')
|
||||
well_known_content = [i for i in well_known_content if i and len(i) == 40]
|
||||
return well_known_content
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue