diff --git a/AppSigner/MainView.swift b/AppSigner/MainView.swift index ade438d..370ad9c 100644 --- a/AppSigner/MainView.swift +++ b/AppSigner/MainView.swift @@ -854,16 +854,32 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo } } + let bundleID = getPlistKey(appBundleInfoPlist, keyName: "CFBundleIdentifier") + //MARK: Generate entitlements.plist if provisioningFile != nil || useAppBundleProfile { setStatus("Parsing entitlements") - if let profile = ProvisioningProfile(filename: useAppBundleProfile ? appBundleProvisioningFilePath : provisioningFile!, skipGetTaskAllow: shouldSkipGetTaskAllow){ - if let entitlements = profile.getEntitlementsPlist(tempFolder) { + if var profile = ProvisioningProfile(filename: useAppBundleProfile ? appBundleProvisioningFilePath : provisioningFile!){ + if shouldSkipGetTaskAllow { + profile.removeGetTaskAllow() + } + let isWildcard = profile.appID == "*" // TODO: support com.example.* wildcard + if !isWildcard && (newApplicationID != "" && newApplicationID != profile.appID) { + setStatus("Unable to change App ID to \(newApplicationID), provisioning profile won't allow it") + cleanup(tempFolder); return + } else if isWildcard { + if newApplicationID != "" { + profile.update(trueAppID: newApplicationID) + } else if let existingBundleID = bundleID { + profile.update(trueAppID: existingBundleID) + } + } + if let entitlements = profile.getEntitlementsPlist() { Log.write("–––––––––––––––––––––––\n\(entitlements)") Log.write("–––––––––––––––––––––––") do { - try entitlements.write(toFile: entitlementsPlist, atomically: false, encoding: String.Encoding.utf8.rawValue) + try entitlements.write(toFile: entitlementsPlist, atomically: false, encoding: .utf8) setStatus("Saved entitlements to \(entitlementsPlist)") } catch let error as NSError { setStatus("Error writing entitlements.plist, \(error.localizedDescription)") @@ -872,10 +888,6 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo setStatus("Unable to read entitlements from provisioning profile") warnings += 1 } - if profile.appID != "*" && (newApplicationID != "" && newApplicationID != profile.appID) { - setStatus("Unable to change App ID to \(newApplicationID), provisioning profile won't allow it") - cleanup(tempFolder); return - } } else { setStatus("Unable to parse provisioning profile, it may be corrupt") warnings += 1 @@ -891,7 +903,7 @@ class MainView: NSView, URLSessionDataDelegate, URLSessionDelegate, URLSessionDo //MARK: Change Application ID if newApplicationID != "" { - if let oldAppID = getPlistKey(appBundleInfoPlist, keyName: "CFBundleIdentifier") { + if let oldAppID = bundleID { func changeAppexID(_ appexFile: String){ guard allowRecursiveSearchAt(appexFile.stringByDeletingLastPathComponent) else { return diff --git a/ProvisioningProfile.swift b/ProvisioningProfile.swift index f8a91d4..606cce6 100644 --- a/ProvisioningProfile.swift +++ b/ProvisioningProfile.swift @@ -15,8 +15,7 @@ struct ProvisioningProfile { expires: Date, appID: String, teamID: String, - rawXML: String, - entitlements: AnyObject? + entitlements: [String : AnyObject] fileprivate let delegate = NSApplication.shared.delegate as! AppDelegate static func getProfiles() -> [ProvisioningProfile] { @@ -55,41 +54,27 @@ struct ProvisioningProfile { return newProfiles; } - init?(filename: String, skipGetTaskAllow: Bool = false){ + init?(filename: String){ let securityArgs = ["cms","-D","-i", filename] let taskOutput = Process().execute("/usr/bin/security", workingDirectory: nil, arguments: securityArgs) + let rawXML: String if taskOutput.status == 0 { if let xmlIndex = taskOutput.output.range(of: " - var entitlements = resultsdict["Entitlements"] as! Dictionary - entitlements.removeValue(forKey: "get-task-allow") - resultsdict["Entitlements"] = entitlements as AnyObject - - let data = PropertyListSerialization.dataFromPropertyList(resultsdict, format: PropertyListSerialization.PropertyListFormat.xml, errorDescription: nil)! - self.rawXML = String(data: data, encoding: .utf8)! - Log.write("Skipped get-task-allow entitlement!"); - } + rawXML = taskOutput.output } - if let results = try? PropertyListSerialization.propertyList(from: self.rawXML.data(using: String.Encoding.utf8)!, options: PropertyListSerialization.MutabilityOptions(), format: nil) { - if let expirationDate = (results as AnyObject).value(forKey: "ExpirationDate") as? Date, - let creationDate = (results as AnyObject).value(forKey: "CreationDate") as? Date, - let name = (results as AnyObject).value(forKey: "Name") as? String, - let entitlements = (results as AnyObject).value(forKey: "Entitlements"), - let applicationIdentifier = (entitlements as AnyObject).value(forKey: "application-identifier") as? String, + if let results = try? PropertyListSerialization.propertyList(from: rawXML.data(using: String.Encoding.utf8)!, options: .mutableContainers, format: nil) as? [String : AnyObject] { + if let expirationDate = results["ExpirationDate"] as? Date, + let creationDate = results["CreationDate"] as? Date, + let name = results["Name"] as? String, + let entitlements = results["Entitlements"] as? [String : AnyObject], + let applicationIdentifier = entitlements["application-identifier"] as? String, let periodIndex = applicationIdentifier.firstIndex(of: ".") { self.filename = filename self.expires = expirationDate @@ -97,7 +82,7 @@ struct ProvisioningProfile { self.appID = applicationIdentifier.substring(from: applicationIdentifier.index(periodIndex, offsetBy: 1)) self.teamID = applicationIdentifier.substring(to: periodIndex) self.name = name - self.entitlements = entitlements as AnyObject? + self.entitlements = entitlements } else { Log.write("Error processing \(filename.lastPathComponent)") return nil @@ -112,22 +97,27 @@ struct ProvisioningProfile { } } - func getEntitlementsPlist(_ tempFolder: String) -> NSString? { - let mobileProvisionPlist = tempFolder.stringByAppendingPathComponent("mobileprovision.plist") - do { - try self.rawXML.write(toFile: mobileProvisionPlist, atomically: false, encoding: String.Encoding.utf8) - let plistBuddy = Process().execute("/usr/libexec/PlistBuddy", workingDirectory: nil, arguments: ["-c", "Print :Entitlements",mobileProvisionPlist, "-x"]) - if plistBuddy.status == 0 { - return plistBuddy.output as NSString? - } else { - Log.write("PlistBuddy Failed") - Log.write(plistBuddy.output) - return nil - } - } catch let error as NSError { - Log.write("Error writing mobileprovision.plist") - Log.write(error.localizedDescription) - return nil + mutating func removeGetTaskAllow() { + if let _ = entitlements.removeValue(forKey: "get-task-allow") { + Log.write("Skipped get-task-allow entitlement!"); + } else { + Log.write("get-task-allow entitlement not found!"); } } + + mutating func update(trueAppID: String) { + guard let oldIdentifier = entitlements["application-identifier"] as? String else { + Log.write("Error reading application-identifier") + return + } + let newIdentifier = teamID + "." + trueAppID + entitlements["application-identifier"] = newIdentifier as AnyObject + Log.write("Updated application-identifier from '\(oldIdentifier)' to '\(newIdentifier)'") + // TODO: update any other wildcard entitlements + } + + func getEntitlementsPlist() -> String? { + let data = PropertyListSerialization.dataFromPropertyList(entitlements, format: PropertyListSerialization.PropertyListFormat.xml, errorDescription: nil)! + return String(data: data, encoding: .utf8) + } }