dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.64k stars 1.05k forks source link

Permission Denied or Access Denied when running a global dotnet tool #41947

Open diegosasw opened 1 month ago

diegosasw commented 1 month ago

Describe the bug

(Some) dotnet tools installed as global cannot be used due to an Access Denied in cmd or Bash: /c/Users/MyUser/.dotnet/tools/coderiff: Permission denied in Git Bash.

This problem is not happening with other dotnet tools such as dotnet-ef

To Reproduce

View this sample public repository that generates a dotnet tool and publishes it in nuget.org: https://github.com/coderiff-tech/coderiff-toolkit/tree/46e63a7e95aeed0e42154b90ddaa726e105efa54

The sample has been created following instructions at https://learn.microsoft.com/en-us/dotnet/core/tools/global-tools-how-to-create

Install the sample dotnet tool globally, which should be available as it's in nuget.org

C:\ dotnet tool install -g Coderiff.Cli
You can invoke the tool using the following command: coderiff
Tool 'coderiff.cli' (version '0.1.9') was successfully installed.

Try to run the tool

C:\ coderiff
Access is denied.

Try to run it with GitBash

$ coderiff
bash: /c/Users/MyUser/.dotnet/tools/coderiff: Permission denied

Now, if I attempt to install another tool, such as dotnet-ef, I don't experience the same problem. Is the above tool missing something which is causing this problem with dotnet CLI?

C:\ dotnet tool install -g dotnet-ef
You can invoke the tool using the following command: dotnet-ef
Tool 'dotnet-ef' (version '8.0.6') was successfully installed.

And no errors when running

C:\ dotnet-ef
Entity Framework Core .NET Command-line Tools 8.0.6

Further technical details

C:\ dotnet --version
8.0.302

in Windows 11.

diegosasw commented 1 month ago

After reinstalling the very same .NET SDK it seems to have fixed the issue with that specific tool.

I thought the problem was fixed and closed the issue, but it's not. The issue remains and I suspect it has something to do with NuGet authentication.

diegosasw commented 1 month ago

I reproduced the error again. It seems to happen with NuGet packages stored in GitHub packages.

My understanding is that, even though my repo is public and the packages are set as public, there is authentication required in the NuGet organization feed (is this correct?), and therefore any dotnet tool hosted as a NuGet package in GitHub requires authentication, even if it's public (strange, but I tested without credentials and got coderiff.cli is not found in NuGet feeds https://api.nuget.org/v3/index.json, https://nuget.pkg.github.com/coderiff-tech/index.json").

This is the repo: https://github.com/coderiff-tech/coderiff-toolkit/tree/46e63a7e95aeed0e42154b90ddaa726e105efa54

I have created a Personal Access Token with a classic token with packages:read scope which can be used to authenticate in the NuGet feed.

So the problem can be reproduced if you go to any directory, and then you add a NuGet.Config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="github" value="https://nuget.pkg.github.com/coderiff-tech/index.json" />
  </packageSources>
  <packageSourceCredentials>
    <github>
        <add key="Username" value="pat-coderiff-packages-read" />
        <add key="ClearTextPassword" value="ghp_***" />
    </github>
  </packageSourceCredentials>
</configuration>

Now the tool can be installed globally

> dotnet tool install -g Coderiff.Cli
You can invoke the tool using the following command: coderiff
Tool 'coderiff.cli' (version '0.1.9') was successfully installed.

and when trying to run it

> coderiff
Access is denied.

To summarize: NuGet dotnet tools from package repositories which need authentication can be installed globally but can't be executed due to Access is denied error.

KalleOlaviNiemitalo commented 1 month ago

Is the Personal Access Token still valid? GitHub Registry claims that the package does not exist, and I get the same response even if use "none" as the username and password. Might GitHub have automatically revoked the token because you posted it here?

$ dotnet tool install -g Coderiff.Cli --configfile NuGet.Config
Unhandled exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at NuGet.Protocol.HttpSource.<>c__DisplayClass15_0`1.<<GetAsync>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at NuGet.Common.ConcurrencyUtilities.ExecuteWithFileLockedAsync[T](String filePath, Func`2 action, CancellationToken token)
   at NuGet.Common.ConcurrencyUtilities.ExecuteWithFileLockedAsync[T](String filePath, Func`2 action, CancellationToken token)
   at NuGet.Protocol.HttpSource.GetAsync[T](HttpSourceCachedRequest request, Func`2 processAsync, ILogger log, CancellationToken token)
   at NuGet.Protocol.PackageMetadataResourceV3.LoadRegistrationIndexAsync(HttpSource httpSource, Uri registrationUri, String packageId, SourceCacheContext cacheContext, Func`2 processAsync, ILogger log, CancellationToken token)
   at NuGet.Protocol.PackageMetadataResourceV3.GetMetadataAsync(String packageId, Boolean includePrerelease, Boolean includeUnlisted, VersionRange range, SourceCacheContext sourceCacheContext, ILogger log, CancellationToken token)
   at NuGet.Protocol.PackageMetadataResourceV3.GetMetadataAsync(String packageId, Boolean includePrerelease, Boolean includeUnlisted, SourceCacheContext sourceCacheContext, ILogger log, CancellationToken token)
   at Microsoft.DotNet.Cli.NuGetPackageDownloader.NuGetPackageDownloader.GetPackageMetadataAsync(PackageSource source, String packageIdentifier, Boolean includePrerelease, Boolean includeUnlisted, CancellationToken cancellationToken)
   at Microsoft.DotNet.Cli.NuGetPackageDownloader.NuGetPackageDownloader.GetMatchingVersionInternalAsync(String packageIdentifier, IEnumerable`1 packageSources, VersionRange versionRange, CancellationToken cancellationToken)
   at Microsoft.DotNet.Cli.NuGetPackageDownloader.NuGetPackageDownloader.GetBestPackageVersionAsync(PackageId packageId, VersionRange versionRange, PackageSourceLocation packageSourceLocation)
   at Microsoft.DotNet.Cli.ToolPackage.ToolPackageDownloader.<>c__DisplayClass8_0.<InstallPackage>b__0()
   at Microsoft.DotNet.Cli.TransactionalAction.Run[T](Func`1 action, Action commit, Action rollback)
   at Microsoft.DotNet.Tools.Tool.Install.ToolInstallGlobalOrToolPathCommand.<>c__DisplayClass20_0.<Execute>b__1()
   at Microsoft.DotNet.Tools.Tool.Install.ToolInstallGlobalOrToolPathCommand.RunWithHandlingInstallError(Action installAction)
   at Microsoft.DotNet.Tools.Tool.Install.ToolInstallGlobalOrToolPathCommand.Execute()
   at System.CommandLine.Invocation.InvocationPipeline.Invoke(ParseResult parseResult)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, TimeSpan startupTime, ITelemetry telemetryClient)
$ curl --silent --include --basic --user pat-coderiff-packages-read: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 https://nuget.pkg.github.com/coderiff-tech/coderiff.toolkit/index.json
HTTP/1.1 404 Not Found
access-control-allow-methods: GET, OPTIONS
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'none';
Content-Type: application/json; charset=utf-8
Server: GitHub Registry
Strict-Transport-Security: max-age=31536000;
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Date: Wed, 03 Jul 2024 17:18:22 GMT
Content-Length: 138
X-GitHub-Request-Id: ECA6:91D63:DC8DF7:E25150:668587DE

{"errors":[{"code":"NAME_UNKNOWN","message":"Package with name 'coderiff.toolkit' was not found in the package source 'coderiff-tech'"}]}
$ curl --silent --include --basic --user none:none https://nuget.pkg.github.com/coderiff-tech/coderiff.toolkit/index.json
HTTP/1.1 404 Not Found
access-control-allow-methods: GET, OPTIONS
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'none';
Content-Type: application/json; charset=utf-8
Server: GitHub Registry
Strict-Transport-Security: max-age=31536000;
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Date: Wed, 03 Jul 2024 17:19:16 GMT
Content-Length: 138
X-GitHub-Request-Id: ECA9:19A221:C7D4FB:CD9923:66858814

{"errors":[{"code":"NAME_UNKNOWN","message":"Package with name 'coderiff.toolkit' was not found in the package source 'coderiff-tech'"}]}
$ curl --silent --include   https://nuget.pkg.github.com/coderiff-tech/coderiff.toolkit/index.json
HTTP/1.1 401 Unauthorized
access-control-allow-methods: GET, OPTIONS
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'none';
Server: GitHub Registry
Strict-Transport-Security: max-age=31536000;
www-authenticate: Basic realm="GitHub Package Registry"
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
x-nuget-warning: No Authorization header detected
X-XSS-Protection: 1; mode=block
Date: Wed, 03 Jul 2024 17:22:09 GMT
Content-Length: 0
X-GitHub-Request-Id: ECAF:70528:DEB4BE:E47926:668588C1
diegosasw commented 1 month ago

Might GitHub have automatically revoked the token because you posted it here?

Correct. It seems so. As soon as the token is revealed here it's revoked (great security, but I'll avoid doing that :) )

You could try this token if all the values are joined (sorry for the trick, I don't want it to be revoked)

username: pat-41947-packages-read
value1of3: ghp_
value2of3: JRbfiIKbJBF2hdnlse
value3of3: C4Wgcn0DBIZl0O9kB4

I've just tested it again with the updated NuGet.Config

C:\Git\coderiff\coderiff-toolkit>dotnet tool install -g Coderiff.Cli
You can invoke the tool using the following command: coderiff
Tool 'coderiff.cli' (version '0.1.9') was successfully installed.

C:\Git\coderiff\coderiff-toolkit>coderiff
Access is denied.

Also, please notice I've renamed the package (not the repo) to Coderiff.Cli and updated my previous comments.

> curl --silent --include --basic --user pat-41947-packages-read:ghp_JR**********C4**** https://nuget.
pkg.github.com/coderiff-tech/coderiff.cli/index.json

HTTP/1.1 200 OK
KalleOlaviNiemitalo commented 1 month ago
C:\Users\WDAGUtilityAccount>coderiff
coderiff v0.1.9+46e63a7e95aeed0e42154b90ddaa726e105efa54
-------------

Usage:
  coderiff <command>

I suggest you use Process Monitor to find exactly which access is denied in your environment.