Skip to content

Instantly share code, notes, and snippets.

@NSExceptional
Last active November 8, 2017 23:39
Show Gist options
  • Save NSExceptional/ddd7543fdd6e873edf6acb1affcf714f to your computer and use it in GitHub Desktop.
Save NSExceptional/ddd7543fdd6e873edf6acb1affcf714f to your computer and use it in GitHub Desktop.
A bash function to re-sign an IPA and optionally change its bundle ID.
# Code sign an IPA
# Usage: csipa [-e entitlements -i identity -b newBundleID] <path to IPA>
csipa() {
# Create temp directory
if [[ ! -d /tmp/csipa ]]; then
mkdir /tmp/csipa
fi
# Default variable values
local ipaPath=
local entitlements=
local identity="iPhone Developer: Tanner Bennett (JWB6AQ4N38)"
local bundleid=
# Get arguments
while test $# -gt 0; do
case "$1" in
-h)
echo "Usage: csipa [-e entitlements.xml] [-i identity] <path to IPA>"
echo
return
;;
-b)
shift
bundleid=$1
echo "New bundle ID: $bundleid"
shift
;;
-e)
shift
entitlements="$1"
if [[ -e $entitlements ]]; then
echo "Using entitlements: $entitlements"
entitlements="--entitlements $1"
else
echo "Entitlements: not a regular file"
echo
return
fi
shift
;;
-i)
shift
identity="$1"
echo "Using PP identity pattern: $identity"
shift
;;
*)
ipaPath="$1"
if [[ ! -e $ipaPath ]]; then
echo "Must specify a valid path to an IPA"
echo
return
fi
shift
;;
esac
done
if [[ $ipaPath ]]; then
# Working directory is IPA name without file extension, inside /tmp/csipa
local filename=`basename $ipaPath .ipa`
local outdir="/private/tmp/csipa/$filename"
# Make working directory, unzip
mkdir "$outdir"
if unzip "$ipaPath" -d "$outdir" &>/dev/null
then
# Get path to .app
local appdir=`echo "$outdir/Payload"/*.app`
if [[ ! -d "$appdir" ]]; then
echo "Not a valid IPA"
echo; rm -rf $outdir; return
fi
# Get path to binary
local binary="$appdir"/`defaults read "$appdir/Info.plist" CFBundleExecutable`
if [[ ! -e $binary ]]; then
echo "Error: binary not found: $binary"
echo; rm -rf $outdir; return
fi
# Maybe change bundle ID for Info.plist and *.appex/Info.plist
if [[ $bundleid ]]; then
# Get original bundle ID, "find and replace" old -> new,
# because app extensions have bundle ID prefix
local origbid=`defaults read "$appdir/Info.plist" CFBundleIdentifier`
_setbundleid $origbid $bundleid "$appdir"
for appex in `find "$appdir" -name "*.appex"`; do
_setbundleid $origbid $bundleid $appex
done
fi
# Sign frameworks and other libraries
find "$appdir" \( -name "*.framework" -or -name "*.dylib" -or -name "*.appex" \) -not -path "*.framework/*" -print0 | xargs -0 codesign -fs "$identity" $entitlements
if [[ $? != 0 ]]; then
error "Codesign failed"
fi
# Sign .app (signs the binary)
codesign -fs "$identity" $entitlements "$appdir"
if [[ $? != 0 ]]; then
error "Failed to sign $app"
fi
# Re-pack, rename old IPA to App.ipa.bak
cd "$outdir"
echo $filename.ipa -> $filename.ipa.bak
mv "$ipaPath" "$ipaPath.bak"
zip -qr "$ipaPath" Payload/
cd - > /dev/null
# Cleanup
rm -rf $outdir
else
echo "Error unzipping IPA. Try it yourself:"
echo "unzip -t \"$ipaPath\""
echo; rm -rf $outdir; return
fi
fi
}
# Takes old bundle ID, new bundle ID, and relative path to bundle with Info.plist
_setbundleid() {
local old=$1
local bundleid=$2
local bundle="$3"
local orig=`defaults read "$bundle/Info.plist" CFBundleIdentifier`
local modified=`echo $orig | sed s/$old/$bundleid/g`
echo "$bundle/Info.plist -> [CFBundleIdentifier: \"$modified\"]"
defaults write "$bundle/Info.plist" CFBundleIdentifier $modified
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment