forked from doubledutch/recodesign
-
Notifications
You must be signed in to change notification settings - Fork 0
/
recodesign.sh
executable file
·356 lines (308 loc) · 13.4 KB
/
recodesign.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
#!/bin/sh
# This script was written by Kyle Louis at DoubleDutch
# and is maintained by Dawson Loudon at DoubleDutch
# Resigning DoubleDutch created ios apps, here we go!
# This script requires the path to the .ipa file provided by DoubleDutch
# This script requires the path to the provisioning profile
# pass all the arguments in any order
function info { # print an info log
printf "\033[32m==> %s\033[0m\n" "$1"
}
function error { # print an error log
printf "\033[31m==> %s\033[0m\n" "$1"
exit 1
}
function prompt { # print an info log
printf "\033[34m==> %s\033[0m\n" "$1"
}
function setTimeSignature {
sig1=^\([0-9]{1,2}\)\.[[:space:]]\([A-Za-z]*\)[[:space:]]\([0-9]{4}\)
sig2=^\([0-9]{1,2}\)[[:space:]]\([A-Za-z]*\),[[:space:]]\([0-9]{4}\)
sig3=^\([A-Za-z]*\)[[:space:]]\([0-9]{1,2}\),[[:space:]]\([0-9]{4}\)
sig4=^\([0-9]{1,2}\)[[:space:]]\([A-Za-z]*\)[[:space:]]\([0-9]{4}\)
if [[ "$1" =~ $sig1 ]]; then
timeSignature="%d. %b %Y"
matchedSig=true
fi
if [[ "$1" =~ $sig2 ]]; then
timeSignature="%d %b, %Y"
matchedSig=true
fi
if [[ "$1" =~ $sig3 ]]; then
timeSignature="%b %d, %Y"
matchedSig=true
fi
if [[ "$1" =~ $sig4 ]]; then
timeSignature="%d %b %Y"
matchedSig=true
fi
if ! [[ "$matchedSig" ]]; then
error "Signature date is not recognised. Please take a screenshot and contact customer support. Invalid signature date: $1"
else
info "time sig. used: $timeSignature"
fi
}
info "This is version 2.3.0"
info "If you run into issues, please take screenshots of your terminal window and share with DoubleDutch."
while getopts "ehtv" opt; do
case "$opt" in
e)
enterpriseOpt=true
info "Enterprise Distribution option enabled."
shift 1
;;
h)
info 'This script requires 2 arguments.
The .ipa that DoubleDutch has sent and the provisioning profile.
an example might look like this:
sh recodesign.sh ~/Desktop/provided.ipa ~/Downloads/app.mobileprovision
There are additional flags you can use.
-h help (show this dialog)
-t enable TestFlight option in script (TestFlight is enabled by default)
-v change the version and use a new provisioning profile
If you run into issues, please take screenshots of your terminal window and share with DoubleDutch.'
shift 1
;;
t)
testFlightOpt=true
info "TestFlight option enabled."
shift 1
;;
v)
versionCustomFlag=true
info "Version customization option enabled."
shift 1
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
datevar=$(date +%m_%d_%H_%M)
tmpDir=$(mktemp -dt codesigndd)
currentDir=$(pwd)
# determine file type and assign to correct value
for var do
if [[ -e "$var" ]]; then
if [[ -e ./"$var" ]]; then
var=("$currentDir/$var")
fi
mimeType=$(file --mime-type "$var" | cut -d ":" -f2)
if [[ "$mimeType" == " application/zip" || "$mimeType" == " application/x-ios-app" ]]; then
zipCheck=$(unzip -l "$var" | grep Payload/Flock.app | wc -l )
if [[ ! $zipCheck == 0 ]]; then
app="$var"
else
error "$var" is not the .ipa provided by DoubleDutch
fi
elif [[ "$mimeType" == " application/octet-stream" ]]; then
profile="$var"
else
error "$var is an invalid argument as it is of file type:$mimeType."
fi
else
error "$var is an invalid argument as it is of file type:$mimeType."
fi
done
[[ -d $tmpDir ]] || (error "Could not create directory")
pushd $tmpDir &> /dev/null
if [[ $# -lt 2 ]]; then
error 'Usage: This script requires 2 arguments, that can be passed in any order.
The path to the .ipa file DoubleDutch sent.
The path to the provisioning profile you created for this app.'
fi
if [[ ! -f /usr/libexec/PlistBuddy ]]; then
error "This script requires Xcode Command Line Tools, which are not present on your system.
For more information see https://developer.apple.com/library/ios/technotes/tn2339/_index.html
You can also try typing this on command line: Xcode-select --install"
fi
# this block setups the initial filepath for the codesigning to happen
cp "$app" app.zip
cp "$profile" temp.mobileprovision
info "Unzipping IPA, this might take a moment."
unzip app.zip >&-
if ! [[ -e Payload/Flock.app/info.plist ]]; then
error "There is an issue with the IPA. Please contact DoubleDutch for a new file."
fi
if [[ ! $enterpriseOpt ]] && [[ ! -e SwiftSupport ]]; then
error "SwiftSupport folder is missing. Please contact DoubleDutch for a new file."
fi
# this block extracts data from the provisioning profile and assigns that data to variables
security cms -D -i temp.mobileprovision > temp.plist 2> /dev/null
profileCheck=$(grep -c "data" temp.plist)
if [[ profileCheck -lt 1 ]]; then
error "There is an issue with the provided provisioning profile.
Please try again with a freshly downloaded provisioning profile."
fi
expiryDate=$(/usr/libexec/PlistBuddy -c "Print ExpirationDate" temp.plist | cut -d " " -f 1-3,6 -) 2> /dev/null
expiryFormatted=$(date -jf"%a %b %d %Y" "$expiryDate" +%Y%m%d) 2> /dev/null
todayFormatted=$(date +%Y%m%d) 2> /dev/null
info "$expiryFormatted to $todayFormatted"
if [[ "$expiryFormatted" -lt "$todayFormatted" ]]; then
error "Provisioning profile has expired.
Go to developer.apple.com and update Provisioning profile with an up to date Distribution certificate."
fi
testFlightCheck=$(/usr/libexec/PlistBuddy -c "Print Entitlements:beta-reports-active" temp.plist)
pushCheck=$(/usr/libexec/PlistBuddy -c "Print Entitlements:aps-environment" temp.plist)
asdCheck=$(grep -c "com.apple.developer.associated-domains" temp.plist)
appIdLong=$(/usr/libexec/PlistBuddy -c "Print Entitlements:application-identifier" temp.plist)
appIdPrefix=$(echo $appIdLong | cut -d "." -f 1)
reverseUrl=$(echo $appIdLong | cut -d "." -f2- )
finalName=$(echo $reverseUrl | tr "." "_")
teamNameProvisioningProfile=$(/usr/libexec/PlistBuddy -c "Print TeamName" temp.plist)
teamIdProvisioningProfile=$(/usr/libexec/PlistBuddy -c "Print TeamIdentifier:0" temp.plist)
contextId=$(/usr/libexec/PlistBuddy -c "Print DDContextIdentifier" Info.plist)
if [[ ! $teamIdProvisioningProfile == $appIdPrefix ]]; then
info "Team ID and App ID Prefix do not match. This is allowed but not advised. No action needed at this time."
fi
info "Creating entitlements.plist based on existing app"
/usr/bin/codesign -d --entitlements :entitlements.plist Payload/Flock.app &> /dev/null
if [[ ! -e entitlements.plist ]]; then
error "Entitlements.plist not created. Run script again."
fi
/usr/libexec/PlistBuddy -c "Set com.apple.developer.team-identifier $teamIdProvisioningProfile" entitlements.plist
/usr/libexec/PlistBuddy -c "Set application-identifier $appIdLong" entitlements.plist
/usr/libexec/PlistBuddy -c "Set keychain-access-groups:0 $appIdLong" entitlements.plist
/usr/libexec/PlistBuddy -c "Set com.apple.developer.associated-domains:0 applinks:www.doubledutch.me" entitlements.plist
/usr/libexec/PlistBuddy -c "Set com.apple.developer.associated-domains:1 applinks:doubledutch.me" entitlements.plist
/usr/libexec/PlistBuddy -c "Set com.apple.developer.associated-domains:2 applinks:$contextId.doubledutch.io" entitlements.plist
if [[ $testFlightOpt ]]; then
prompt "Would you like to disable TestFlight? If so type 'y' otherwise type 'n' or press Enter"
read choice
if [[ $choice == 'y' ]]; then
/usr/libexec/PlistBuddy -c "Delete beta-reports-active" entitlements.plist
fi
fi
if [[ $asdCheck == "0" ]]
then
error "This provisioning profile does not have Associated Domains entitlement!
This entitlement is required by this app and can be enabled from developer.apple.com.
It will require a new provisoining profile after the App ID is updated to include Associated Domains."
fi
if [[ "$pushCheck" = "production" ]];
then
info "Push is enabled for use in production on this provisioning profile."
elif [[ "$pushCheck" = "development" ]];
then
info "Push is enabled for use in development on this provisioning profile."
info "This provisioning profile cannot be used for upload to App Store."
/usr/libexec/PlistBuddy -c "Set aps-environment development" entitlements.plist
else
info "This provisioning profile doesn't have push entitlement!"
fi
info "Testflight Enabled: $testFlightCheck"
if [[ "$testFlightCheck" == "true" ]]; then
/usr/libexec/PlistBuddy -c "Add beta-reports-active bool true" entitlements.plist
fi
# move the provisioning profile into the app
cp temp.mobileprovision Payload/Flock.app/embedded.mobileprovision
# This block edits the info.plist
/usr/libexec/PlistBuddy -c "Set CFBundleIdentifier $reverseUrl" Payload/Flock.app/info.plist
/usr/libexec/PlistBuddy -c "Set CFBundleURLTypes:0:CFBundleURLName $reverseUrl.context_id" Payload/Flock.app/info.plist
/usr/libexec/PlistBuddy -c "Set CFBundleURLTypes:0:CFBundleURLSchemes:0 dd$contextId" Payload/Flock.app/info.plist
if [[ $versionCustomFlag ]]; then
shortVersion=$(/usr/libexec//PlistBuddy -c "Print CFBundleShortVersionString" Payload/Flock.app/info.plist)
longerVersion=$(/usr/libexec//PlistBuddy -c "Print CFBundleVersion" Payload/Flock.app/info.plist)
info "current Short version is $shortVersion"
prompt "Do you want to change the short version string?
If so, type the version as x.x.x when done hit Enter.
To keep the existing shortVersion type 'n' then hit Enter"
read newShort
if ! [[ $newShort == "n" ]]; then
/usr/libexec//PlistBuddy -c "Set CFBundleShortVersionString $newShort" Payload/Flock.app/info.plist
fi
info "current longer version is $longerVersion"
prompt "Do you want to change the long version string?
If so, type the version as x.x.x.x when done hit Enter.
To keep the existing long version string type 'n' then hit Enter"
read newLong
if ! [[ $newLong == "n" ]]; then
/usr/libexec//PlistBuddy -c "Set CFBundleVersion $newLong" Payload/Flock.app/info.plist
fi
fi
# This is the actual codesigning
# determines the sha-1 value of the distribution certificate that is embedded in the provided provisioning profile $profile
certHash=$(cat temp.plist \
| sed -ne 's/^.*<data>\(.*\)<\/data>.*$/\1/p' \
| base64 -D \
| shasum \
| cut -d " " -f1 \
| tr '[:lower:]' '[:upper:]')
/usr/bin/security find-identity -v -p codesigning > identity.txt
countOfSigningIdentities=$(cat identity.txt \
| grep "valid identities found" \
| cut -d "v" -f1 \
| tr -d [:blank:])
if [[ ! $countOfSigningIdentities == 0 ]]; then
info "You have $countOfSigningIdentities valid signing identities in your Keychain."
else
error "You have 0 valid signing identities.
A valid Distribution certificate is needed to continue."
fi
certHashCount=$(grep "$certHash" identity.txt | wc -l | tr -d [:blank:])
if ! [[ "$certHashCount" == "0" ]]; then
info "Distribution Certificate present for $teamNameProvisioningProfile"
info "Codesigning the App"
if [[ $enterpriseOpt == true ]]; then
info "Signing app for Enterprise Distribution"
codesign -fs "$certHash" Payload/Flock.app/Frameworks/*.dylib
fi
if [[ -e Payload/Flock.app/Frameworks/Sentry.framework ]]; then
codesign -fs "$certHash" Payload/Flock.app/Frameworks/Sentry.framework >/dev/null
fi
codesign -fs "$certHash" --entitlements entitlements.plist Payload/Flock.app >/dev/null
elif [[ "$certHashCount" == "0" ]]; then
error "The correct distribution certificate is not present in Keychain Access.
Match the expiry date of the Distribution Certificate with that from the provisioning profile, which is $expirydate"
fi
#info "This is the contents of entitlements file that was used:"
#codesign -d --entitlements :- Payload/Flock.app
# validation
printf "Validating the signing [ ]\r"
codesign -dvvv Payload/Flock.app &> validation.txt
#cat validation.txt
validationReverseURL=$(grep "Identifier" validation.txt | cut -d "=" -f2 | tr "\n" " " | cut -d " " -f1)
validationTeamDigit=$(grep "TeamIdentifier" validation.txt | cut -d "=" -f2)
validationSignedTime=$(grep "Signed Time" validation.txt | cut -d "=" -f2 | cut -d "," -f1-2)
entitlementsSigningTeamDigit=$(/usr/libexec/PlistBuddy -c "Print com.apple.developer.team-identifier" entitlements.plist)
setTimeSignature "$validationSignedTime"
if [[ "$timeSignature" ]]; then
validationSignedTimeFormatted=$(date -jf"$timeSignature" "$validationSignedTime" +%Y%m%d)
if [[ "$validationSignedTimeFormatted" -ne "$todayFormatted" ]];
then
info "Comparing $validationSignedTimeFormatted to $todayFormatted failed."
error "Time of codesigning not correct. Codesigning was not successful."
fi
fi
printf " Validating the signing [- ]\r"
sleep 1
if [[ "$reverseUrl" != "$validationReverseURL" ]];
then
error "Reverse URL was not updated successfully. Codesigning was not successful."
fi
printf " Validating the signing [-- ]\r"
sleep 1
if [[ "$validationTeamDigit" != "$teamIdProvisioningProfile" ]];
then
error "Team Identifier is incorrect. Codesigning was not successful."
fi
printf " Validating the signing [--- ]\r"
sleep 1
if [[ "$entitlementsSigningTeamDigit" != "$teamIdProvisioningProfile" ]];
then
error "Team Identifier is incorrect. Codesigning was not successful."
fi
printf " Validating the signing [----]\n"
info "App Signing Validated"
info "Zipping IPA, this might take a moment."
mkdir ~/desktop/Codesign_Output-$datevar
mv entitlements.plist ~/Desktop/Codesign_Output-$datevar/entitlements.plist
if [[ $enterpriseOpt == true ]]; then
info "Exporting app for Enterprise Distribution"
zip -rq ~/Desktop/Codesign_Output-$datevar/"$finalName"-enterprise-build.ipa Payload/
else
info "Exporting app for App Store Distribution"
zip -rq ~/Desktop/Codesign_Output-$datevar/"$finalName"-appstore-build.ipa Payload/ SwiftSupport/
fi
info "The finished file is on your Desktop in a folder called Codesign_Output-$datevar"
open ~/Desktop/Codesign_Output-$datevar