Files
Tarnax/scripts/verify_profile.py
2026-11-04 15:16:11 +00:00

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()