tMerge pull request #5007 from cculianu/fix_codesign_electrum - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 4e10f9e301cc8e72653453c61bc46fe8f195a119 DIR parent c7f3adb67ea6afd50fec60221ba711ddea110281 HTML Author: ThomasV <thomasv@electrum.org> Date: Thu, 17 Jan 2019 16:22:31 +0100 Merge pull request #5007 from cculianu/fix_codesign_electrum t[MacOS] Fixed code signing on macos to code sign *all* embedded binaries Diffstat: M contrib/osx/make_osx | 4 +--- M contrib/osx/osx.spec | 45 +++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 5 deletions(-) --- DIR diff --git a/contrib/osx/make_osx b/contrib/osx/make_osx t@@ -75,7 +75,6 @@ tar xz --directory $BUILDDIR cp $BUILDDIR/libusb/1.0.22/lib/libusb-1.0.dylib contrib/osx echo "82c368dfd4da017ceb32b12ca885576f325503428a4966cc09302cbd62702493 contrib/osx/libusb-1.0.dylib" | \ shasum -a 256 -c || fail "libusb checksum mismatched" -DoCodeSignMaybe "libusb" "contrib/osx/libusb-1.0.dylib" "$APP_SIGN" # If APP_SIGN is empty will be a noop info "Building libsecp256k1" brew install autoconf automake libtool t@@ -88,7 +87,6 @@ git clean -f -x -q make popd cp $BUILDDIR/secp256k1/.libs/libsecp256k1.0.dylib contrib/osx -DoCodeSignMaybe "libsecp256k1" "contrib/osx/libsecp256k1.0.dylib" "$APP_SIGN" # If APP_SIGN is empty will be a noop info "Building CalinsQRReader..." d=contrib/osx/CalinsQRReader t@@ -120,7 +118,7 @@ for d in ~/Library/Python/ ~/.pyenv .; do done info "Building binary" -pyinstaller --noconfirm --ascii --clean --name $VERSION contrib/osx/osx.spec || fail "Could not build binary" +APP_SIGN="$APP_SIGN" pyinstaller --noconfirm --ascii --clean --name $VERSION contrib/osx/osx.spec || fail "Could not build binary" info "Adding bitcoin URI types to Info.plist" plutil -insert 'CFBundleURLTypes' \ DIR diff --git a/contrib/osx/osx.spec b/contrib/osx/osx.spec t@@ -2,13 +2,50 @@ from PyInstaller.utils.hooks import collect_data_files, collect_submodules, collect_dynamic_libs -import sys -import os +import sys, os PACKAGE='Electrum' PYPKG='electrum' MAIN_SCRIPT='run_electrum' ICONS_FILE='electrum.icns' +APP_SIGN = os.environ.get('APP_SIGN', '') + +def fail(*msg): + RED='\033[0;31m' + NC='\033[0m' # No Color + print("\r🗯 {}ERROR:{}".format(RED, NC), *msg) + sys.exit(1) + +def codesign(identity, binary): + d = os.path.dirname(binary) + saved_dir=None + if d: + # switch to directory of the binary so codesign verbose messages don't include long path + saved_dir = os.path.abspath(os.path.curdir) + os.chdir(d) + binary = os.path.basename(binary) + os.system("codesign -v -f -s '{}' '{}'".format(identity, binary))==0 or fail("Could not code sign " + binary) + if saved_dir: + os.chdir(saved_dir) + +def monkey_patch_pyinstaller_for_codesigning(identity): + # Monkey-patch PyInstaller so that we app-sign all binaries *after* they are modified by PyInstaller + # If we app-sign before that point, the signature will be invalid because PyInstaller modifies + # @loader_path in the Mach-O loader table. + try: + import PyInstaller.depend.dylib + _saved_func = PyInstaller.depend.dylib.mac_set_relative_dylib_deps + except (ImportError, NameError, AttributeError): + # Hmm. Likely wrong PyInstaller version. + fail("Could not monkey-patch PyInstaller for code signing. Please ensure that you are using PyInstaller 3.4.") + _signed = set() + def my_func(fn, distname): + _saved_func(fn, distname) + if (fn, distname) not in _signed: + codesign(identity, fn) + _signed.add((fn,distname)) # remember we signed it so we don't sign again + PyInstaller.depend.dylib.mac_set_relative_dylib_deps = my_func + for i, x in enumerate(sys.argv): if x == '--name': t@@ -90,6 +127,10 @@ for x in a.binaries.copy(): a.binaries.remove(x) print('----> Removed x =', x) +# If code signing, monkey-patch in a code signing step to pyinstaller. See: https://github.com/spesmilo/electrum/issues/4994 +if APP_SIGN: + monkey_patch_pyinstaller_for_codesigning(APP_SIGN) + pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz,