Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[msbuild] Sign simulator apps by default. Fixes #18469. #20824

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion msbuild/Xamarin.MacDev.Tasks/Tasks/Codesign.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,11 @@ bool ExecuteUnsafe ()
var info = new SignInfo { Item = item };
if (!Validate (info))
continue;
if (NeedsCodesign (resourcesToSign, i, info.GetStampFileContents (this)))
if (NeedsCodesign (resourcesToSign, i, info.GetStampFileContents (this))) {
itemsToSign.Add (info);
} else {
resourcesToSign [i] = null;
}
}

if (Log.HasLoggedErrors)
Expand Down
55 changes: 42 additions & 13 deletions msbuild/Xamarin.MacDev.Tasks/Tasks/CompileEntitlements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,22 @@ protected string EntitlementBundlePath {
}
}

bool IsDeviceOrDesktop {
get {
switch (Platform) {
case ApplePlatform.iOS:
case ApplePlatform.TVOS:
case ApplePlatform.WatchOS:
return !SdkIsSimulator;
case ApplePlatform.MacOSX:
case ApplePlatform.MacCatalyst:
return true;
default:
throw new InvalidOperationException (string.Format (MSBStrings.InvalidPlatform, Platform));
}
}
}

PString MergeEntitlementString (PString pstr, MobileProvision? profile, bool expandWildcards, string? key)
{
string TeamIdentifierPrefix;
Expand All @@ -146,7 +162,7 @@ PString MergeEntitlementString (PString pstr, MobileProvision? profile, bool exp
if (string.IsNullOrEmpty (pstr.Value))
return (PString) pstr.Clone ();

if (profile is null) {
if (profile is null && IsDeviceOrDesktop) {
if (!warnedTeamIdentifierPrefix && pstr.Value.Contains ("$(TeamIdentifierPrefix)")) {
Log.LogWarning (null, null, null, Entitlements, 0, 0, 0, 0, MSBStrings.W0108b /* Cannot expand $(TeamIdentifierPrefix) in Entitlements.plist without a provisioning profile for key '{0}' with value '{1}' */, key, pstr.Value);
warnedTeamIdentifierPrefix = true;
Expand Down Expand Up @@ -456,7 +472,7 @@ public override bool Execute ()
MobileProvision? profile;
PDictionary template;
PDictionary compiled;
PDictionary archived;
PDictionary? archived = null;
string path;

switch (SdkPlatform) {
Expand Down Expand Up @@ -509,7 +525,27 @@ public override bool Execute ()
}

compiled = GetCompiledEntitlements (profile, template);
archived = GetArchivedExpandedEntitlements (template, compiled);

Directory.CreateDirectory (Path.GetDirectoryName (CompiledEntitlements!.ItemSpec));

if (SdkIsSimulator) {
var simulatedEntitlements = compiled;
var simulatedXcent = Path.ChangeExtension (CompiledEntitlements.ItemSpec, "").TrimEnd ('.') + "-Simulated.xcent";
try {
WriteXcent (simulatedEntitlements, simulatedXcent);
} catch (Exception ex) {
Log.LogError (MSBStrings.E0114, simulatedXcent, ex.Message);
return false;
}

EntitlementsInExecutable = new TaskItem (simulatedXcent);

// No matter what, I've only been able to make Xcode apply a single entitlement to simulator builds: com.apple.security.get-task-allow
compiled = new PDictionary ();
compiled.Add ("com.apple.security.get-task-allow", new PBoolean (true));
} else {
archived = GetArchivedExpandedEntitlements (template, compiled);
}

try {
Directory.CreateDirectory (Path.GetDirectoryName (CompiledEntitlements!.ItemSpec));
Expand All @@ -519,17 +555,10 @@ public override bool Execute ()
return false;
}

SaveArchivedExpandedEntitlements (archived);
if (archived is not null)
SaveArchivedExpandedEntitlements (archived);

if (Platform == Utils.ApplePlatform.MacCatalyst) {
EntitlementsInSignature = CompiledEntitlements;
} else if (SdkIsSimulator) {
if (compiled.Count > 0) {
EntitlementsInExecutable = CompiledEntitlements;
}
} else {
EntitlementsInSignature = CompiledEntitlements;
}
EntitlementsInSignature = CompiledEntitlements;

return !Log.HasLoggedErrors;
}
Expand Down
59 changes: 1 addition & 58 deletions msbuild/Xamarin.MacDev.Tasks/Tasks/DetectSigningIdentity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -591,64 +591,7 @@ public override bool Execute ()
return !Log.HasLoggedErrors;
}
} else {
// Framework is either iOS, tvOS or watchOS
if (SdkIsSimulator) {
if (AppleSdkSettings.XcodeVersion.Major >= 8 && RequireProvisioningProfile) {
// Note: Starting with Xcode 8.0, we need to codesign iOS Simulator builds that enable Entitlements
// in order for them to run. The "-" key is a special value allowed by the codesign utility that
// allows us to get away with not having an actual codesign key.
DetectedCodeSigningKey = "-";

if (!IsAutoCodeSignProfile (ProvisioningProfile)) {
identity.Profile = MobileProvisionIndex.GetMobileProvision (platform, ProvisioningProfile);

if (identity.Profile is null) {
Log.LogError (MSBStrings.E0140, PlatformName, ProvisioningProfile);
return false;
}

identity.AppId = ConstructValidAppId (identity.Profile, identity.BundleId);
if (identity.AppId is null) {
Log.LogError (MSBStrings.E0141, identity.BundleId, ProvisioningProfile);
return false;
}

provisioningProfileName = identity.Profile.Name;

DetectedProvisioningProfile = identity.Profile.Uuid;
DetectedDistributionType = identity.Profile.DistributionType.ToString ();
} else {
certs = new X509Certificate2 [0];

if ((profiles = GetProvisioningProfiles (platform, type, identity, certs)) is null)
return false;

if ((pairs = GetCodeSignIdentityPairs (profiles, certs)) is null)
return false;

var match = GetBestMatch (pairs, identity);
identity.Profile = match.Profile;
identity.AppId = match.AppId;

if (identity.Profile is not null) {
DetectedDistributionType = identity.Profile.DistributionType.ToString ();
DetectedProvisioningProfile = identity.Profile.Uuid;
provisioningProfileName = identity.Profile.Name;
}

DetectedAppId = identity.AppId;
}
} else {
// Note: Do not codesign. Codesigning seems to break the iOS Simulator in older versions of Xcode.
DetectedCodeSigningKey = null;
}

ReportDetectedCodesignInfo ();

return !Log.HasLoggedErrors;
}

if (!SdkIsSimulator && !RequireCodeSigning) {
if (SdkIsSimulator || !RequireCodeSigning) {
// The "-" key is a special value allowed by the codesign utility that
// allows us to get away with not having an actual codesign key.
DetectedCodeSigningKey = "-";
Expand Down
31 changes: 30 additions & 1 deletion msbuild/Xamarin.MacDev.Tasks/Tasks/LinkNativeCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ bool ExecuteUnsafe ()
foreach (var obj in ObjectFiles)
arguments.Add (Path.GetFullPath (obj.ItemSpec));

arguments.AddRange (GetEmbedEntitlementsInExecutableLinkerFlags (EntitlementsInExecutable));
arguments.AddRange (GetEmbedEntitlementsWithDerInExecutableLinkerFlags (EntitlementsInExecutable));

arguments.Add ("-o");
arguments.Add (Path.GetFullPath (OutputFile));
Expand Down Expand Up @@ -243,6 +243,20 @@ bool ExecuteUnsafe ()
return !Log.HasLoggedErrors;
}

IEnumerable<string> GetEmbedEntitlementsWithDerInExecutableLinkerFlags (string entitlements)
{
var rv = GetEmbedEntitlementsInExecutableLinkerFlags (entitlements).ToList ();
if (rv.Count > 0) {
rv.AddRange (new string [] {
"-Xlinker", "-sectcreate",
"-Xlinker", "__TEXT",
"-Xlinker", "__ents_der",
"-Xlinker", ConvertEntitlementsToDerEntitlements (Path.GetFullPath (entitlements)),
});
}
return rv;
}

public static string [] GetEmbedEntitlementsInExecutableLinkerFlags (string entitlements)
{
if (string.IsNullOrEmpty (entitlements))
Expand All @@ -259,6 +273,21 @@ public static string [] GetEmbedEntitlementsInExecutableLinkerFlags (string enti
};
}

string ConvertEntitlementsToDerEntitlements (string entitlements)
{
var derEntitlements = entitlements + ".der";
var arguments = new List<string> () {
"derq",
"query",
"-f", "xml",
"-i", entitlements,
"-o", derEntitlements,
"--raw",
};
ExecuteAsync ("xcrun", arguments, sdkDevPath: SdkDevPath).Wait ();
return derEntitlements;
}

static bool EntitlementsRequireLinkerFlags (string path)
{
try {
Expand Down
8 changes: 3 additions & 5 deletions msbuild/Xamarin.Shared/Xamarin.Shared.props
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,12 @@ Copyright (C) 2020 Microsoft. All rights reserved.
</PropertyGroup>

<!-- RequireCodeSigning -->
<!-- iOS/watchOS/tvOS is simple: device builds require code signing, simulator builds do not. This is a big lie, for some simulator builds need to be signed, but the _DetectCodeSigning task handles those cases. -->
<!-- iOS/watchOS/tvOS is simple: device builds require code signing, simulator builds technically don't even though some important features won't work unless the app is signed (launch screen won't show for instance) -->
<PropertyGroup Condition="'$(_PlatformName)' != 'macOS' And '$(_PlatformName)' != 'MacCatalyst'">
<!-- Make it possible to override the default logic by setting EnableCodeSigning -->
<_RequireCodeSigning Condition="'$(_RequireCodeSigning)' == ''">$(EnableCodeSigning)</_RequireCodeSigning>
<!-- Device builds must be signed -->
<_RequireCodeSigning Condition="'$(_RequireCodeSigning)' == '' And '$(ComputedPlatform)' == 'iPhone'">true</_RequireCodeSigning>
<!-- Otherwise code signing is disabled by default (simulator builds)-->
<_RequireCodeSigning Condition="'$(_RequireCodeSigning)' == ''">false</_RequireCodeSigning>
<!-- Device builds must be signed, and some features won't work in the simulator if the app isn't signed (launch screen for instance), so default to always sign -->
<_RequireCodeSigning Condition="'$(_RequireCodeSigning)' == ''">true</_RequireCodeSigning>
</PropertyGroup>
<!-- macOS is a bit more complicated:
* 'EnableCodeSigning' specifies whether the app is signed or not, and this defaults to false if it's not set.
Expand Down
5 changes: 0 additions & 5 deletions tests/common/MonoNativeConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ public enum MonoNativeLinkMode {
Static,
Dynamic,
Framework,
Symlink,
}

public enum MonoNativeFlavor {
Expand All @@ -24,8 +23,6 @@ public static MonoNativeLinkMode LinkMode {
return MonoNativeLinkMode.Static;
#elif MONO_NATIVE_DYNAMIC
return MonoNativeLinkMode.Dynamic;
#elif MONO_NATIVE_SYMLINK
return MonoNativeLinkMode.Symlink;
#else
return MonoNativeLinkMode.None;
#endif
Expand Down Expand Up @@ -76,8 +73,6 @@ public static string GetPInvokeLibraryName (MonoNativeFlavor flavor, MonoNativeL
return null;
case MonoNativeLinkMode.Dynamic:
return GetDynamicLibraryName (flavor);
case MonoNativeLinkMode.Symlink:
return "libmono-native.dylib";
default:
Assert.Fail ($"Invalid link mode: {MonoNativeConfig.LinkMode}");
throw new NotImplementedException ();
Expand Down
2 changes: 1 addition & 1 deletion tests/dotnet/UnitTests/BundleStructureTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ public enum CodeSignature {
// Debug
[TestCase (ApplePlatform.iOS, "ios-arm64", CodeSignature.All, "Debug")]
[TestCase (ApplePlatform.iOS, "ios-arm64;ios-arm", CodeSignature.All, "Debug")]
[TestCase (ApplePlatform.iOS, "iossimulator-x64", CodeSignature.Frameworks, "Debug")]
[TestCase (ApplePlatform.iOS, "iossimulator-x64", CodeSignature.All, "Debug")]
[TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64", CodeSignature.All, "Debug")]
[TestCase (ApplePlatform.MacCatalyst, "maccatalyst-x64;maccatalyst-arm64", CodeSignature.All, "Debug")]
[TestCase (ApplePlatform.MacOSX, "osx-x64", CodeSignature.Frameworks, "Debug")]
Expand Down
2 changes: 1 addition & 1 deletion tests/introspection/iOS/introspection-ios.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\iPhoneSimulator\$(Configuration)-unified</OutputPath>
<DefineConstants>DEBUG;MONOTOUCH;MONO_NATIVE_SYMLINK;$(DefineConstants)</DefineConstants>
<DefineConstants>DEBUG;MONOTOUCH;MONO_NATIVE_STATIC;$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>0</WarningLevel>
<MtouchLink>None</MtouchLink>
Expand Down
13 changes: 0 additions & 13 deletions tests/mono-native/Introspection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,6 @@ void CheckStaticLibrary ()
Assert.That (count, Is.EqualTo (0), "zero mono-native libraries.");
}

void CheckSymlinkedLibrary ()
{
AssertShouldExist ("libmono-native.dylib");
AssertShouldNotExist ("libmono-native-compat.dylib");
AssertShouldNotExist ("libmono-native-unified.dylib");

var count = CountFiles ("libmono-native*");
Assert.That (count, Is.EqualTo (1), "exactly one mono-native library.");
}

[Test]
public void CheckLibrary ()
{
Expand All @@ -69,9 +59,6 @@ public void CheckLibrary ()
case MonoNativeLinkMode.Static:
CheckStaticLibrary ();
break;
case MonoNativeLinkMode.Symlink:
CheckSymlinkedLibrary ();
break;
default:
Assert.Fail ($"Unknown link mode: {MonoNativeConfig.LinkMode}");
break;
Expand Down
1 change: 0 additions & 1 deletion tests/mono-native/iOS/mono-native.csproj.template
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<MonoNativeMode Condition="'$(TargetFrameworkIdentifier)|$(Configuration)|$(Platform)' == 'Xamarin.iOS|Debug|iPhoneSimulator'">MONO_NATIVE_SYMLINK</MonoNativeMode>
<MonoNativeMode Condition="'$(MonoNativeMode)' == ''">MONO_NATIVE_STATIC</MonoNativeMode>
<DefineConstants>$(MonoNativeMode);$(DefineConstants)</DefineConstants>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion tests/monotouch-test/dotnet/shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<LinkMode>None</LinkMode>
<!-- Don't remove native symbols, because it makes debugging native crashes harder -->
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
<CodesignEntitlements Condition="'$(Platform)' == 'iPhoneSimulator'">$(MonoTouchTestDirectory)\Entitlements.plist</CodesignEntitlements>
<CodesignEntitlements Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'iOS' Or $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tvOS'">$(MonoTouchTestDirectory)\Entitlements.plist</CodesignEntitlements>

<DefineConstants Condition="'$(Configuration)' == 'Debug'">$(DefineConstants);DEBUG</DefineConstants>

Expand Down
Loading