From 73d0c7a96df2212d5a3ee6289fc286f3e6459028 Mon Sep 17 00:00:00 2001 From: "kali kaneko (leap communications)" Date: Fri, 9 Oct 2020 18:53:11 +0200 Subject: [pkg] refactor vendor init/check --- branding/scripts/ASSETS_LIST | 2 - branding/scripts/ASSETS_REQUIRED | 3 ++ branding/scripts/check | 62 +++++++++++++++++++++++++- branding/scripts/check-ca-crt | 74 +++++++++++++++++++++++++++++++ branding/scripts/check-ca-crt.py | 61 ------------------------- branding/scripts/getparam | 5 ++- branding/scripts/init | 96 +++++++++++++++++++++++++++++----------- 7 files changed, 211 insertions(+), 92 deletions(-) delete mode 100644 branding/scripts/ASSETS_LIST create mode 100644 branding/scripts/ASSETS_REQUIRED create mode 100755 branding/scripts/check-ca-crt delete mode 100755 branding/scripts/check-ca-crt.py (limited to 'branding/scripts') diff --git a/branding/scripts/ASSETS_LIST b/branding/scripts/ASSETS_LIST deleted file mode 100644 index 71c89e3..0000000 --- a/branding/scripts/ASSETS_LIST +++ /dev/null @@ -1,2 +0,0 @@ -svg/icon.svg -ico/logo.ico diff --git a/branding/scripts/ASSETS_REQUIRED b/branding/scripts/ASSETS_REQUIRED new file mode 100644 index 0000000..b1889d1 --- /dev/null +++ b/branding/scripts/ASSETS_REQUIRED @@ -0,0 +1,3 @@ +icon.svg +icon.ico +icon.icns diff --git a/branding/scripts/check b/branding/scripts/check index 07b2a71..aab962e 100755 --- a/branding/scripts/check +++ b/branding/scripts/check @@ -1,4 +1,64 @@ #!/usr/bin/env python3 +import os +import sys + +# TODO check file list +# TODO remove fom README + +VENDOR_PATH = None + +def getVendorPath(): + global VENDOR_PATH + VENDOR_PATH = os.environ.get("VENDOR_PATH") + if not VENDOR_PATH: + print("[ERROR] VENDOR_PATH not set") + sys.exit(1) + + if not os.path.isdir(os.path.abspath(VENDOR_PATH)): + print("[ERROR] VENDOR_PATH folder does not exist:", VENDOR_PATH) + sys.exit(1) + +def checkCAFile(provider): + caFile = os.path.join(os.path.abspath(VENDOR_PATH), provider, provider + '-ca.crt') + if not os.path.isfile(caFile): + print("ERROR: Missing provider CA file:", caFile) + sys.exit(1) + print('[+] CA file ok:', caFile) + +def checkAssets(provider): + top = os.path.join(os.path.abspath(VENDOR_PATH), 'assets') + if os.path.isdir(top): + ok = checkAssetFiles(top) + if ok: + return + under = os.path.join(os.path.abspath(VENDOR_PATH), provider, 'assets') + if os.path.isdir(under): + ok = checkAssetFiles(under) + if ok: + return + print('[!] ERROR: cannot find some assets for provider {provider}'.format(provider=provider)) + sys.exit(1) + +def checkAssetFiles(path): + for item in allAssets(): + asset = os.path.join(path, item) + if not os.path.isfile(asset): + print("[!] Error: missing asset file:", asset) + return False + return True + +def allAssets(): + with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "ASSETS_REQUIRED")) as f: + allAssets = f.readlines() + return list(map(lambda s: s.strip(), allAssets)) + if __name__ == "__main__": - print("[+] Checking your provider config... (WIP)") + print("[+] Checking your provider config...") + provider = sys.argv[1] + if not provider: + print("ERROR: must pass provider as first argument") + sys.exit(1) + getVendorPath() + checkCAFile(provider) + checkAssets(provider) diff --git a/branding/scripts/check-ca-crt b/branding/scripts/check-ca-crt new file mode 100755 index 0000000..7458263 --- /dev/null +++ b/branding/scripts/check-ca-crt @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +import os +import re +import sys +import configparser +import urllib.request + +SCRIPT_NAME = 'check-ca-crt' +VENDOR_PATH = None + +USAGE = '''Check that the stored provider CA matches the one announced online. +Usage: {name} + +Example: {name} riseup'''.format(name=SCRIPT_NAME) + + +def getLocalCert(provider): + with open(os.path.join(VENDOR_PATH, provider, + '{provider}-ca.crt'.format(provider=sanitize(provider).lower()))) as crt: + return crt.read().strip() + + +def getRemoteCert(uri): + print("... checking cert from", uri) + fp = urllib.request.urlopen(uri) + remote_cert = fp.read().decode('utf-8').strip() + fp.close() + return remote_cert + +def getUriForProvider(provider, configfile): + c = configparser.ConfigParser() + c.read(configfile) + return c[provider]['caURL'] + +def sanitize(s): + return re.sub(r'[^\w\s-]', '', s).strip() + +if __name__ == '__main__': + VENDOR_PATH = os.environ.get('VENDOR_PATH') + + if not VENDOR_PATH: + print('[!] ERROR: Please set VENDOR_PATH variable first') + sys.exit(1) + if not os.path.isdir(os.path.abspath(VENDOR_PATH)): + print('[!] ERROR: VENDOR_PATH points to non-existent dir') + sys.exit(1) + + if len(sys.argv) != 2: + print('[!] Not enough arguments') + print(USAGE) + sys.exit(1) + + provider = sys.argv[1] + config = os.path.abspath(os.path.join(VENDOR_PATH, 'vendor.conf')) + if not os.path.isfile(config): + print('[!] ERROR: cannot open {config}') + sys.exit(1) + + try: + uri = getUriForProvider(provider, config) + except IndexError: + print('[!] Misconfigured provider') + sys.exit(1) + + local = getLocalCert(provider) + remote = getRemoteCert(uri) + + try: + assert local == remote + except AssertionError: + print('[!] ERROR: remote and local CA certs do not match') + sys.exit(1) + else: + print('OK: local CA matches what provider announces') diff --git a/branding/scripts/check-ca-crt.py b/branding/scripts/check-ca-crt.py deleted file mode 100755 index dbf9b40..0000000 --- a/branding/scripts/check-ca-crt.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python3 -import re -import sys -import configparser -import urllib.request - -SCRIPT_NAME = 'check-ca-crt.py' - -USAGE = '''Check that the stored provider CA matches the one announced online. -Usage: {name} - -Example: {name} riseup branding/config/vendor.conf'''.format(name=SCRIPT_NAME) - - -def getLocalCert(provider): - sanitized = re.sub(r'[^\w\s-]', '', provider).strip().lower() - with open('branding/config/' - '{provider}-ca.crt'.format(provider=sanitized)) as crt: - return crt.read().strip() - - -def getRemoteCert(uri): - print("... checking cert from", uri) - fp = urllib.request.urlopen(uri) - remote_cert = fp.read().decode('utf-8').strip() - fp.close() - return remote_cert - - -def getUriForProvider(provider, configfile): - c = configparser.ConfigParser() - c.read(configfile) - return c[provider]['caURL'] - - -if __name__ == '__main__': - - if len(sys.argv) != 3: - print('[!] Not enough arguments') - print(USAGE) - sys.exit(1) - - provider = sys.argv[1] - config = sys.argv[2] - - try: - uri = getUriForProvider(provider, config) - except IndexError: - print('[!] Misconfigured provider') - sys.exit(1) - - local = getLocalCert(provider) - remote = getRemoteCert(uri) - - try: - assert local == remote - except AssertionError: - print('[!] ERROR: remote and local CA certs do not match') - sys.exit(1) - else: - print('OK: local CA matches what provider announces') diff --git a/branding/scripts/getparam b/branding/scripts/getparam index 2b87e1e..235745d 100755 --- a/branding/scripts/getparam +++ b/branding/scripts/getparam @@ -13,9 +13,10 @@ from provider import getProviderData def getData(): here = os.path.abspath(os.path.dirname(__file__)) - configPath = os.path.join(here, '../../branding/config/vendor.conf') + vendorPath = os.environ.get('VENDOR_PATH') + configPath = os.path.join(vendorPath, 'vendor.conf') if not os.path.isfile(configPath): - print("ERROR: path does not exist", config) + print("ERROR: path does not exist", configPath) os.exit(1) config = configparser.ConfigParser() config.read(configPath) diff --git a/branding/scripts/init b/branding/scripts/init index ba9ce52..4c57d43 100755 --- a/branding/scripts/init +++ b/branding/scripts/init @@ -2,13 +2,15 @@ # (c) LEAP Encryption Access Project 2020 # License: GPL +import string import subprocess import sys import os VENDOR_PATH = None +PROVIDER=None SCRIPT_NAME = sys.argv[0] -CA_README = "config/CERT.Readme" +CA_README = "CERT.Readme" ASSETS_README = "assets/FILES.Readme" def initVendor(): @@ -17,9 +19,9 @@ def initVendor(): bail("ERROR: Please set VENDOR_PATH environment variable.") VENDOR_PATH = os.path.abspath(VENDOR_PATH) if os.path.isdir(VENDOR_PATH): - bail("ERROR: VENDOR_PATH folder already exists") + bail("ERROR: VENDOR_PATH folder already exists {path}".format(path=VENDOR_PATH)) - for d in ["config", "assets", "pkg"]: + for d in ["assets"]: os.makedirs(os.path.join(VENDOR_PATH, d)) initVendorConfig() @@ -27,10 +29,12 @@ def initVendor(): displayRepoInfo() def displayRepoInfo(): + print() print("[+] Initialized repo in", VENDOR_PATH) - print(f"[ ] - Add the assets in the assets/ folder, see {ASSETS_README}.") - print(f"[ ] - Add the CA certificate in the config/ folder, see {CA_README}.") - print("[ ] - Remember to commit your changes.") + print() + print(f"- Please add all the needed assets. See {VENDOR_PATH}/{ASSETS_README}.") + print(f"- Add your provider's CA certificate, see see {VENDOR_PATH}/{PROVIDER}/{CA_README}.") + print("- Remember to commit your changes.") print() print("[+] After doing that, you can run 'make vendor_check' to validate the configuration for your provider.") @@ -46,15 +50,42 @@ def bail(msg=None): def getVendorPath(): return os.environ.get('VENDOR_PATH') +def sanitize(word): + result = "" + for letter in word: + if letter in string.ascii_letters: + result = result + letter.lower() + return result + +def getProvider(): + provider = os.environ.get('PROVIDER') + if not provider: + provider = input('> provider name? ') + provider = sanitize(provider) + print("[+] provider name:", provider) + return provider + +def getProviderURL(): + url = os.environ.get('PROVIDER_URL') + if not url : + url = input('> provider url?: https://') + return url.replace('https://', '').replace('/', '') + +def getAppName(provider): + return provider[0].capitalize() + provider[1:] + "VPN" + def initVendorConfig(): + with open(os.path.join(VENDOR_PATH, "vendor.conf"), "w") as f: + f.write(getConf()) - with open(os.path.join(VENDOR_PATH, "config", "vendor.conf"), "w") as f: - f.write(CONF_TEMPLATE) + caDir = os.path.join(VENDOR_PATH, PROVIDER) + print("CADIR??", caDir) - with open(os.path.join(VENDOR_PATH, CA_README), "w") as f: - f.write(CA_INFO) + os.makedirs(caDir, exist_ok=True) + with open(os.path.join(caDir, CA_README), "w") as f: + f.write(getCAInfo()) - with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "ASSETS_LIST")) as f: + with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "ASSETS_REQUIRED")) as f: allAssets = f.read() with open(os.path.join(VENDOR_PATH, ASSETS_README), "w") as f: @@ -69,34 +100,44 @@ def initGitRepo(): CONF_TEMPLATE = """[default] -provider = myprovider +provider = {provider} -[myprovider] +[{provider}] -name = MyProvider -applicationName = MyProviderVPN -binaryName = myprovider-vpn +name = {provider} +applicationName = {appName} +binaryName = {provider}-vpn -providerURL = example.org +providerURL = https://{providerURL} auth = anon -apiURL = https://api.myprovider.net/ -caURL = https://myprovider.net/ca.crt +apiURL = https://api.{providerURL}/ +caURL = https://{providerURL}/ca.crt -infoURL = https://myprovider.net/vpn -tosURL = https://myprovider.net/tos -helpURL = https://myprovider.net/support +infoURL = https://{providerURL}/vpn +tosURL = https://{providerURL}/tos +helpURL = https://{providerURL}/support -geolocationAPI = https://myprovider.net:9001/json +geolocationAPI = https://{providerURL}:9001/json -askForDonations = true -donateURL = https://myprovider.net/vpn/donate +askForDonations = false +donateURL = https://{providerURL}/vpn/donate """ +def getConf(): + return CONF_TEMPLATE.format( + provider=PROVIDER, + appName=getAppName(PROVIDER), + providerURL=PROVIDER_URL) + + CA_INFO = """Place in this folder your provider's CA certificate, with the name: - -ca.crt + {provider}-ca.crt """ +def getCAInfo(): + return CA_INFO.format(provider=PROVIDER) + ASSETS_INFO = """This is the list of assets that you MUST place in this folder for your provider: """ @@ -104,5 +145,8 @@ ASSETS_INFO = """This is the list of assets that you MUST place in this folder f if __name__ == "__main__": if len(sys.argv) != 1: bail() + VENDOR_PATH = getVendorPath() + PROVIDER = getProvider() + PROVIDER_URL = getProviderURL() initVendor() -- cgit v1.2.3