| File: SudoEnvironmentDirectoryOverride.cs | Web Access |
| Project: src\sdk\src\Cli\dotnet\dotnet.csproj (dotnet) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable using System.CommandLine; using Microsoft.DotNet.Cli.Commands.Workload; using Microsoft.DotNet.Cli.Extensions; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Configurer; using Microsoft.DotNet.InternalAbstractions; using NuGet.Common; using NuGet.Configuration; namespace Microsoft.DotNet.Cli; /// <summary> /// https://github.com/dotnet/sdk/issues/20195 /// </summary> public static class SudoEnvironmentDirectoryOverride { /// <summary> /// Not for security use. Detect if command is running under sudo /// via if SUDO_UID being set. /// </summary> public static bool IsRunningUnderSudo() { if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("SUDO_UID"))) { return true; } return false; } public static void OverrideEnvironmentVariableToTmp(ParseResult parseResult) { if (!OperatingSystem.IsWindows() && IsRunningUnderSudo() && IsRunningWorkloadCommand(parseResult)) { string sudoHome = TemporaryDirectory.CreateSubdirectory(); var homeBeforeOverride = Environment.GetEnvironmentVariable(CliFolderPathCalculator.DotnetHomeVariableName); Environment.SetEnvironmentVariable(CliFolderPathCalculator.DotnetHomeVariableName, sudoHome); if (homeBeforeOverride is not null) { CopyUserNuGetConfigToOverriddenHome(homeBeforeOverride); } } } /// <summary> /// To make NuGet honor the user's NuGet config file. /// Copying instead of using the file directly to avoid existing file being set higher permission /// Try to delete the existing NuGet config file in "/tmp/dotnet_sudo_home/" /// to avoid different user's NuGet config getting mixed. /// </summary> private static void CopyUserNuGetConfigToOverriddenHome(string homeBeforeOverride) { // https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Common/PathUtil/NuGetEnvironment.cs#L139 // home is cache in NuGet we cannot directly use the call var userSettingsDir = Path.Combine(homeBeforeOverride, ".nuget", "NuGet"); string userNuGetConfig = Settings.OrderedSettingsFileNames .Select(fileName => Path.Combine(userSettingsDir, fileName)) .FirstOrDefault(f => File.Exists(f)); var overriddenSettingsDir = NuGetEnvironment.GetFolderPath(NuGetFolderPath.UserSettingsDirectory); var overriddenNugetConfig = Path.Combine(overriddenSettingsDir, Settings.DefaultSettingsFileName); if (File.Exists(overriddenNugetConfig)) { try { FileAccessRetrier.RetryOnIOException( () => File.Delete(overriddenNugetConfig)); } catch { // best effort to remove } } if (userNuGetConfig != default) { try { FileAccessRetrier.RetryOnIOException( () => File.Copy(userNuGetConfig, overriddenNugetConfig, overwrite: true)); } catch { // best effort to copy } } } private static bool IsRunningWorkloadCommand(ParseResult parseResult) => parseResult.RootSubCommandResult() == WorkloadCommandDefinition.Name; }