58 lines
2.4 KiB
Python
58 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Validate Tarnax's embedded profile, including Apple's wildcard App IDs."""
|
|
import argparse
|
|
import datetime
|
|
import fnmatch
|
|
import plistlib
|
|
import sys
|
|
|
|
|
|
def validate(app, profile, device=None, distribution=False):
|
|
bundle = app.get('CFBundleIdentifier')
|
|
if bundle != 'net.absdev.Tarnax':
|
|
raise ValueError('This script installs only net.absdev.Tarnax.')
|
|
entitlements = profile.get('Entitlements', {})
|
|
pattern = entitlements.get('application-identifier', '')
|
|
# The App ID prefix can differ from the Team ID on older Apple accounts.
|
|
prefixes = profile.get('ApplicationIdentifierPrefix', [])
|
|
if not pattern or not any(fnmatch.fnmatchcase(prefix + '.' + bundle, pattern) for prefix in prefixes):
|
|
raise ValueError('Profile does not match Tarnax.')
|
|
expiry = profile.get('ExpirationDate')
|
|
if expiry is None:
|
|
raise ValueError('Profile has no expiration date.')
|
|
if expiry.tzinfo is None:
|
|
expiry = expiry.replace(tzinfo=datetime.timezone.utc)
|
|
if expiry <= datetime.datetime.now(datetime.timezone.utc):
|
|
raise ValueError('The app provisioning profile has expired.')
|
|
devices = profile.get('ProvisionedDevices', [])
|
|
if not devices:
|
|
raise ValueError('Profile does not include registered devices.')
|
|
if device and device not in devices:
|
|
raise ValueError('This iPhone is not included in the app provisioning profile. Register it and export again.')
|
|
if distribution and entitlements.get('get-task-allow', False):
|
|
raise ValueError('Distribution IPA has debugging enabled.')
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('app_plist')
|
|
parser.add_argument('profile_plist')
|
|
parser.add_argument('--device')
|
|
parser.add_argument('--distribution', action='store_true')
|
|
args = parser.parse_args()
|
|
try:
|
|
with open(args.app_plist, 'rb') as f:
|
|
app = plistlib.load(f)
|
|
with open(args.profile_plist, 'rb') as f:
|
|
profile = plistlib.load(f)
|
|
validate(app, profile, args.device, args.distribution)
|
|
except (ValueError, OSError, plistlib.InvalidFileException) as error:
|
|
sys.exit(str(error))
|
|
print('Verified Tarnax', app['CFBundleShortVersionString'], 'build', app['CFBundleVersion'])
|
|
print('Registered devices:', len(profile['ProvisionedDevices']))
|
|
print('Profile expiry:', profile['ExpirationDate'].isoformat())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|