Skip to content

Commit

Permalink
AzureArcManagedIdentitySource fix
Browse files Browse the repository at this point in the history
  • Loading branch information
christothes committed Jun 10, 2024
1 parent 06dd672 commit 2db9a0f
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 6 deletions.
8 changes: 4 additions & 4 deletions eng/Packages.Data.props
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,13 @@
<!-- Other approved packages -->
<PackageReference Update="Microsoft.Azure.Amqp" Version="2.6.5" />
<PackageReference Update="Microsoft.Azure.WebPubSub.Common" Version="1.2.0" />
<PackageReference Update="Microsoft.Identity.Client" Version="4.60.3" />
<PackageReference Update="Microsoft.Identity.Client.Extensions.Msal" Version="4.60.3" />
<PackageReference Update="Microsoft.Identity.Client" Version="4.61.3" />
<PackageReference Update="Microsoft.Identity.Client.Extensions.Msal" Version="4.61.3" />
<!--
TODO: This package needs to be released as GA and arch-board approved before taking a dependency in any stable SDK library.
Currently, it is referencd by Azure.Identity.Broker which is still in beta
-->
<PackageReference Update="Microsoft.Identity.Client.Broker" Version="4.60.3" />
<PackageReference Update="Microsoft.Identity.Client.Broker" Version="4.61.3" />

<!-- TODO: Make sure this package is arch-board approved -->
<PackageReference Update="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="6.35.0" />
Expand Down Expand Up @@ -379,7 +379,7 @@
<PackageReference Update="Microsoft.Extensions.Http" Version="2.1.1" />
<PackageReference Update="Microsoft.Extensions.Logging.Configuration" Version="2.1.1" />
</ItemGroup>

<PropertyGroup>
<TestProxyVersion>1.0.0-dev.20240410.2</TestProxyVersion>
</PropertyGroup>
Expand Down
5 changes: 5 additions & 0 deletions sdk/identity/Azure.Identity/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Release History

## 1.11.4 (2024-06-11)

### Bugs Fixed
- Managed identity bug fixes

## 1.11.3 (2024-05-07)

### Bugs Fixed
Expand Down
4 changes: 2 additions & 2 deletions sdk/identity/Azure.Identity/src/Azure.Identity.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<PropertyGroup>
<Description>This is the implementation of the Azure SDK Client Library for Azure Identity</Description>
<AssemblyTitle>Microsoft Azure.Identity Component</AssemblyTitle>
<Version>1.11.3</Version>
<Version>1.11.4</Version>
<!--The ApiCompatVersion is managed automatically and should not generally be modified manually.-->
<ApiCompatVersion>1.11.2</ApiCompatVersion>
<ApiCompatVersion>1.11.3</ApiCompatVersion>
<PackageTags>Microsoft Azure Identity;$(PackageCommonTags)</PackageTags>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
<NoWarn>$(NoWarn);3021;AZC0011</NoWarn>
Expand Down
37 changes: 37 additions & 0 deletions sdk/identity/Azure.Identity/src/AzureArcManagedIdentitySource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ protected override async ValueTask<AccessToken> HandleResponseAsync(bool async,
{
throw new AuthenticationFailedException(InvalidChallangeErrorMessage);
}
string filePath = splitChallenge[1];

ValidatePath(filePath);
var authHeaderValue = "Basic " + File.ReadAllText(splitChallenge[1]);

using Request request = CreateRequest(context.Scopes);
Expand All @@ -112,5 +114,40 @@ protected override async ValueTask<AccessToken> HandleResponseAsync(bool async,

return await base.HandleResponseAsync(async, context, message, cancellationToken).ConfigureAwait(false);
}

private void ValidatePath(string filePath)
{
// check that the file ends with '.key'
if (!filePath.EndsWith(".key"))
{
throw new AuthenticationFailedException("The secret key file failed validation. File name is invalid.");
}
// if the current platform is windows check that the file is in the path %ProgramData%\AzureConnectedMachineAgent\Tokens
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
var programData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
var expectedPath = Path.Combine(programData, "AzureConnectedMachineAgent", "Tokens");
if (!filePath.StartsWith(expectedPath))
{
throw new AuthenticationFailedException("The secret key file failed validation. File path is invalid.");
}
}

// if the current platform is linux check that the file is in the path /var/opt/azcmagent/tokens
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
var expectedPath = Path.Combine("/", "var", "opt", "azcmagent", "tokens");
if (!filePath.StartsWith(expectedPath))
{
throw new AuthenticationFailedException("The secret key file failed validation. File path is invalid.");
}
}

// Check that the file length is no larger than 4096 bytes
if (new FileInfo(filePath).Length > 4096)
{
throw new AuthenticationFailedException("The secret key file failed validation. File is too large.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public ManagedIdentityCredentialArcLiveTests(bool isAsync) : base(isAsync)

[NonParallelizable]
[Test]
[LiveOnly(Reason = "path validation fails in playback mode")]
public async Task ValidateSystemAssignedIdentity()
{
if (string.IsNullOrEmpty(TestEnvironment.ArcEnable))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,80 @@ public async Task VerifyAuthenticationFailedExceptionsAreDeferredToGetToken(Dict
await Task.CompletedTask;
}

[Test]
public void VerifyArcIdentitySourceFilePathValidation_DoesNotEndInDotKey()
{
using var environment = new TestEnvVar(
new()
{
{ "MSI_ENDPOINT", null },
{ "MSI_SECRET", null },
{ "IDENTITY_ENDPOINT", "https://identity.constoso.com" },
{ "IMDS_ENDPOINT", "https://imds.constoso.com" },
{ "IDENTITY_HEADER", null },
{ "AZURE_POD_IDENTITY_AUTHORITY_HOST", null }
});

var mockTransport = new MockTransport(request =>
{
var response = new MockResponse(401);
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
response.AddHeader("WWW-Authenticate", "file=c:\\ProgramData\\AzureConnectedMachineAgent\\Tokens\\secret.foo");
}
else
{
response.AddHeader("WWW-Authenticate", "file=/var/opt/azcmagent/tokens/secret.foo");
}
return response;
});
var options = new TokenCredentialOptions() { Transport = mockTransport };
options.Retry.MaxDelay = TimeSpan.Zero;
var pipeline = CredentialPipeline.GetInstance(options);

ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential(null, pipeline));

var ex = Assert.ThrowsAsync<AuthenticationFailedException>(async () => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));
Assert.That(ex.Message, Does.Contain("File name is invalid."));
}

[Test]
public void VerifyArcIdentitySourceFilePathValidation_FilePathInvalid()
{
using var environment = new TestEnvVar(
new()
{
{ "MSI_ENDPOINT", null },
{ "MSI_SECRET", null },
{ "IDENTITY_ENDPOINT", "https://identity.constoso.com" },
{ "IMDS_ENDPOINT", "https://imds.constoso.com" },
{ "IDENTITY_HEADER", null },
{ "AZURE_POD_IDENTITY_AUTHORITY_HOST", null }
});

var mockTransport = new MockTransport(request =>
{
var response = new MockResponse(401);
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
response.AddHeader("WWW-Authenticate", "file=c:\\ProgramData\\bugus\\AzureConnectedMachineAgent\\Tokens\\secret.key");
}
else
{
response.AddHeader("WWW-Authenticate", "file=/var/opt/bogus/azcmagent/tokens/secret.key");
}
return response;
});
var options = new TokenCredentialOptions() { Transport = mockTransport };
options.Retry.MaxDelay = TimeSpan.Zero;
var pipeline = CredentialPipeline.GetInstance(options);

ManagedIdentityCredential credential = InstrumentClient(new ManagedIdentityCredential(null, pipeline));

var ex = Assert.ThrowsAsync<AuthenticationFailedException>(async () => await credential.GetTokenAsync(new TokenRequestContext(MockScopes.Default)));
Assert.That(ex.Message, Does.Contain("File path is invalid."));
}

private static IEnumerable<TestCaseData> ResourceAndClientIds()
{
yield return new TestCaseData(new object[] { null, false });
Expand Down

0 comments on commit 2db9a0f

Please sign in to comment.