diff options
author | Kali Kaneko (leap communications) <kali@leap.se> | 2019-07-15 18:06:29 +0200 |
---|---|---|
committer | Ruben Pollan <meskio@sindominio.net> | 2019-08-05 11:46:16 -0400 |
commit | 1106467f972e6e5d6781412e999d7c44195bb2df (patch) | |
tree | a0f72d3902407564439cfe866aeba4a03d9854bb /branding/templates/osx/generate.py | |
parent | f8218b2beb8b184e7b3585f1280695ecfef040f9 (diff) |
[feat] osx build templates
Diffstat (limited to 'branding/templates/osx/generate.py')
-rw-r--r-- | branding/templates/osx/generate.py | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/branding/templates/osx/generate.py b/branding/templates/osx/generate.py new file mode 100644 index 0000000..528605d --- /dev/null +++ b/branding/templates/osx/generate.py @@ -0,0 +1,153 @@ +#!/usr/bin/python + +# Generate bundles for brandable Bitmask Lite. + +# (c) LEAP Encryption Access Project +# (c) Kali Kaneko 2018-2019 + +import json +import os +import os.path +import shutil +import stat + +from string import Template + +here = os.path.split(os.path.abspath(__file__))[0] + +ENTRYPOINT = 'bitmask-vpn' +HELPER = 'bitmask-helper' +OPENVPN = 'openvpn-osx' +TEMPLATE_INFO = 'template-info.plist' +TEMPLATE_HELPER = 'template-helper.plist' + +TEMPLATE_PREINSTALL = 'template-preinstall' +TEMPLATE_POSTINSTALL = 'template-postinstall' + + +data = json.load(open(os.path.join(here, 'data.json'))) +APPNAME = data.get('applicationName') +VERSION = data.get('version', 'unknown') + +APP_PATH = os.path.abspath(here + '/../dist/' + APPNAME + ".app") +STAGING = os.path.abspath(here + '/../staging/') +ASSETS = os.path.abspath(here + '/../assets/') +ICON = os.path.join(ASSETS, APPNAME.lower() + '.icns') +SCRIPTS = os.path.join(os.path.abspath(here), 'scripts') +INFO_PLIST = APP_PATH + '/Contents/Info.plist' +HELPER_PLIST = os.path.join(SCRIPTS, 'se.leap.bitmask-helper.plist') +PREINSTALL = os.path.join(SCRIPTS, 'preinstall') +POSTINSTALL = os.path.join(SCRIPTS, 'postinstall') +RULEFILE = os.path.join(here, 'bitmask.pf.conf') +VPN_UP = os.path.join(here, 'client.up.sh') +VPN_DOWN = os.path.join(here, 'client.down.sh') + +try: + os.makedirs(APP_PATH + "/Contents/MacOS") +except Exception: + pass +try: + os.makedirs(APP_PATH + "/Contents/Resources") +except Exception: + pass +try: + os.makedirs(APP_PATH + "/Contents/helper") +except Exception: + pass + + +data['entrypoint'] = ENTRYPOINT +data['info_string'] = APPNAME + " " + VERSION +data['bundle_identifier'] = 'se.leap.' + data['applicationNameLower'] +data['bundle_name'] = APPNAME + +# utils + + +def copy_payload(filename, destfile=None): + if destfile is None: + destfile = APP_PATH + "/Contents/MacOS/" + filename + else: + destfile = APP_PATH + destfile + shutil.copyfile(STAGING + '/' + filename, destfile) + cmode = os.stat(destfile).st_mode + os.chmod(destfile, cmode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) + + +def generate_from_template(template, dest, data): + print("[+] File written from template to", dest) + template = Template(open(template).read()) + with open(dest, 'w') as output: + output.write(template.substitute(data)) + + +# 1. Generation of the Bundle Info.plist +# -------------------------------------- + +generate_from_template(TEMPLATE_INFO, INFO_PLIST, data) + + +# 2. Generate PkgInfo +# ------------------------------------------- + +with open(APP_PATH + "/Contents/PkgInfo", "w") as f: + # is this enough? See what PyInstaller does. + f.write("APPL????") + + +# 3. Copy the binary payloads +# -------------------------------------------- + +copy_payload(ENTRYPOINT) +copy_payload(HELPER) +copy_payload(OPENVPN, destfile='/Contents/Resources/openvpn.leap') + +# 4. Copy the app icon from the assets folder +# ----------------------------------------------- + +shutil.copyfile(ICON, APP_PATH + '/Contents/Resources/app.icns') + + +# 5. Generate the scripts for the installer +# ----------------------------------------------- + +# Watch out that, for now, all the brandings are sharing the same helper name. +# This is intentional: I prefer not to have too many root helpers laying around +# until we consolidate a way of uninstalling and/or updating them. +# This also means that only one of the derivatives will work at a given time +# (ie, uninstall bitmask legacy to use riseupvpn). +# If this bothers you, and it should, let's work on improving uninstall and +# updates. + +generate_from_template(TEMPLATE_HELPER, HELPER_PLIST, data) +generate_from_template(TEMPLATE_PREINSTALL, PREINSTALL, data) +generate_from_template(TEMPLATE_POSTINSTALL, POSTINSTALL, data) + +# 6. Copy helper pf rule file +# ------------------------------------------------ + +shutil.copy(RULEFILE, APP_PATH + '/Contents/helper/') + +# 7. Copy openvpn up/down scripts +# ------------------------------------------------ + +shutil.copy(VPN_UP, APP_PATH + '/Contents/helper/') +shutil.copy(VPN_DOWN, APP_PATH + '/Contents/helper/') + + +# 8. Generate uninstall script +# ----------------------------------------------- +# TODO copy the uninstaller script from bitmask-dev +# TODO substitute vars +# this is a bit weak procedure for now. +# To begin with, this assumes everything is hardcoded into +# /Applications/APPNAME.app +# We could consider moving the helpers into /usr/local/sbin, +# so that the plist files always reference there. + + +# We're all set! +# ----------------------------------------------- +print("[+] Output written to build/{provider}/dist/{appname}.app".format( + provider=data['name'].lower(), + appname=APPNAME)) |