diff options
Diffstat (limited to 'branding/templates/osx')
-rwxr-xr-x | branding/templates/osx/cross-quickpkg | 136 | ||||
-rw-r--r-- | branding/templates/osx/generate.py | 148 | ||||
-rwxr-xr-x | branding/templates/osx/quickpkg | 557 | ||||
-rw-r--r-- | branding/templates/osx/template-helper.plist | 26 | ||||
-rw-r--r-- | branding/templates/osx/template-info.plist | 34 | ||||
-rw-r--r-- | branding/templates/osx/template-packageinfo.plist | 21 | ||||
-rw-r--r-- | branding/templates/osx/template-postinstall | 14 | ||||
-rw-r--r-- | branding/templates/osx/template-preinstall | 12 |
8 files changed, 0 insertions, 948 deletions
diff --git a/branding/templates/osx/cross-quickpkg b/branding/templates/osx/cross-quickpkg deleted file mode 100755 index a940889..0000000 --- a/branding/templates/osx/cross-quickpkg +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/bash -# --------------------------------------------------------- -# Creates a OSX flat installer package from a Linux -# environment. You need xar and bomutils in your $PATH -# --------------------------------------------------------- -# -# kudos to SchizoDuckie for putting this gist together -# -# https://gist.github.com/SchizoDuckie/2a1a1cc71284e6463b9a -# https://krypted.com/mac-os-x/inspecting-creating-mac-installer-packages-linux/ -# ---------------------------------------------------------- - - -# The following variables need to be overriden by environment vars - -: "${VERSION:=0.0.1}" -: "${APPNAME:=TestApp}" -: "${IDENTIFIER:=se.leap.bitmask.installer}" - -# ---------------------------------------------------------- - -BUILD_DIR="../dist" -BASE_DIR="../build/osx" -BACKGROUND="../assets/osx-background.png" - -# ---------------------------------------------------------- - -initialize () { - rm -rf "$BASE_DIR/darwin" - mkdir -p "$BASE_DIR/darwin/flat/Resources/en.lproj" - mkdir -p "$BASE_DIR/darwin/flat/base.pkg/" - mkdir -p "$BASE_DIR/darwin/root/Applications" - mkdir -p "$BASE_DIR/darwin/scripts" - cp -R $BUILD_DIR/*.app $BASE_DIR/darwin/root/Applications - cp -R scripts/* $BASE_DIR/darwin/scripts/ - cp $BACKGROUND $BASE_DIR/darwin/flat/Resources/en.lproj/background.png - NUM_FILES=$(find ${BASE_DIR}/darwin/root | wc -l) - INSTALL_KB_SIZE=$(du -k -s ${BASE_DIR}/darwin/root | awk "{print $1}") -} - -# TODO for localization, these files should be taken from transifex, etc. -# TODO hardcoding a foundation for now. -writeInstallerDocs () { - cat <<EOF > ${BASE_DIR}/darwin/flat/Resources/en.lproj/welcome.html -<html> -<body> -<font face="helvetica"> -<h1>${APPNAME} installer</h1> -This will guide you through the steps needed to install ${APPNAME} in your computer. - -<hr/> - -<p> -<b>${APPNAME}</b> is a <i>simple, fast and secure VPN</i> developed by the Bitmask team. This app is configured to connect to a single trusted VPN provider. -</p> - -<hr/> -<p>The service is expensive to run. Please donate at <a href="https://riseup.net/vpn/donate">https://riseup.net/vpn/donate</a></p> - -</font> -</body> -</html> -EOF - -} - -writePackageInfo () { - cat <<EOF > ${BASE_DIR}/darwin/flat/base.pkg/PackageInfo -<?xml version="1.0" encoding="utf-8" standalone="no"?> -<pkg-info overwrite-permissions="true" relocatable="false" identifier="${IDENTIFIER}" postinstall-action="none" version="${VERSION}" format-version="2" generator-version="InstallCmds-502 (14B25)" auth="root"> - <payload numberOfFiles="${NUM_FILES}" installKBytes="${INSTALL_KB_SIZE}"/> - <bundle-version> - <bundle id="${IDENTIFIER}" CFBundleIdentifier="${IDENTIFIER}" path="./Applications/${APPNAME}.app" CFBundleVersion="1.3.0"/> - </bundle-version> - <update-bundle/> - <atomic-update-bundle/> - <strict-identifier/> - <relocate/> - <scripts> - <preinstall file="preinstall"/> - <postinstall file="postinstall"/> - </scripts> -</pkg-info> -EOF -} - -writeDistribution () { - cat <<EOF > ${BASE_DIR}/darwin/flat/Distribution -<?xml version="1.0" encoding="utf-8"?> -<installer-gui-script minSpecVersion="1"> - <title>${APPNAME} ${VERSION}</title> - <options customize="never" allow-external-scripts="no"/> - <domains enable_anywhere="true"/> - <background file="background.png" mime-type="image/png" scaling="tofit" /> - <background-darkAqua file="background.png" mime-type="image/png" scaling="tofit" /> - <welcome file="welcome.html" mime-type="text/html"/> - <installation-check script="pm_install_check();"/> - <script>function pm_install_check() { - if(!(system.compareVersions(system.version.ProductVersion,'10.5') >= 0)) { - my.result.title = "Failure"; - my.result.message = "You need at least Mac OS X 10.5 to install ${APPNAME}."; - my.result.type = "Fatal"; - return false; - } - return true; - } - </script> - <choices-outline> - <line choice="choice1"/> - </choices-outline> - <choice id="choice1" title="base"> - <pkg-ref id="${IDENTIFIER}.base.pkg"/> - </choice> - <pkg-ref id="${IDENTIFIER}.base.pkg" installKBytes="${INSTALL_KB_SIZE}" version="${VERSION}" auth="Root">#base.pkg</pkg-ref> -</installer-gui-script> -EOF -} - -createPackage () { - PKG_NAME="${APPNAME}-${VERSION}_unsigned.pkg" - PKG_LOCATION="../../${PKG_NAME}" - PKG_LOCATION_REL="${BASE_DIR}/${PKG_NAME}" - PKG_FINAL="${BUILD_DIR}/${PKG_NAME}" - ( cd ${BASE_DIR}/darwin/root && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > ${BASE_DIR}/darwin/flat/base.pkg/Payload - ( cd ${BASE_DIR}/darwin/scripts && find . | cpio -o --format odc --owner 0:80 | gzip -c ) > ${BASE_DIR}/darwin/flat/base.pkg/Scripts - mkbom -u 0 -g 80 ${BASE_DIR}/darwin/root ${BASE_DIR}/darwin/flat/base.pkg/Bom - ( cd ${BASE_DIR}/darwin/flat/ && xar --compression none -cf "${PKG_LOCATION}" * ) - cp ${PKG_LOCATION_REL} ${PKG_FINAL} - echo "[+] OSX package has been built: ${PKG_FINAL}" -} - -initialize -writeInstallerDocs -writePackageInfo -writeDistribution -createPackage diff --git a/branding/templates/osx/generate.py b/branding/templates/osx/generate.py deleted file mode 100644 index ada7269..0000000 --- a/branding/templates/osx/generate.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/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 -import sys - -from string import Template - -here = os.path.split(os.path.abspath(__file__))[0] - -ENTRYPOINT = 'bitmask-vpn' -TEMPLATE_INFO = 'template-info.plist' -TEMPLATE_HELPER = 'template-helper.plist' -TEMPLATE_PACKAGEINFO = 'template-packageinfo.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") -PKG_PATH = os.path.abspath(here + '/../dist/' + APPNAME) -STAGING = os.path.abspath(here + '/../staging/') -ASSETS = os.path.abspath(here + '/../assets/') -ICON = os.path.join(ASSETS, 'icon.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') -PACKAGEINFO = os.path.join(PKG_PATH, 'PackageInfo') -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 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. Generate if needed the package info (for cross build) -# -------------------------------------------- - -if not sys.platform.startswith('darwin'): - try: - os.mkdir(PKG_PATH) - except FileExistsError: - pass - generate_from_template(TEMPLATE_PACKAGEINFO, PACKAGEINFO, data) - -# 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)) diff --git a/branding/templates/osx/quickpkg b/branding/templates/osx/quickpkg deleted file mode 100755 index a8d0498..0000000 --- a/branding/templates/osx/quickpkg +++ /dev/null @@ -1,557 +0,0 @@ -#!/usr/bin/python - -import argparse -import string -import os -import subprocess -import tempfile -import shutil -import stat - -# includes FoundationPlist since some apps store their Info.plist -# as binary PropertyLists - -# FoundationPlist: - -# Copyright 2009-2014 Greg Neagle. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""FoundationPlist.py -- a tool to generate and parse MacOSX .plist files. - -This is intended as a drop-in replacement for Python's included plistlib, -with a few caveats: - - readPlist() and writePlist() operate only on a filepath, - not a file object. - - there is no support for the deprecated functions: - readPlistFromResource() - writePlistToResource() - - there is no support for the deprecated Plist class. - -The Property List (.plist) file format is a simple XML pickle supporting -basic object types, like dictionaries, lists, numbers and strings. -Usually the top level object is a dictionary. - -To write out a plist file, use the writePlist(rootObject, filepath) -function. 'rootObject' is the top level object, 'filepath' is a -filename. - -To parse a plist from a file, use the readPlist(filepath) function, -with a file name. It returns the top level object (again, usually a -dictionary). - -To work with plist data in strings, you can use readPlistFromString() -and writePlistToString(). -""" - -from Foundation import NSData, \ - NSPropertyListSerialization, \ - NSPropertyListMutableContainersAndLeaves, \ - NSPropertyListXMLFormat_v1_0 - - -class FoundationPlistException(Exception): - '''Base error for this module''' - pass - - -class NSPropertyListSerializationException(FoundationPlistException): - '''Read error for this module''' - pass - - -class NSPropertyListWriteException(FoundationPlistException): - '''Write error for this module''' - pass - - -# private functions -def _dataToPlist(data): - '''low-level function that parses a data object into a propertyList object''' - darwin_vers = int(os.uname()[2].split('.')[0]) - if darwin_vers > 10: - (plistObject, plistFormat, error) = ( - NSPropertyListSerialization.propertyListWithData_options_format_error_( - data, NSPropertyListMutableContainersAndLeaves, None, None)) - else: - # 10.5 doesn't support propertyListWithData:options:format:error: - # 10.6's PyObjC wrapper for propertyListWithData:options:format:error: - # is broken - # so use the older NSPropertyListSerialization function - (plistObject, plistFormat, error) = ( - NSPropertyListSerialization.propertyListFromData_mutabilityOption_format_errorDescription_( - data, NSPropertyListMutableContainersAndLeaves, None, None)) - if plistObject is None: - if error is None: - error = "Plist data is invalid and could not be deserialized." - raise NSPropertyListSerializationException(error) - else: - return plistObject - - -def _plistToData(plistObject): - '''low-level function that creates NSData from a plist object''' - darwin_vers = int(os.uname()[2].split('.')[0]) - if darwin_vers > 10: - (data, error) = ( - NSPropertyListSerialization.dataWithPropertyList_format_options_error_( - plistObject, NSPropertyListXMLFormat_v1_0, 0, None)) - else: - # use the older NSPropertyListSerialization function on 10.6 and 10.5 - (data, error) = ( - NSPropertyListSerialization.dataFromPropertyList_format_errorDescription_( - plistObject, NSPropertyListXMLFormat_v1_0, None)) - if data is None: - if error is None: - error = "Property list invalid for format." - raise NSPropertyListSerializationException(error) - return data - - -# public functions -def readPlist(filepath): - '''Read a .plist file from filepath. Return the unpacked root object - (which is usually a dictionary).''' - try: - data = NSData.dataWithContentsOfFile_(filepath) - except NSPropertyListSerializationException, error: - # insert filepath info into error message - errmsg = (u'%s in %s' % (error, filepath)) - raise NSPropertyListSerializationException(errmsg) - return _dataToPlist(data) - - -def readPlistFromString(aString): - '''Read a plist data from a string. Return the root object.''' - data = buffer(aString) - return _dataToPlist(data) - - -def writePlist(plistObject, filepath): - '''Write 'plistObject' as a plist to filepath.''' - plistData = _plistToData(plistObject) - if plistData.writeToFile_atomically_(filepath, True): - return - else: - raise NSPropertyListWriteException( - u"Failed to write plist data to %s" % filepath) - - -def writePlistToString(plistObject): - '''Create a plist-formatted string from plistObject.''' - return str(_plistToData(plistObject)) - - -# -# quickpkg -# - - -quickpkg_version = '0.5' -supported_extensions = ['dmg', 'app', 'zip'] - - -# modeled after munkiimport but to build a pkg - - -def logger(log, v=0): - if args.verbosity >= v: - print log - - -def cmdexec(command, stdin=''): - """Execute a command.""" - # if 'command' is a string, split the string into components - if isinstance(command, str): - command = command.split() - - proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) - (stdout, stderr) = proc.communicate(stdin) - - logger("cmdexec: %s, result: %s, error: %s" % (command, stdout, stderr), 3) - - # strip trailing whitespace, which would mess with string comparisons - return {"return_code": proc.returncode, "stderr": stderr.rstrip(), "stdout": stdout.rstrip()} - - -# from munkicommons.py -def getFirstPlist(textString): - """Gets the next plist from a text string that may contain one or - more text-style plists. - Returns a tuple - the first plist (if any) and the remaining - string after the plist""" - plist_header = '<?xml version' - plist_footer = '</plist>' - plist_start_index = textString.find(plist_header) - if plist_start_index == -1: - # not found - return ("", textString) - plist_end_index = textString.find( - plist_footer, plist_start_index + len(plist_header)) - if plist_end_index == -1: - # not found - return ("", textString) - # adjust end value - plist_end_index = plist_end_index + len(plist_footer) - return (textString[plist_start_index:plist_end_index], - textString[plist_end_index:]) - - -def dmg_has_sla(dmgpath): - has_sla = False - imageinfo_cmd = ['/usr/bin/hdiutil', 'imageinfo', dmgpath, '-plist'] - result = cmdexec(imageinfo_cmd) - if result["return_code"] != 0: - print "error getting imageinfo! %s, %s" % (result["return_code"], result["stderr"]) - return False - result_plist = result["stdout"] - imageinfo_dict = readPlistFromString(result_plist) - properties = imageinfo_dict.get('Properties') - if properties is not None: - has_sla = properties.get('Software License Agreement', False) - return has_sla - - -def attachdmg(dmgpath): - global dmg_was_mounted - info_cmd = ["hdiutil", "info", "-plist"] - info_result = cmdexec(info_cmd) - if info_result["return_code"] == 0: - # parse the plist output - (theplist, alltext) = getFirstPlist(info_result["stdout"]) - info_dict = readPlistFromString(theplist) - volpaths = [] - if "images" in info_dict.keys(): - for y in info_dict["images"]: - if "image-path" in y.keys(): - if os.path.samefile(y["image-path"], dmgpath): - for x in y.get("system-entities"): - if "mount-point" in x.keys(): - volpaths.append(x["mount-point"]) - dmg_was_mounted = True - return volpaths - else: - print "error getting hdiutil info" - print "(%d, %s)" % (info_result["returncode"], info_result["stderr"]) - cleanup_and_exit(1) - - attachcmd = ["/usr/bin/hdiutil", - "attach", - dmgpath, - "-mountrandom", - "/private/tmp", - "-plist", - "-nobrowse"] - if dmg_has_sla(dmgpath): - stdin = "Y\n" - print "NOTE: Disk image %s has a license agreement!" % dmgpath - else: - stdin = '' - result = cmdexec(attachcmd, stdin) - if result["return_code"] == 0: - # parse the plist output - (theplist, alltext) = getFirstPlist(result["stdout"]) - resultdict = readPlistFromString(theplist) - volpaths = [] - for x in resultdict["system-entities"]: - if x["potentially-mountable"]: - if x["volume-kind"] == 'hfs': - volpaths.append(x["mount-point"]) - # return the paths to mounted volume - return volpaths - else: - print "error mounting disk image" - print "(%d, %s)" % (result["returncode"], result["stderr"]) - cleanup_and_exit(1) - - -def detachpaths(volpaths): - for x in volpaths: - if os.path.exists(x): - if os.path.ismount(x): - detachcmd = ["/usr/bin/hdiutil", "detach", x] - cmdexec(detachcmd) - - -def finditemswithextension(dirpath, item_extension): - foundapps = [] - if os.path.exists(dirpath): - for x in os.listdir(dirpath): - (item_basename, item_extension) = os.path.splitext(x) - item_extension = string.lstrip(item_extension, '.') - if item_extension == 'app': - foundapps.append(os.path.join(dirpath, x)) - else: - print "path %s does not exist" % dirpath - cleanup_and_exit(1) - return foundapps - - -def appNameAndVersion(app_path): - info_path = os.path.join(app_path, "Contents/Info.plist") - if not os.path.exists(info_path): - print "Application at path %s does not have Info.plist" % app_path - # TODO: cleanup volumes here - cleanup_and_exit(1) - info_plist = readPlist(info_path) - app_name = info_plist.get("CFBundleName") - if app_name is None: - app_name = info_plist.get("CFBundleDisplayName") - if app_name is None: - (app_name, app_ext) = os.path.splitext(os.path.basename(app_path)) - app_identifier = info_plist.get("CFBundleIdentifier") - app_version = info_plist.get("CFBundleShortVersionString") - if app_version is None: - app_version = info_plist.get("CFBundleVersion") - return (app_name, app_identifier, app_version) - - -def cleanup_and_exit(returncode): - global dmgvolumepaths - global dmg_was_mounted - global tmp_path - - if args.clean: - if not dmg_was_mounted: - detachpaths(dmgvolumepaths) - if tmp_path is not None: - shutil.rmtree(tmp_path) - exit(returncode) - - -if __name__ == "__main__": - - parser = argparse.ArgumentParser(description="""Attempts to build a pkg from the input. - Installer item can be a dmg, zip, or app.""", - epilog="""Example: quickpkg /path/to/installer_item""") - - # takes a path as input - parser.add_argument('item_path', help="path to the installer item") - - scripts_group = parser.add_argument_group('Installation Scripts', - '''These options will set the installation scripts. You pass an entire folder of scripts, - just like the option of `pkgbuild` or you can give a file for the preinstall or postinstall - scripts respectively. If you give both the --scripts and either one or both of --preinstall - and --postinstall, quickpkg will attempt to merge, but throw an error if it cannot.''') - scripts_group.add_argument('--scripts', help="path to a folder with scripts") - scripts_group.add_argument('--preinstall', '--pre', help="path to the preinstall script") - scripts_group.add_argument('--postinstall', '--post', help="path to the postinstall script") - - parser.add_argument('--ownership', choices=['recommended', 'preserve', 'preserve-other'], - help="will be passed through to pkgbuild") - parser.add_argument('--output', '--out', '-o', - help='''path where the package file will be created. If you give the full filename - then you can use '{name}', '{version}' and '{identifier}' as placeholders. - If this is a directory, then the - package will be created with the default filename {name}-{version}.pkg''') - - parser.add_argument('--clean', dest='clean', action='store_true', help="clean up temp files (DEFAULT)") - parser.add_argument('--no-clean', dest='clean', action='store_false', help=" do NOT clean up temp files") - parser.set_defaults(clean=True) - - parser.add_argument('--relocatable', dest='relocatable', action='store_true', - help="sets BundleIsRelocatable in the PackageInfo to true") - parser.add_argument('--no-relocatable', dest='relocatable', action='store_false', - help="sets BundleIsRelocatable in the PackageInfo (DEFAULT is false)") - parser.set_defaults(relocatable=False) - - - parser.add_argument("-v", "--verbosity", action="count", default=0, help="controls amount of logging output (max -vvv)") - parser.add_argument('--version', help='prints the version', action='version', version=quickpkg_version) - - args = parser.parse_args() - - # remove trailing '/' from path - item_path = string.rstrip(args.item_path, '/') - - if item_path.startswith('~'): - item_path = os.path.expanduser(item_path) - item_path = os.path.abspath(item_path) - - # get file extension - (item_basename, item_extension) = os.path.splitext(item_path) - item_extension = string.lstrip(item_extension, '.') - - # is extension supported - if item_extension not in supported_extensions: - print ".%s is not a supported extension!" % item_extension - exit(1) - - foundapps = [] - - # if item is an app, just pass it on - if item_extension == 'app': - if not os.path.exists(item_path): - print "This does not seem to be an Application!" - exit(1) - foundapps.append(item_path) - - dmgvolumepaths = [] - tmp_path = None - dmg_was_mounted = False - tmp_scripts_path = None - tmp_path = tempfile.mkdtemp() - payload_path = os.path.join(tmp_path, "payload") - os.makedirs(payload_path) - - # if item is a dmg, mount it and find useful contents - if item_extension == 'dmg': - dmgvolumepaths = attachdmg(item_path) - for x in dmgvolumepaths: - moreapps = finditemswithextension(x, 'app') - foundapps.extend(moreapps) - if len(foundapps) == 0: - print "Could not find an application!" - cleanup_and_exit(1) - elif len(foundapps) > 1: - print "Found too many Applications! Can't decide!" - print foundapps - cleanup_and_exit(1) - - # if item is zip, unzip to tmp location and find useful contents - if item_extension == 'zip': - unarchive_path = os.path.join(tmp_path, "unarchive") - unzip_cmd = ["/usr/bin/unzip", "-d", unarchive_path, item_path] - result = cmdexec(unzip_cmd) - if result["return_code"] != 0: - print "An error occured while unzipping:" - print "%d, %s" % (result["return_code"], result["stderr"]) - cleanup_and_exit(1) - foundapps = finditemswithextension(unarchive_path, 'app') - if len(foundapps) == 0: - print "Could not find an application!" - cleanup_and_exit(1) - elif len(foundapps) > 1: - print "Found too many Applications! Can't decide!" - print foundapps - cleanup_and_exit(1) - - logger("Found application: %s" % foundapps[0], 1) - - # copy found app to payload folder - app_name = os.path.basename(foundapps[0]) - app_path = os.path.join(payload_path, app_name) - shutil.copytree(foundapps[0], app_path) - - # extract version and other metadata - (app_name, app_identifier, app_version) = appNameAndVersion(app_path) - - logger("Name: %s, ID: %s, Version: %s" % (app_name, app_identifier, app_version), 1) - - # create the component plist - component_plist = os.path.join(tmp_path, app_identifier) + ".plist" - analyzecmd = ["/usr/bin/pkgbuild", - "--analyze", - "--root", payload_path, - "--identifier", app_identifier, - "--version", app_version, - "--install-location", "/Applications", - component_plist] - result = cmdexec(analyzecmd) - - logger(result["stdout"], 1) - if result["return_code"] != 0: - print "Error Code: %d " % result["return_code"] - print result["stderr"] - cleanup_and_exit(1) - - if not args.relocatable: - # read and change component plist - components = readPlist(component_plist) - # component plist is an array of components - for bundle in components: - if "BundleIsRelocatable" in bundle.keys(): - bundle["BundleIsRelocatable"] = False - writePlist(components, component_plist) - - pkg_name = "{name}-{version}.pkg" - if args.output: - if os.path.isdir(args.output): - pkg_path = os.path.join(args.output, pkg_name) - else: - pkg_path = args.output - else: - pkg_path = pkg_name - nospace_app_name = app_name.replace(' ', '') # remove spaces - pkg_path = pkg_path.format(name=nospace_app_name, version=app_version, identifier=app_identifier) - - if not pkg_path.endswith('pkg'): - pkg_path += '.pkg' - - # run pkgutil to build result - pkgcmd = ["/usr/bin/pkgbuild", - "--root", payload_path, - "--component-plist", component_plist, - "--identifier", app_identifier, - "--version", app_version, - "--install-location", "/Applications", - pkg_path] - - if args.scripts and not os.path.exists(args.scripts): - print "scripts folder %s does not exist!" % args.scripts - cleanup_and_exit(1) - - if args.postinstall or args.preinstall: - tmp_scripts_path = os.path.join(tmp_dir, "scripts") - os.makedirs(tmp_scripts_path) - - if args.scripts: - logger("copying %s to tmp scripts folder %s" % (args.scripts, tmp_scripts_path), 1) - shutil.rmtree(tmp_scripts_path) - shutil.copytree(args.scripts, tmp_scripts_path) - if args.postinstall: - if not os.path.exists(args.postinstall): - print "postinstall file %s does not exist!" % args.postinstall - cleanup_and_exit(1) - postinstall_path = os.path.join(tmp_scripts_path, "postinstall") - if os.path.exists(postinstall_path): - print "postinstall script already exists in %s" % args.scripts - cleanup_and_exit(1) - logger("copying %s to %s" % (args.postinstall, postinstall_path), 1) - shutil.copy2(args.postinstall, postinstall_path) - os.chmod(postinstall_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | - stat.S_IRGRP | stat.S_IXGRP | - stat.S_IROTH | stat.S_IXOTH) - if args.preinstall: - if not os.path.exists(args.preinstall): - print "preinstall file %s does not exist!" % args.preinstall - cleanup_and_exit(1) - preinstall_path = os.path.join(tmp_scripts_path, "preinstall") - if os.path.exists(preinstall_path): - print "preinstall script already exists in %s" % args.scripts - cleanup_and_exit(1) - logger("copying %s to %s" % (args.preinstall, preinstall_path), 1) - shutil.copy2(args.preinstall, preinstall_path) - os.chmod(preinstall_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | - stat.S_IRGRP | stat.S_IXGRP | - stat.S_IROTH | stat.S_IXOTH) - - if tmp_scripts_path: - logger("scripts path: %s" % tmp_scripts_path, 1) - pkgcmd.extend(["--scripts", tmp_scripts_path]) - elif args.scripts: - logger("scripts path: %s" % args.scripts, 1) - pkgcmd.extend(["--scripts", args.scripts]) - - if args.ownership: - pkgcmd.extend(["--ownership", args.ownership]) - - result = cmdexec(pkgcmd) - - logger(result["stdout"], 1) - if result["return_code"] != 0: - print "Error Code: %d " % result["return_code"] - print result["stderr"] - else: - print pkg_path - - cleanup_and_exit(0) diff --git a/branding/templates/osx/template-helper.plist b/branding/templates/osx/template-helper.plist deleted file mode 100644 index 160d95c..0000000 --- a/branding/templates/osx/template-helper.plist +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>WorkingDirectory</key> - <string>/tmp</string> - <key>StandardOutPath</key> - <string>bitmask-helper.log</string> - <key>StandardErrorPath</key> - <string>bitmask-helper-err.log</string> - <key>GroupName</key> - <string>daemon</string> - <key>RunAtLoad</key> - <true/> - <key>SessionCreate</key> - <true/> - <key>KeepAlive</key> - <true/> - <key>ThrottleInterval</key> - <integer>5</integer> - <key>Label</key> - <string>se.leap.BitmaskHelper</string> - <key>Program</key> - <string>/Applications/$applicationName.app/Contents/MacOS/bitmask-helper</string> -</dict> -</plist> diff --git a/branding/templates/osx/template-info.plist b/branding/templates/osx/template-info.plist deleted file mode 100644 index e67ddcc..0000000 --- a/branding/templates/osx/template-info.plist +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>$entrypoint</string> - <key>CFBundleGetInfoString</key> - <string>$info_string</string> - <key>CFBundleIconFile</key> - <string>app.icns</string> - <key>CFBundleIdentifier</key> - <string>$bundle_identifier</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>$bundle_name</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>$info_string</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>$version</string> - <key>NSAppleScriptEnabled</key> - <string>YES</string> - <key>NSMainNibFile</key> - <string>MainMenu</string> - <key>NSPrincipalClass</key> - <string>NSApplication</string> -</dict> -</plist> diff --git a/branding/templates/osx/template-packageinfo.plist b/branding/templates/osx/template-packageinfo.plist deleted file mode 100644 index 7297442..0000000 --- a/branding/templates/osx/template-packageinfo.plist +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="no"?> -<pkg-info overwrite-permissions="true" relocatable="false" identifier="se.leap.$applicationNameLower" postinstall-action="none" version="$applicationName $version" format-version="2" generator-version="InstallCmds-502 (14A389)" install-location="/Applications" auth="root"> - <payload numberOfFiles="15" installKBytes="10188"/> - <bundle path="./$applicationName.app" id="se.leap.$applicationNameLower" CFBundleShortVersionString="$applicationName $version" CFBundleVersion="0.19.1"/> - <bundle-version> - <bundle id="se.leap.$applicationNameLower"/> - </bundle-version> - <upgrade-bundle> - <bundle id="se.leap.$applicationNameLower"/> - </upgrade-bundle> - <update-bundle/> - <atomic-update-bundle/> - <strict-identifier> - <bundle id="se.leap.$applicationNameLower"/> - </strict-identifier> - <relocate/> - <scripts> - <preinstall file="./preinstall"/> - <postinstall file="./postinstall"/> - </scripts> -</pkg-info> diff --git a/branding/templates/osx/template-postinstall b/branding/templates/osx/template-postinstall deleted file mode 100644 index 377508c..0000000 --- a/branding/templates/osx/template-postinstall +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# Bitmask Post-Instalation script -# (c) LEAP Encryption access Project -# We copy the bitmask-helper plist to the LaunchDaemons folder, and load the bitmask-helper that runs as root. - -LOG=/tmp/$applicationName-install.log - -chmod +x /Applications/$applicationName.app/Contents/MacOS/bitmask-helper -cp se.leap.bitmask-helper.plist /Library/LaunchDaemons/ \ - && echo `date` ":: $applicationName post-install: copied bitmask-helper Plist." >> $$LOG -launchctl load /Library/LaunchDaemons/se.leap.bitmask-helper.plist && echo `date` ":: $applicationName post-install: loaded bitmask-helper." >> $$LOG -chown admin:wheel /Applications/$applicationName.app/Contents/helper -echo `date` ":: $applicationName post-install: ok." >> $$LOG -exit 0 diff --git a/branding/templates/osx/template-preinstall b/branding/templates/osx/template-preinstall deleted file mode 100644 index 90fe7fe..0000000 --- a/branding/templates/osx/template-preinstall +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -# Bitmask Pre-Instalation script -# (c) LEAP Encryption access Project -# We unload the bitmask-helper if it is running, because we can be installing an upgrade. - -LOG=/tmp/$applicationName-install.log - -ps aux | grep [b]itmask-helper \ - && launchctl unload /Library/LaunchDaemons/se.leap.bitmask-helper.plist \ - && echo `date` ":: $applicationName pre-install: unloaded bitmask-helper." >> $$LOG -echo `date` ":: $applicationName pre-install: ok." >> $$LOG -exit 0 |