|
| 1 | +import os.path |
| 2 | + |
| 3 | +import requests |
| 4 | + |
| 5 | +from logging_helper import setup_logging |
| 6 | + |
| 7 | +from ._fetch import _storage_location |
| 8 | +from ._util import _check_in, _reverse_host |
| 9 | + |
| 10 | +logger = setup_logging() |
| 11 | + |
| 12 | +_hg_url = "https://hg.mozilla.org/releases/mozilla-{version}/raw-file/tip/security/manager/ssl/nsSTSPreloadList.inc" |
| 13 | +_VERSIONS = ["beta", "release"] |
| 14 | + |
| 15 | + |
| 16 | +def _fetch_preload(version="release"): |
| 17 | + filename = _storage_location(_hg_url, version) |
| 18 | + if os.path.exists(filename): |
| 19 | + return filename |
| 20 | + |
| 21 | + r = requests.get(_hg_url.format(version=version)) |
| 22 | + r.raise_for_status() |
| 23 | + |
| 24 | + with open(filename, "w") as f: |
| 25 | + f.write(r.text) |
| 26 | + |
| 27 | + return filename |
| 28 | + |
| 29 | + |
| 30 | +def _load_preload_data(filename): |
| 31 | + with open(filename) as f: |
| 32 | + positive = set() |
| 33 | + negative = set() |
| 34 | + lines = [line.strip() for line in f.readlines()] |
| 35 | + start = lines.index("%%") |
| 36 | + lines = lines[start + 1 :] |
| 37 | + end = lines.index("%%") |
| 38 | + lines = lines[:end] |
| 39 | + for line in lines: |
| 40 | + name, flag = line.split(",") |
| 41 | + name = name.strip() |
| 42 | + if flag.strip() == "1": |
| 43 | + positive.add(name) |
| 44 | + else: |
| 45 | + negative.add(name) |
| 46 | + return positive, negative |
| 47 | + |
| 48 | + |
| 49 | +def _preload_remove_negative(remove_overlap=False): |
| 50 | + filename = _fetch_preload() |
| 51 | + domains, negative = _load_preload_data(filename) |
| 52 | + |
| 53 | + for name in negative: |
| 54 | + rv = _check_in(domains, name) |
| 55 | + if rv: |
| 56 | + logger.warning("Removing {} because of negative {}".format(rv, name)) |
| 57 | + domains.remove(rv) |
| 58 | + |
| 59 | + if remove_overlap: |
| 60 | + entries = {} |
| 61 | + for name in domains: |
| 62 | + reversed_name = _reverse_host(name) |
| 63 | + assert reversed_name not in entries |
| 64 | + entries[reversed_name] = name |
| 65 | + |
| 66 | + previous = "" |
| 67 | + for item in sorted(entries.keys()): |
| 68 | + entry = entries[item] |
| 69 | + if not previous or previous not in item: |
| 70 | + previous = item |
| 71 | + continue |
| 72 | + |
| 73 | + domains.remove(entry) |
| 74 | + logger.warning( |
| 75 | + "Removing {} because of base domain {}".format(entry, entries[previous]) |
| 76 | + ) |
| 77 | + |
| 78 | + return domains |
0 commit comments