1cb93a386Sopenharmony_ci#!/usr/bin/env python2.7
2cb93a386Sopenharmony_ci#
3cb93a386Sopenharmony_ci# Copyright 2017 Google Inc.
4cb93a386Sopenharmony_ci#
5cb93a386Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be
6cb93a386Sopenharmony_ci# found in the LICENSE file.
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ciimport glob
9cb93a386Sopenharmony_ciimport os
10cb93a386Sopenharmony_ciimport os.path
11cb93a386Sopenharmony_ciimport re
12cb93a386Sopenharmony_ciimport shutil
13cb93a386Sopenharmony_ciimport subprocess
14cb93a386Sopenharmony_ciimport sys
15cb93a386Sopenharmony_ciimport tempfile
16cb93a386Sopenharmony_ci
17cb93a386Sopenharmony_ci# Arguments to the script:
18cb93a386Sopenharmony_ci#  pkg              path to application directory, e.g. out/Debug/dm.app
19cb93a386Sopenharmony_ci#                   executable and plist should already be in this directory
20cb93a386Sopenharmony_ci#  identstr         search string (regex fragment) for code signing identity
21cb93a386Sopenharmony_ci#  profile          path or name of provisioning profile
22cb93a386Sopenharmony_cipkg,identstr,profile = sys.argv[1:]
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ci# Find the signing identity.
25cb93a386Sopenharmony_ciidentity = None
26cb93a386Sopenharmony_cifor line in subprocess.check_output(['security', 'find-identity']).split('\n'):
27cb93a386Sopenharmony_ci  m = re.match(r'''.*\) (.*) "''' + identstr + '"', line)
28cb93a386Sopenharmony_ci  if m:
29cb93a386Sopenharmony_ci    identity = m.group(1)
30cb93a386Sopenharmony_ciif identity is None:
31cb93a386Sopenharmony_ci  print("Signing identity matching '" + identstr + "' not found.")
32cb93a386Sopenharmony_ci  print("Please verify by running 'security find-identity' or checking your keychain.")
33cb93a386Sopenharmony_ci  sys.exit(1)
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ci# Find the mobile provisioning profile.
36cb93a386Sopenharmony_cimobileprovision = None
37cb93a386Sopenharmony_ciif os.path.isfile(profile):
38cb93a386Sopenharmony_ci  mobileprovision = profile
39cb93a386Sopenharmony_cielse:
40cb93a386Sopenharmony_ci  for p in glob.glob(os.path.join(os.environ['HOME'], 'Library', 'MobileDevice',
41cb93a386Sopenharmony_ci                                  'Provisioning Profiles',
42cb93a386Sopenharmony_ci                                  '*.mobileprovision')):
43cb93a386Sopenharmony_ci    if re.search(r'''<key>Name</key>
44cb93a386Sopenharmony_ci\t<string>''' + profile + r'''</string>''', open(p).read(), re.MULTILINE):
45cb93a386Sopenharmony_ci      mobileprovision = p
46cb93a386Sopenharmony_ciif mobileprovision is None:
47cb93a386Sopenharmony_ci  print("Provisioning profile matching '" + profile + "' not found.")
48cb93a386Sopenharmony_ci  print("Please verify that the correct profile is installed in '${HOME}/Library/MobileDevice/Provisioning Profiles' or specify the path directly.")
49cb93a386Sopenharmony_ci  sys.exit(1)
50cb93a386Sopenharmony_ci
51cb93a386Sopenharmony_ci# The .mobileprovision just gets copied into the package.
52cb93a386Sopenharmony_cishutil.copy(mobileprovision,
53cb93a386Sopenharmony_ci            os.path.join(pkg, 'embedded.mobileprovision'))
54cb93a386Sopenharmony_ci
55cb93a386Sopenharmony_ci# Extract the appliciation identitifer prefix from the .mobileprovision.
56cb93a386Sopenharmony_cim = re.search(r'''<key>ApplicationIdentifierPrefix</key>
57cb93a386Sopenharmony_ci\t<array>
58cb93a386Sopenharmony_ci\t<string>(.*)</string>''', open(mobileprovision).read(), re.MULTILINE)
59cb93a386Sopenharmony_ciprefix = m.group(1)
60cb93a386Sopenharmony_ci
61cb93a386Sopenharmony_ciapp, _ = os.path.splitext(os.path.basename(pkg))
62cb93a386Sopenharmony_ci
63cb93a386Sopenharmony_ci# Write a minimal entitlements file, then codesign.
64cb93a386Sopenharmony_ciwith tempfile.NamedTemporaryFile() as f:
65cb93a386Sopenharmony_ci  f.write('''
66cb93a386Sopenharmony_ci<plist version="1.0">
67cb93a386Sopenharmony_ci  <dict>
68cb93a386Sopenharmony_ci    <key>application-identifier</key> <string>{prefix}.com.google.{app}</string>
69cb93a386Sopenharmony_ci    <key>get-task-allow</key>         <true/>
70cb93a386Sopenharmony_ci  </dict>
71cb93a386Sopenharmony_ci</plist>
72cb93a386Sopenharmony_ci'''.format(prefix=prefix, app=app))
73cb93a386Sopenharmony_ci  f.flush()
74cb93a386Sopenharmony_ci
75cb93a386Sopenharmony_ci  subprocess.check_call(['codesign',
76cb93a386Sopenharmony_ci                         '--force',
77cb93a386Sopenharmony_ci                         '--sign', identity,
78cb93a386Sopenharmony_ci                         '--entitlements', f.name,
79cb93a386Sopenharmony_ci                         '--timestamp=none',
80cb93a386Sopenharmony_ci                         pkg])
81