From 725ac09a3411bc90b59491f0e1e725cd897c55b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Tue, 2 Jul 2024 07:07:05 +0200 Subject: [PATCH] Update the application discriminator and instance identifier generation logic to produce shorter pipe names --- .../OpenIddict.Sandbox.WinForms.Client.csproj | 2 +- .../OpenIddict.Sandbox.Wpf.Client.csproj | 2 +- ...ictClientSystemIntegrationConfiguration.cs | 76 +++++++++---------- ...IddictClientSystemIntegrationExtensions.cs | 13 +++- 4 files changed, 45 insertions(+), 48 deletions(-) diff --git a/sandbox/OpenIddict.Sandbox.WinForms.Client/OpenIddict.Sandbox.WinForms.Client.csproj b/sandbox/OpenIddict.Sandbox.WinForms.Client/OpenIddict.Sandbox.WinForms.Client.csproj index 44719f06..2c943f59 100644 --- a/sandbox/OpenIddict.Sandbox.WinForms.Client/OpenIddict.Sandbox.WinForms.Client.csproj +++ b/sandbox/OpenIddict.Sandbox.WinForms.Client/OpenIddict.Sandbox.WinForms.Client.csproj @@ -3,7 +3,7 @@ WinExe net48 - $(TargetFrameworks);net8.0-windows7.0 + $(TargetFrameworks);net8.0-windows7.0 true diff --git a/sandbox/OpenIddict.Sandbox.Wpf.Client/OpenIddict.Sandbox.Wpf.Client.csproj b/sandbox/OpenIddict.Sandbox.Wpf.Client/OpenIddict.Sandbox.Wpf.Client.csproj index 6eed25c1..0a00897f 100644 --- a/sandbox/OpenIddict.Sandbox.Wpf.Client/OpenIddict.Sandbox.Wpf.Client.csproj +++ b/sandbox/OpenIddict.Sandbox.Wpf.Client/OpenIddict.Sandbox.Wpf.Client.csproj @@ -3,7 +3,7 @@ WinExe net48 - $(TargetFrameworks);net8.0-windows10.0.17763 + $(TargetFrameworks);net8.0-windows10.0.17763 true false diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs index 98b58713..dfa22e74 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs @@ -83,11 +83,16 @@ public sealed class OpenIddictClientSystemIntegrationConfiguration : IConfigureO throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0389)); } -#if !SUPPORTS_APPKIT && !SUPPORTS_UIKIT +#if !SUPPORTS_APPKIT // When running on iOS, Mac Catalyst or macOS, ensure the version compiled for these platforms is used. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) || - RuntimeInformation.IsOSPlatform(OSPlatform.Create("maccatalyst")) || - RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0449)); + } +#endif +#if !SUPPORTS_UIKIT + if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("maccatalyst"))) { throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0449)); } @@ -138,34 +143,29 @@ public sealed class OpenIddictClientSystemIntegrationConfiguration : IConfigureO throw new InvalidOperationException(SR.GetResourceString(SR.ID0386)); } - options.ApplicationDiscriminator = Base64UrlEncoder.Encode( - OpenIddictHelpers.ComputeSha256Hash( - Encoding.UTF8.GetBytes(_environment.ApplicationName))); + var digest = OpenIddictHelpers.ComputeSha256Hash(Encoding.UTF8.GetBytes(_environment.ApplicationName)); + + // Note: only the left-most half of the hash is used to limit the length of the resulting discriminator, + // which is required on platforms like macOS, where the name of pipes is always prefixed with a static part + // (e.g /var/folders/5j/jjxtct5j1gvg35z6sdh2fz0w0000gn/T/CoreFxPipe_) and must not exceed 104 characters. + options.ApplicationDiscriminator = Base64UrlEncoder.Encode(digest, 0, digest.Length / 2); } - // If no explicit instance identifier was specified, use a random GUID. + // If no explicit instance identifier was specified, use a 96-bit random identifier. if (string.IsNullOrEmpty(options.InstanceIdentifier)) { - options.InstanceIdentifier = Guid.NewGuid().ToString(); + options.InstanceIdentifier = Base64UrlEncoder.Encode(OpenIddictHelpers.CreateRandomArray(size: 96)); } // If no explicit pipe name was specified, build one using the application discriminator. if (string.IsNullOrEmpty(options.PipeName)) { - var builder = new StringBuilder(); - // Note: on Windows, the name is deliberately prefixed with "LOCAL\" to support // partial trust/sandboxed applications that are executed in an AppContainer // and cannot communicate with applications outside the sandbox container. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - builder.Append(@"LOCAL\"); - } - - options.PipeName = builder.Append("OpenIddict.Client.SystemIntegration") - .Append('-') - .Append(options.ApplicationDiscriminator) - .ToString(); + options.PipeName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? + @$"LOCAL\{options.ApplicationDiscriminator}" : + options.ApplicationDiscriminator; } #if SUPPORTS_CURRENT_USER_ONLY_PIPE_OPTION @@ -183,31 +183,23 @@ public sealed class OpenIddictClientSystemIntegrationConfiguration : IConfigureO // even if the flag was not explicitly set by the user. options.PipeOptions |= PipeOptions.Asynchronous; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + // On Windows, if no explicit pipe security policy was specified, grant the current + // user full control over the created pipe and allow cross-process communication + // between elevated and non-elevated processes. Note: if the process executes + // inside an AppContainer, don't override the default OS pipe security policy + // to allow all applications with the same identity to access the named pipe. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && options.PipeSecurity is null) { - // If no explicit pipe security policy was specified, grant the current user - // full control over the created pipe and allow cross-process communication - // between elevated and non-elevated processes. Note: if the process executes - // inside an AppContainer, don't override the default OS pipe security policy - // to allow all applications with the same identity to access the named pipe. - if (options.PipeSecurity is null) + using var identity = WindowsIdentity.GetCurrent(TokenAccessLevels.Query); + + if (!OpenIddictClientSystemIntegrationHelpers.IsWindowsVersionAtLeast(10, 0, 10240) || + !OpenIddictClientSystemIntegrationHelpers.HasAppContainerToken(identity)) { - using var identity = WindowsIdentity.GetCurrent(TokenAccessLevels.Query); - - if (!IsRunningInAppContainer(identity)) - { - options.PipeSecurity = new PipeSecurity(); - options.PipeSecurity.SetOwner(identity.User!); - options.PipeSecurity.AddAccessRule(new PipeAccessRule(identity.User!, - PipeAccessRights.FullControl, AccessControlType.Allow)); - } + options.PipeSecurity = new PipeSecurity(); + options.PipeSecurity.SetOwner(identity.User!); + options.PipeSecurity.AddAccessRule(new PipeAccessRule(identity.User!, + PipeAccessRights.FullControl, AccessControlType.Allow)); } - - [MethodImpl(MethodImplOptions.NoInlining)] - [SupportedOSPlatform("windows")] - static bool IsRunningInAppContainer(WindowsIdentity identity) - => OpenIddictClientSystemIntegrationHelpers.IsWindowsVersionAtLeast(10, 0, 10240) && - OpenIddictClientSystemIntegrationHelpers.HasAppContainerToken(identity); } } } diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs index 08c3f45f..af20f33d 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs @@ -40,11 +40,16 @@ public static class OpenIddictClientSystemIntegrationExtensions throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0389)); } -#if !SUPPORTS_APPKIT && !SUPPORTS_UIKIT +#if !SUPPORTS_APPKIT // When running on iOS, Mac Catalyst or macOS, ensure the version compiled for these platforms is used. - if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) || - RuntimeInformation.IsOSPlatform(OSPlatform.Create("maccatalyst")) || - RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0449)); + } +#endif +#if !SUPPORTS_UIKIT + if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) || + RuntimeInformation.IsOSPlatform(OSPlatform.Create("maccatalyst"))) { throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0449)); }