/// <summary> /// Constructs a MobileProvision from an xml blob extracted from the real ASN.1 file /// </summary> public MobileProvision(string EmbeddedPListText) { Data = new Utilities.PListHelper(EmbeddedPListText); // Now extract things // Key: ApplicationIdentifierPrefix, Array<String> List<string> PrefixList = Data.GetArray("ApplicationIdentifierPrefix", "string"); if (PrefixList.Count > 1) { Program.Warning("Found more than one entry for ApplicationIdentifierPrefix in the .mobileprovision, using the first one found"); } if (PrefixList.Count > 0) { ApplicationIdentifierPrefix = PrefixList[0]; } // Key: DeveloperCertificates, Array<Data> (uuencoded) string CertificatePassword = ""; List<string> CertificateList = Data.GetArray("DeveloperCertificates", "data"); foreach (string EncodedCert in CertificateList) { byte[] RawCert = Convert.FromBase64String(EncodedCert); DeveloperCertificates.Add(new X509Certificate2(RawCert, CertificatePassword)); } // Key: Name, String if (!Data.GetString("Name", out ProvisionName)) { ProvisionName = "(unknown)"; } // Key: ProvisionedDevices, Array<String> ProvisionedDeviceIDs = Data.GetArray("ProvisionedDevices", "string"); }
/// <summary> /// Extracts the dict values for the Entitlements key and creates a new full .plist file /// from them (with outer plist and dict keys as well as doctype, etc...) /// </summary> public string GetEntitlementsString(string CFBundleIdentifier, out string TeamIdentifier) { Utilities.PListHelper XCentPList = null; Data.ProcessValueForKey("Entitlements", "dict", delegate(XmlNode ValueNode) { XCentPList = Utilities.PListHelper.CloneDictionaryRootedAt(ValueNode); }); // Modify the application-identifier to be fully qualified if needed string CurrentApplicationIdentifier; XCentPList.GetString("application-identifier", out CurrentApplicationIdentifier); XCentPList.GetString("com.apple.developer.team-identifier", out TeamIdentifier); // if (CurrentApplicationIdentifier.Contains("*")) { // Replace the application identifier string NewApplicationIdentifier = String.Format("{0}.{1}", ApplicationIdentifierPrefix, CFBundleIdentifier); XCentPList.SetString("application-identifier", NewApplicationIdentifier); // Replace the keychain access groups // Note: This isn't robust, it ignores the existing value in the wildcard and uses the same value for // each entry. If there is a legitimate need for more than one entry in the access group list, then // don't use a wildcard! List <string> KeyGroups = XCentPList.GetArray("keychain-access-groups", "string"); for (int i = 0; i < KeyGroups.Count; ++i) { string Entry = KeyGroups[i]; if (Entry.Contains("*")) { Entry = NewApplicationIdentifier; } KeyGroups[i] = Entry; } XCentPList.SetValueForKey("keychain-access-groups", KeyGroups); } return(XCentPList.SaveToString()); }
/// <summary> /// Constructs a MobileProvision from an xml blob extracted from the real ASN.1 file /// </summary> public MobileProvision(string EmbeddedPListText) { Data = new Utilities.PListHelper(EmbeddedPListText); // Now extract things // Key: ApplicationIdentifierPrefix, Array<String> List <string> PrefixList = Data.GetArray("ApplicationIdentifierPrefix", "string"); if (PrefixList.Count > 1) { Program.Warning("Found more than one entry for ApplicationIdentifierPrefix in the .mobileprovision, using the first one found"); } if (PrefixList.Count > 0) { ApplicationIdentifierPrefix = PrefixList[0]; } // Example date string from the XML: "2014-06-30T20:45:55Z"; DateTimeStyles AppleDateStyle = DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal; string CreationDateString; if (Data.GetDate("CreationDate", out CreationDateString)) { CreationDate = DateTime.Parse(CreationDateString, CultureInfo.InvariantCulture, AppleDateStyle); } string ExpirationDateString; if (Data.GetDate("ExpirationDate", out ExpirationDateString)) { ExpirationDate = DateTime.Parse(ExpirationDateString, CultureInfo.InvariantCulture, AppleDateStyle); } // Key: DeveloperCertificates, Array<Data> (uuencoded) string CertificatePassword = ""; List <string> CertificateList = Data.GetArray("DeveloperCertificates", "data"); foreach (string EncodedCert in CertificateList) { byte[] RawCert = Convert.FromBase64String(EncodedCert); DeveloperCertificates.Add(new X509Certificate2(RawCert, CertificatePassword)); } // Key: Name, String if (!Data.GetString("Name", out ProvisionName)) { ProvisionName = "(unknown)"; } // Key: ProvisionedDevices, Array<String> ProvisionedDeviceIDs = Data.GetArray("ProvisionedDevices", "string"); // Key: application-identifier, Array<String> Utilities.PListHelper XCentPList = null; Data.ProcessValueForKey("Entitlements", "dict", delegate(XmlNode ValueNode) { XCentPList = Utilities.PListHelper.CloneDictionaryRootedAt(ValueNode); }); // Modify the application-identifier to be fully qualified if needed if (!XCentPList.GetString("application-identifier", out ApplicationIdentifier)) { ApplicationIdentifier = "(unknown)"; } // check for get-task-allow bDebug = XCentPList.GetBool("get-task-allow"); if (!Data.GetString("UUID", out UUID)) { UUID = "(unkown)"; } List <string> Platforms = Data.GetArray("Platform", "string"); if (Platforms.Contains("iOS")) { Platform = "IOS"; } else if (Platforms.Contains("tvOS")) { Platform = "TVOS"; } else { Platform = ""; } }
/// <summary> /// Extracts the dict values for the Entitlements key and creates a new full .plist file /// from them (with outer plist and dict keys as well as doctype, etc...) /// </summary> public string GetEntitlementsString(string CFBundleIdentifier, out string TeamIdentifier) { Utilities.PListHelper XCentPList = null; Data.ProcessValueForKey("Entitlements", "dict", delegate(XmlNode ValueNode) { XCentPList = Utilities.PListHelper.CloneDictionaryRootedAt(ValueNode); }); // Modify the application-identifier to be fully qualified if needed string CurrentApplicationIdentifier; XCentPList.GetString("application-identifier", out CurrentApplicationIdentifier); XCentPList.GetString("com.apple.developer.team-identifier", out TeamIdentifier); // if (CurrentApplicationIdentifier.Contains("*")) { // Replace the application identifier string NewApplicationIdentifier = String.Format("{0}.{1}", ApplicationIdentifierPrefix, CFBundleIdentifier); XCentPList.SetString("application-identifier", NewApplicationIdentifier); // Replace the keychain access groups // Note: This isn't robust, it ignores the existing value in the wildcard and uses the same value for // each entry. If there is a legitimate need for more than one entry in the access group list, then // don't use a wildcard! List <string> KeyGroups = XCentPList.GetArray("keychain-access-groups", "string"); for (int i = 0; i < KeyGroups.Count; ++i) { string Entry = KeyGroups[i]; if (Entry.Contains("*")) { Entry = NewApplicationIdentifier; } KeyGroups[i] = Entry; } XCentPList.SetValueForKey("keychain-access-groups", KeyGroups); } // must have CloudKit and CloudDocuments for com.apple.developer.icloud-services // otherwise the game will not be listed in the Settings->iCloud apps menu on the device { // iOS only if (Platform == "IOS" && XCentPList.HasKey("com.apple.developer.icloud-services")) { List <string> ServicesGroups = XCentPList.GetArray("com.apple.developer.icloud-services", "string"); ServicesGroups.Clear(); ServicesGroups.Add("CloudKit"); ServicesGroups.Add("CloudDocuments"); XCentPList.SetValueForKey("com.apple.developer.icloud-services", ServicesGroups); } // For distribution builds, the entitlements from mobileprovisioning have a modified syntax if (Config.bForDistribution) { // remove the wildcards from the ubiquity-kvstore-identifier string if (XCentPList.HasKey("com.apple.developer.ubiquity-kvstore-identifier")) { string UbiquityKvstoreString; XCentPList.GetString("com.apple.developer.ubiquity-kvstore-identifier", out UbiquityKvstoreString); int DotPosition = UbiquityKvstoreString.LastIndexOf("*"); if (DotPosition >= 0) { string TeamPrefix = DotPosition > 1 ? UbiquityKvstoreString.Substring(0, DotPosition - 1) : TeamIdentifier; string NewUbiquityKvstoreIdentifier = String.Format("{0}.{1}", TeamPrefix, CFBundleIdentifier); XCentPList.SetValueForKey("com.apple.developer.ubiquity-kvstore-identifier", NewUbiquityKvstoreIdentifier); } } // remove the wildcards from the ubiquity-container-identifiers array if (XCentPList.HasKey("com.apple.developer.ubiquity-container-identifiers")) { List <string> UbiquityContainerIdentifiersGroups = XCentPList.GetArray("com.apple.developer.ubiquity-container-identifiers", "string"); for (int i = 0; i < UbiquityContainerIdentifiersGroups.Count; i++) { int DotPosition = UbiquityContainerIdentifiersGroups[i].LastIndexOf("*"); if (DotPosition >= 0) { string TeamPrefix = DotPosition > 1 ? UbiquityContainerIdentifiersGroups[i].Substring(0, DotPosition - 1) : TeamIdentifier; string NewUbiquityContainerIdentifier = String.Format("{0}.{1}", TeamPrefix, CFBundleIdentifier); UbiquityContainerIdentifiersGroups[i] = NewUbiquityContainerIdentifier; } } if (UbiquityContainerIdentifiersGroups.Count == 0) { string NewUbiquityKvstoreIdentifier = String.Format("{0}.{1}", TeamIdentifier, CFBundleIdentifier); UbiquityContainerIdentifiersGroups.Add(NewUbiquityKvstoreIdentifier); } XCentPList.SetValueForKey("com.apple.developer.ubiquity-container-identifiers", UbiquityContainerIdentifiersGroups); } // remove the wildcards from the developer.associated-domains array or string if (XCentPList.HasKey("com.apple.developer.associated-domains")) { string AssociatedDomainsString; XCentPList.GetString("com.apple.developer.associated-domains", out AssociatedDomainsString); //check if the value is string if (AssociatedDomainsString != null && AssociatedDomainsString.Contains("*")) { XCentPList.RemoveKeyValue("com.apple.developer.associated-domains"); } else { //check if the value is an array List <string> AssociatedDomainsGroup = XCentPList.GetArray("com.apple.developer.associated-domains", "string"); if (AssociatedDomainsGroup.Count == 1 && AssociatedDomainsGroup[0].Contains("*")) { XCentPList.RemoveKeyValue("com.apple.developer.associated-domains"); } } } // remove development keys - generated when the cloudkit container is in development mode XCentPList.RemoveKeyValue("com.apple.developer.icloud-container-development-container-identifiers"); } // set the icloud-container-environment according to the project settings if (XCentPList.HasKey("com.apple.developer.icloud-container-environment")) { List <string> ContainerEnvironmentGroup = XCentPList.GetArray("com.apple.developer.icloud-container-environment", "string"); if (ContainerEnvironmentGroup.Count != 0) { ContainerEnvironmentGroup.Clear(); // The new value is a string, not an array string NewContainerEnvironment = Config.bForDistribution ? "Production" : "Development"; XCentPList.SetValueForKey("com.apple.developer.icloud-container-environment", NewContainerEnvironment); } } } return(XCentPList.SaveToString()); }
/// <summary> /// Constructs a MobileProvision from an xml blob extracted from the real ASN.1 file /// </summary> public MobileProvision(string EmbeddedPListText) { Data = new Utilities.PListHelper(EmbeddedPListText); // Now extract things // Key: ApplicationIdentifierPrefix, Array<String> List<string> PrefixList = Data.GetArray("ApplicationIdentifierPrefix", "string"); if (PrefixList.Count > 1) { Program.Warning("Found more than one entry for ApplicationIdentifierPrefix in the .mobileprovision, using the first one found"); } if (PrefixList.Count > 0) { ApplicationIdentifierPrefix = PrefixList[0]; } // Example date string from the XML: "2014-06-30T20:45:55Z"; DateTimeStyles AppleDateStyle = DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal; string CreationDateString; if (Data.GetDate("CreationDate", out CreationDateString)) { CreationDate = DateTime.Parse(CreationDateString, CultureInfo.InvariantCulture, AppleDateStyle); } string ExpirationDateString; if (Data.GetDate("ExpirationDate", out ExpirationDateString)) { ExpirationDate = DateTime.Parse(ExpirationDateString, CultureInfo.InvariantCulture, AppleDateStyle); } // Key: DeveloperCertificates, Array<Data> (uuencoded) string CertificatePassword = ""; List<string> CertificateList = Data.GetArray("DeveloperCertificates", "data"); foreach (string EncodedCert in CertificateList) { byte[] RawCert = Convert.FromBase64String(EncodedCert); DeveloperCertificates.Add(new X509Certificate2(RawCert, CertificatePassword)); } // Key: Name, String if (!Data.GetString("Name", out ProvisionName)) { ProvisionName = "(unknown)"; } // Key: ProvisionedDevices, Array<String> ProvisionedDeviceIDs = Data.GetArray("ProvisionedDevices", "string"); // Key: application-identifier, Array<String> Utilities.PListHelper XCentPList = null; Data.ProcessValueForKey("Entitlements", "dict", delegate(XmlNode ValueNode) { XCentPList = Utilities.PListHelper.CloneDictionaryRootedAt(ValueNode); }); // Modify the application-identifier to be fully qualified if needed if (!XCentPList.GetString("application-identifier", out ApplicationIdentifier)) { ApplicationIdentifier = "(unknown)"; } // check for get-task-allow bDebug = XCentPList.GetBool("get-task-allow"); }