| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import argparse | 5 import argparse |
| 6 import fnmatch | 6 import fnmatch |
| 7 import glob | 7 import glob |
| 8 import os | 8 import os |
| 9 import plistlib | 9 import plistlib |
| 10 import shutil | 10 import shutil |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 'no mobile provisioning profile for "%s"', | 199 'no mobile provisioning profile for "%s"', |
| 200 bundle.identifier) | 200 bundle.identifier) |
| 201 | 201 |
| 202 # Select the most specific mobile provisioning profile, i.e. the one with | 202 # Select the most specific mobile provisioning profile, i.e. the one with |
| 203 # the longest application identifier pattern. | 203 # the longest application identifier pattern. |
| 204 return max( | 204 return max( |
| 205 valid_provisioning_profiles, | 205 valid_provisioning_profiles, |
| 206 key=lambda p: len(p.application_identifier_pattern)) | 206 key=lambda p: len(p.application_identifier_pattern)) |
| 207 | 207 |
| 208 | 208 |
| 209 def CodeSignBundle(binary, bundle, args): | 209 def InstallFramework(framework_path, bundle, args): |
| 210 """Install framework from |framework_path| to |bundle| and code-re-sign it.""" |
| 211 installed_framework_path = os.path.join( |
| 212 bundle.path, 'Frameworks', os.path.basename(framework_path)) |
| 213 |
| 214 if os.path.exists(installed_framework_path): |
| 215 shutil.rmtree(installed_framework_path) |
| 216 |
| 217 shutil.copytree(framework_path, installed_framework_path) |
| 218 |
| 219 framework_bundle = Bundle(installed_framework_path) |
| 220 CodeSignBundle(framework_bundle.binary_path, framework_bundle, args, True) |
| 221 |
| 222 |
| 223 def CodeSignBundle(binary, bundle, args, preserve=False): |
| 210 """Cryptographically signs bundle. | 224 """Cryptographically signs bundle. |
| 211 | 225 |
| 212 Args: | 226 Args: |
| 213 bundle: the Bundle object to sign. | 227 bundle: the Bundle object to sign. |
| 214 args: a dictionary with configuration settings for the code signature, | 228 args: a dictionary with configuration settings for the code signature, |
| 215 need to define 'entitlements_path', 'provisioning_profile_short_name', | 229 need to define 'entitlements_path', 'provisioning_profile_short_name', |
| 216 'deep_signature' and 'identify' keys. | 230 'deep_signature' and 'identify' keys. |
| 217 """ | 231 """ |
| 218 provisioning_profile = FindProvisioningProfile( | 232 provisioning_profile = FindProvisioningProfile( |
| 219 bundle, args.provisioning_profile_short_name) | 233 bundle, args.provisioning_profile_short_name) |
| 220 provisioning_profile.Install(bundle) | 234 provisioning_profile.Install(bundle) |
| 221 | 235 |
| 222 signature_file = os.path.join(bundle.path, '_CodeSignature', 'CodeResources') | 236 if preserve: |
| 223 if os.path.isfile(signature_file): | 237 process = subprocess.Popen([ |
| 224 os.unlink(signature_file) | |
| 225 | |
| 226 shutil.copy(binary, bundle.binary_path) | |
| 227 | |
| 228 if args.preserve: | |
| 229 subprocess.check_call([ | |
| 230 'xcrun', 'codesign', '--force', '--sign', args.identity, | 238 'xcrun', 'codesign', '--force', '--sign', args.identity, |
| 231 '--deep', '--preserve-metadata=identifier,entitlements', | 239 '--deep', '--preserve-metadata=identifier,entitlements', |
| 232 '--timestamp=none', bundle.path]) | 240 '--timestamp=none', bundle.path], stderr=subprocess.PIPE) |
| 241 _, stderr = process.communicate() |
| 242 if process.returncode: |
| 243 sys.stderr.write(stderr) |
| 244 sys.exit(process.returncode) |
| 245 for line in stderr.splitlines(): |
| 246 # Ignore expected warning as we are replacing the signature on purpose. |
| 247 if not line.endswith(': replacing existing signature'): |
| 248 sys.stderr.write(line + '\n') |
| 233 else: | 249 else: |
| 250 signature_file = os.path.join( |
| 251 bundle.path, '_CodeSignature', 'CodeResources') |
| 252 if os.path.isfile(signature_file): |
| 253 os.unlink(signature_file) |
| 254 |
| 255 if os.path.isfile(bundle.binary_path): |
| 256 os.unlink(bundle.binary_path) |
| 257 shutil.copy(binary, bundle.binary_path) |
| 258 |
| 234 entitlements = Entitlements(args.entitlements_path) | 259 entitlements = Entitlements(args.entitlements_path) |
| 235 entitlements.LoadDefaults(provisioning_profile.entitlements) | 260 entitlements.LoadDefaults(provisioning_profile.entitlements) |
| 236 entitlements.ExpandVariables({ | 261 entitlements.ExpandVariables({ |
| 237 'CFBundleIdentifier': bundle.identifier, | 262 'CFBundleIdentifier': bundle.identifier, |
| 238 'AppIdentifierPrefix': '%s.' % (provisioning_profile.team_identifier,) | 263 'AppIdentifierPrefix': '%s.' % (provisioning_profile.team_identifier,) |
| 239 }) | 264 }) |
| 240 | 265 |
| 241 with tempfile.NamedTemporaryFile(suffix='.xcent') as temporary_file_path: | 266 with tempfile.NamedTemporaryFile(suffix='.xcent') as temporary_file_path: |
| 242 entitlements.WriteTo(temporary_file_path.name) | 267 entitlements.WriteTo(temporary_file_path.name) |
| 243 subprocess.check_call([ | 268 subprocess.check_call([ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 254 '--binary', '-b', required=True, | 279 '--binary', '-b', required=True, |
| 255 help='path to the iOS bundle binary') | 280 help='path to the iOS bundle binary') |
| 256 parser.add_argument( | 281 parser.add_argument( |
| 257 '--provisioning-profile', '-p', dest='provisioning_profile_short_name', | 282 '--provisioning-profile', '-p', dest='provisioning_profile_short_name', |
| 258 help='short name of the mobile provisioning profile to use (' | 283 help='short name of the mobile provisioning profile to use (' |
| 259 'if undefined, will autodetect the mobile provisioning ' | 284 'if undefined, will autodetect the mobile provisioning ' |
| 260 'to use)') | 285 'to use)') |
| 261 parser.add_argument( | 286 parser.add_argument( |
| 262 '--identity', '-i', required=True, | 287 '--identity', '-i', required=True, |
| 263 help='identity to use to codesign') | 288 help='identity to use to codesign') |
| 264 group = parser.add_mutually_exclusive_group(required=True) | 289 parser.add_argument( |
| 265 group.add_argument( | |
| 266 '--entitlements', '-e', dest='entitlements_path', | 290 '--entitlements', '-e', dest='entitlements_path', |
| 267 help='path to the entitlements file to use') | 291 help='path to the entitlements file to use') |
| 268 group.add_argument( | 292 parser.add_argument( |
| 269 '--deep', '-d', action='store_true', default=False, dest='preserve', | 293 '--framework', '-F', action='append', default=[], dest="frameworks", |
| 270 help='deep signature (default: %(default)s)') | 294 help='install and resign system framework') |
| 271 args = parser.parse_args() | 295 args = parser.parse_args() |
| 272 | 296 |
| 273 CodeSignBundle(args.binary, Bundle(args.path), args) | 297 bundle = Bundle(args.path) |
| 298 for framework in args.frameworks: |
| 299 InstallFramework(framework, bundle, args) |
| 300 |
| 301 CodeSignBundle(args.binary, bundle, args) |
| 274 | 302 |
| 275 | 303 |
| 276 if __name__ == '__main__': | 304 if __name__ == '__main__': |
| 277 sys.exit(Main()) | 305 sys.exit(Main()) |
| OLD | NEW |