From 744d8dbb959f60ed6fbdf4937d2627c5802ba22d Mon Sep 17 00:00:00 2001 From: Thomas Boop Date: Mon, 2 Dec 2019 08:41:01 -0500 Subject: [PATCH] Add Proxy Support for self-hosted runner. --- src/Misc/layoutroot/env.sh | 3 - src/Runner.Common/Constants.cs | 7 - src/Runner.Common/HostContext.cs | 66 ++- src/Runner.Common/RunnerWebProxy.cs | 196 --------- src/Runner.Listener/Agent.cs | 3 +- src/Runner.Listener/CommandSettings.cs | 18 - .../Configuration/ConfigurationManager.cs | 26 -- .../Repository/v1.0/GitSourceProvider.cs | 50 +-- .../Repository/v1.1/GitSourceProvider.cs | 42 +- src/Runner.Sdk/ActionPlugin.cs | 47 +- src/Runner.Sdk/RunnerWebProxy.cs | 224 ++++++++++ src/Runner.Sdk/RunnerWebProxyCore.cs | 104 ----- src/Runner.Worker/ExecutionContext.cs | 23 - src/Runner.Worker/JobExtension.cs | 9 +- src/Runner.Worker/Worker.cs | 3 +- src/Test/L0/HostContextL0.cs | 29 ++ .../Configuration/ConfigurationManagerL0.cs | 5 - src/Test/L0/ProxyConfigL0.cs | 116 ----- src/Test/L0/RunnerWebProxyL0.cs | 416 ++++++++++++++++++ src/Test/L0/TestHostContext.cs | 20 +- src/Test/L0/Worker/ActionManagerL0.cs | 4 - src/Test/L0/Worker/ExecutionContextL0.cs | 4 - src/Test/L0/Worker/JobRunnerL0.cs | 6 - src/Test/L0/Worker/WorkerL0.cs | 4 - 24 files changed, 743 insertions(+), 682 deletions(-) delete mode 100644 src/Runner.Common/RunnerWebProxy.cs create mode 100644 src/Runner.Sdk/RunnerWebProxy.cs delete mode 100644 src/Runner.Sdk/RunnerWebProxyCore.cs delete mode 100644 src/Test/L0/ProxyConfigL0.cs create mode 100644 src/Test/L0/RunnerWebProxyL0.cs diff --git a/src/Misc/layoutroot/env.sh b/src/Misc/layoutroot/env.sh index 9aaf2bf5176..cfe1a2cafc1 100755 --- a/src/Misc/layoutroot/env.sh +++ b/src/Misc/layoutroot/env.sh @@ -9,9 +9,6 @@ varCheckList=( 'GRADLE_HOME' 'NVM_BIN' 'NVM_PATH' - 'VSTS_HTTP_PROXY' - 'VSTS_HTTP_PROXY_USERNAME' - 'VSTS_HTTP_PROXY_PASSWORD' 'LD_LIBRARY_PATH' 'PERL5LIB' ) diff --git a/src/Runner.Common/Constants.cs b/src/Runner.Common/Constants.cs index 4e4bb661d6a..72e364e1c67 100644 --- a/src/Runner.Common/Constants.cs +++ b/src/Runner.Common/Constants.cs @@ -29,9 +29,6 @@ public enum WellKnownConfigFile Service, CredentialStore, Certificates, - Proxy, - ProxyCredentials, - ProxyBypass, Options, } @@ -97,8 +94,6 @@ public static class Args public static readonly string Auth = "auth"; public static readonly string MonitorSocketAddress = "monitorsocketaddress"; public static readonly string Pool = "pool"; - public static readonly string ProxyUrl = "proxyurl"; - public static readonly string ProxyUserName = "proxyusername"; public static readonly string SslCACert = "sslcacert"; public static readonly string SslClientCert = "sslclientcert"; public static readonly string SslClientCertKey = "sslclientcertkey"; @@ -111,14 +106,12 @@ public static class Args // Secret args. Must be added to the "Secrets" getter as well. public static readonly string Password = "password"; - public static readonly string ProxyPassword = "proxypassword"; public static readonly string SslClientCertPassword = "sslclientcertpassword"; public static readonly string Token = "token"; public static readonly string WindowsLogonPassword = "windowslogonpassword"; public static string[] Secrets => new[] { Password, - ProxyPassword, SslClientCertPassword, Token, WindowsLogonPassword, diff --git a/src/Runner.Common/HostContext.cs b/src/Runner.Common/HostContext.cs index 376299d3488..f49932adc23 100644 --- a/src/Runner.Common/HostContext.cs +++ b/src/Runner.Common/HostContext.cs @@ -26,6 +26,7 @@ public interface IHostContext : IDisposable ShutdownReason RunnerShutdownReason { get; } ISecretMasker SecretMasker { get; } ProductInfoHeaderValue UserAgent { get; } + RunnerWebProxy WebProxy { get; } string GetDirectory(WellKnownDirectory directory); string GetConfigFile(WellKnownConfigFile configFile); Tracing GetTrace(string name); @@ -67,12 +68,14 @@ public sealed class HostContext : EventListener, IObserver, private IDisposable _diagListenerSubscription; private StartupType _startupType; private string _perfFile; + private RunnerWebProxy _webProxy = new RunnerWebProxy(); public event EventHandler Unloading; public CancellationToken RunnerShutdownToken => _runnerShutdownTokenSource.Token; public ShutdownReason RunnerShutdownReason { get; private set; } public ISecretMasker SecretMasker => _secretMasker; public ProductInfoHeaderValue UserAgent => _userAgent; + public RunnerWebProxy WebProxy => _webProxy; public HostContext(string hostType, string logFile = null) { // Validate args. @@ -147,6 +150,48 @@ public HostContext(string hostType, string logFile = null) _trace.Error(ex); } } + + // Check and trace proxy info + if (!string.IsNullOrEmpty(WebProxy.HttpProxyAddress)) + { + if (string.IsNullOrEmpty(WebProxy.HttpProxyUsername) && string.IsNullOrEmpty(WebProxy.HttpProxyPassword)) + { + _trace.Info($"Configuring anonymous proxy {WebProxy.HttpProxyAddress} for all HTTP requests."); + } + else + { + // Register proxy password as secret + if (!string.IsNullOrEmpty(WebProxy.HttpProxyPassword)) + { + this.SecretMasker.AddValue(WebProxy.HttpProxyPassword); + } + + _trace.Info($"Configuring authenticated proxy {WebProxy.HttpProxyAddress} for all HTTP requests."); + } + } + + if (!string.IsNullOrEmpty(WebProxy.HttpsProxyAddress)) + { + if (string.IsNullOrEmpty(WebProxy.HttpsProxyUsername) && string.IsNullOrEmpty(WebProxy.HttpsProxyPassword)) + { + _trace.Info($"Configuring anonymous proxy {WebProxy.HttpsProxyAddress} for all HTTPS requests."); + } + else + { + // Register proxy password as secret + if (!string.IsNullOrEmpty(WebProxy.HttpsProxyPassword)) + { + this.SecretMasker.AddValue(WebProxy.HttpsProxyPassword); + } + + _trace.Info($"Configuring authenticated proxy {WebProxy.HttpsProxyAddress} for all HTTPS requests."); + } + } + + if (string.IsNullOrEmpty(WebProxy.HttpProxyAddress) && string.IsNullOrEmpty(WebProxy.HttpsProxyAddress)) + { + _trace.Info($"No proxy settings were found based on environmental variables (http_proxy/https_proxy/HTTP_PROXY/HTTPS_PROXY)"); + } } public RunMode RunMode @@ -282,24 +327,6 @@ public string GetConfigFile(WellKnownConfigFile configFile) ".certificates"); break; - case WellKnownConfigFile.Proxy: - path = Path.Combine( - GetDirectory(WellKnownDirectory.Root), - ".proxy"); - break; - - case WellKnownConfigFile.ProxyCredentials: - path = Path.Combine( - GetDirectory(WellKnownDirectory.Root), - ".proxycredentials"); - break; - - case WellKnownConfigFile.ProxyBypass: - path = Path.Combine( - GetDirectory(WellKnownDirectory.Root), - ".proxybypass"); - break; - case WellKnownConfigFile.Options: path = Path.Combine( GetDirectory(WellKnownDirectory.Root), @@ -580,8 +607,7 @@ public static class HostContextExtension public static HttpClientHandler CreateHttpClientHandler(this IHostContext context) { HttpClientHandler clientHandler = new HttpClientHandler(); - var runnerWebProxy = context.GetService(); - clientHandler.Proxy = runnerWebProxy.WebProxy; + clientHandler.Proxy = context.WebProxy; return clientHandler; } } diff --git a/src/Runner.Common/RunnerWebProxy.cs b/src/Runner.Common/RunnerWebProxy.cs deleted file mode 100644 index ecb12fe1fba..00000000000 --- a/src/Runner.Common/RunnerWebProxy.cs +++ /dev/null @@ -1,196 +0,0 @@ -using GitHub.Runner.Common.Util; -using System; -using System.Linq; -using System.Net; -using System.IO; -using System.Collections.Generic; -using System.Text.RegularExpressions; -using GitHub.Runner.Sdk; - -namespace GitHub.Runner.Common -{ - [ServiceLocator(Default = typeof(RunnerWebProxy))] - public interface IRunnerWebProxy : IRunnerService - { - string ProxyAddress { get; } - string ProxyUsername { get; } - string ProxyPassword { get; } - List ProxyBypassList { get; } - IWebProxy WebProxy { get; } - } - - public class RunnerWebProxy : RunnerService, IRunnerWebProxy - { - private readonly List _regExBypassList = new List(); - private readonly List _bypassList = new List(); - private RunnerWebProxyCore _runnerWebProxy = new RunnerWebProxyCore(); - - public string ProxyAddress { get; private set; } - public string ProxyUsername { get; private set; } - public string ProxyPassword { get; private set; } - public List ProxyBypassList => _bypassList; - public IWebProxy WebProxy => _runnerWebProxy; - - public override void Initialize(IHostContext context) - { - base.Initialize(context); - LoadProxySetting(); - } - - // This should only be called from config - public void SetupProxy(string proxyAddress, string proxyUsername, string proxyPassword) - { - ArgUtil.NotNullOrEmpty(proxyAddress, nameof(proxyAddress)); - Trace.Info($"Update proxy setting from '{ProxyAddress ?? string.Empty}' to'{proxyAddress}'"); - ProxyAddress = proxyAddress; - ProxyUsername = proxyUsername; - ProxyPassword = proxyPassword; - - if (string.IsNullOrEmpty(ProxyUsername) || string.IsNullOrEmpty(ProxyPassword)) - { - Trace.Info($"Config proxy use DefaultNetworkCredentials."); - } - else - { - Trace.Info($"Config authentication proxy as: {ProxyUsername}."); - } - - _runnerWebProxy.Update(ProxyAddress, ProxyUsername, ProxyPassword, ProxyBypassList); - } - - // This should only be called from config - public void SaveProxySetting() - { - if (!string.IsNullOrEmpty(ProxyAddress)) - { - string proxyConfigFile = HostContext.GetConfigFile(WellKnownConfigFile.Proxy); - IOUtil.DeleteFile(proxyConfigFile); - Trace.Info($"Store proxy configuration to '{proxyConfigFile}' for proxy '{ProxyAddress}'"); - File.WriteAllText(proxyConfigFile, ProxyAddress); - File.SetAttributes(proxyConfigFile, File.GetAttributes(proxyConfigFile) | FileAttributes.Hidden); - - string proxyCredFile = HostContext.GetConfigFile(WellKnownConfigFile.ProxyCredentials); - IOUtil.DeleteFile(proxyCredFile); - if (!string.IsNullOrEmpty(ProxyUsername) && !string.IsNullOrEmpty(ProxyPassword)) - { - string lookupKey = Guid.NewGuid().ToString("D").ToUpperInvariant(); - Trace.Info($"Store proxy credential lookup key '{lookupKey}' to '{proxyCredFile}'"); - File.WriteAllText(proxyCredFile, lookupKey); - File.SetAttributes(proxyCredFile, File.GetAttributes(proxyCredFile) | FileAttributes.Hidden); - - var credStore = HostContext.GetService(); - credStore.Write($"GITHUB_ACTIONS_RUNNER_PROXY_{lookupKey}", ProxyUsername, ProxyPassword); - } - } - else - { - Trace.Info("No proxy configuration exist."); - } - } - - // This should only be called from unconfig - public void DeleteProxySetting() - { - string proxyCredFile = HostContext.GetConfigFile(WellKnownConfigFile.ProxyCredentials); - if (File.Exists(proxyCredFile)) - { - Trace.Info("Delete proxy credential from credential store."); - string lookupKey = File.ReadAllLines(proxyCredFile).FirstOrDefault(); - if (!string.IsNullOrEmpty(lookupKey)) - { - var credStore = HostContext.GetService(); - credStore.Delete($"GITHUB_ACTIONS_RUNNER_PROXY_{lookupKey}"); - } - - Trace.Info($"Delete .proxycredentials file: {proxyCredFile}"); - IOUtil.DeleteFile(proxyCredFile); - } - - string proxyBypassFile = HostContext.GetConfigFile(WellKnownConfigFile.ProxyBypass); - if (File.Exists(proxyBypassFile)) - { - Trace.Info($"Delete .proxybypass file: {proxyBypassFile}"); - IOUtil.DeleteFile(proxyBypassFile); - } - - string proxyConfigFile = HostContext.GetConfigFile(WellKnownConfigFile.Proxy); - Trace.Info($"Delete .proxy file: {proxyConfigFile}"); - IOUtil.DeleteFile(proxyConfigFile); - } - - private void LoadProxySetting() - { - string proxyConfigFile = HostContext.GetConfigFile(WellKnownConfigFile.Proxy); - if (File.Exists(proxyConfigFile)) - { - // we expect the first line of the file is the proxy url - Trace.Verbose($"Try read proxy setting from file: {proxyConfigFile}."); - ProxyAddress = File.ReadLines(proxyConfigFile).FirstOrDefault() ?? string.Empty; - ProxyAddress = ProxyAddress.Trim(); - Trace.Verbose($"{ProxyAddress}"); - } - - if (!string.IsNullOrEmpty(ProxyAddress) && !Uri.IsWellFormedUriString(ProxyAddress, UriKind.Absolute)) - { - Trace.Info($"The proxy url is not a well formed absolute uri string: {ProxyAddress}."); - ProxyAddress = string.Empty; - } - - if (!string.IsNullOrEmpty(ProxyAddress)) - { - Trace.Info($"Config proxy at: {ProxyAddress}."); - - string proxyCredFile = HostContext.GetConfigFile(WellKnownConfigFile.ProxyCredentials); - if (File.Exists(proxyCredFile)) - { - string lookupKey = File.ReadAllLines(proxyCredFile).FirstOrDefault(); - if (!string.IsNullOrEmpty(lookupKey)) - { - var credStore = HostContext.GetService(); - var proxyCred = credStore.Read($"GITHUB_ACTIONS_RUNNER_PROXY_{lookupKey}"); - ProxyUsername = proxyCred.UserName; - ProxyPassword = proxyCred.Password; - } - } - - if (!string.IsNullOrEmpty(ProxyPassword)) - { - HostContext.SecretMasker.AddValue(ProxyPassword); - } - - if (string.IsNullOrEmpty(ProxyUsername) || string.IsNullOrEmpty(ProxyPassword)) - { - Trace.Info($"Config proxy use DefaultNetworkCredentials."); - } - else - { - Trace.Info($"Config authentication proxy as: {ProxyUsername}."); - } - - string proxyBypassFile = HostContext.GetConfigFile(WellKnownConfigFile.ProxyBypass); - if (File.Exists(proxyBypassFile)) - { - Trace.Verbose($"Try read proxy bypass list from file: {proxyBypassFile}."); - foreach (string bypass in File.ReadAllLines(proxyBypassFile)) - { - if (string.IsNullOrWhiteSpace(bypass)) - { - continue; - } - else - { - Trace.Info($"Bypass proxy for: {bypass}."); - ProxyBypassList.Add(bypass.Trim()); - } - } - } - - _runnerWebProxy.Update(ProxyAddress, ProxyUsername, ProxyPassword, ProxyBypassList); - } - else - { - Trace.Info($"No proxy setting found."); - } - } - } -} diff --git a/src/Runner.Listener/Agent.cs b/src/Runner.Listener/Agent.cs index 3d2eba35bd1..b55b192ff19 100644 --- a/src/Runner.Listener/Agent.cs +++ b/src/Runner.Listener/Agent.cs @@ -37,9 +37,8 @@ public async Task ExecuteCommand(CommandSettings command) { try { - var runnerWebProxy = HostContext.GetService(); var runnerCertManager = HostContext.GetService(); - VssUtil.InitializeVssClientSettings(HostContext.UserAgent, runnerWebProxy.WebProxy, runnerCertManager.VssClientCertificateManager); + VssUtil.InitializeVssClientSettings(HostContext.UserAgent, HostContext.WebProxy, runnerCertManager.VssClientCertificateManager); _inConfigStage = true; _completedCommand.Reset(); diff --git a/src/Runner.Listener/CommandSettings.cs b/src/Runner.Listener/CommandSettings.cs index 2c5e3f555eb..2104d973780 100644 --- a/src/Runner.Listener/CommandSettings.cs +++ b/src/Runner.Listener/CommandSettings.cs @@ -47,9 +47,6 @@ public sealed class CommandSettings Constants.Runner.CommandLine.Args.MonitorSocketAddress, Constants.Runner.CommandLine.Args.Password, Constants.Runner.CommandLine.Args.Pool, - Constants.Runner.CommandLine.Args.ProxyPassword, - Constants.Runner.CommandLine.Args.ProxyUrl, - Constants.Runner.CommandLine.Args.ProxyUserName, Constants.Runner.CommandLine.Args.SslCACert, Constants.Runner.CommandLine.Args.SslClientCert, Constants.Runner.CommandLine.Args.SslClientCertKey, @@ -290,21 +287,6 @@ public string GetStartupType() return GetArg(Constants.Runner.CommandLine.Args.StartupType); } - public string GetProxyUrl() - { - return GetArg(Constants.Runner.CommandLine.Args.ProxyUrl); - } - - public string GetProxyUserName() - { - return GetArg(Constants.Runner.CommandLine.Args.ProxyUserName); - } - - public string GetProxyPassword() - { - return GetArg(Constants.Runner.CommandLine.Args.ProxyPassword); - } - public bool GetSkipCertificateValidation() { return TestFlag(Constants.Runner.CommandLine.Flags.SslSkipCertValidation); diff --git a/src/Runner.Listener/Configuration/ConfigurationManager.cs b/src/Runner.Listener/Configuration/ConfigurationManager.cs index 5b25a65b76d..d533b0dc355 100644 --- a/src/Runner.Listener/Configuration/ConfigurationManager.cs +++ b/src/Runner.Listener/Configuration/ConfigurationManager.cs @@ -86,24 +86,6 @@ public async Task ConfigureAsync(CommandSettings command) throw new InvalidOperationException("Cannot configure the runner because it is already configured. To reconfigure the runner, run 'config.cmd remove' or './config.sh remove' first."); } - // Populate proxy setting from commandline args - var runnerProxy = HostContext.GetService(); - bool saveProxySetting = false; - string proxyUrl = command.GetProxyUrl(); - if (!string.IsNullOrEmpty(proxyUrl)) - { - if (!Uri.IsWellFormedUriString(proxyUrl, UriKind.Absolute)) - { - throw new ArgumentOutOfRangeException(nameof(proxyUrl)); - } - - Trace.Info("Reset proxy base on commandline args."); - string proxyUserName = command.GetProxyUserName(); - string proxyPassword = command.GetProxyPassword(); - (runnerProxy as RunnerWebProxy).SetupProxy(proxyUrl, proxyUserName, proxyPassword); - saveProxySetting = true; - } - // Populate cert setting from commandline args var runnerCertManager = HostContext.GetService(); bool saveCertSetting = false; @@ -371,12 +353,6 @@ public async Task ConfigureAsync(CommandSettings command) _store.SaveSettings(runnerSettings); - if (saveProxySetting) - { - Trace.Info("Save proxy setting to disk."); - (runnerProxy as RunnerWebProxy).SaveProxySetting(); - } - if (saveCertSetting) { Trace.Info("Save agent cert setting to disk."); @@ -515,8 +491,6 @@ public async Task UnconfigureAsync(CommandSettings command) currentAction = "Removing .runner"; if (isConfigured) { - // delete proxy setting - (HostContext.GetService() as RunnerWebProxy).DeleteProxySetting(); // delete agent cert setting (HostContext.GetService() as RunnerCertificateManager).DeleteCertificateSetting(); diff --git a/src/Runner.Plugins/Repository/v1.0/GitSourceProvider.cs b/src/Runner.Plugins/Repository/v1.0/GitSourceProvider.cs index ed7ba9f29f7..57f30a629cb 100644 --- a/src/Runner.Plugins/Repository/v1.0/GitSourceProvider.cs +++ b/src/Runner.Plugins/Repository/v1.0/GitSourceProvider.cs @@ -79,8 +79,6 @@ public async Task GetSourceAsync( { // Validate args. ArgUtil.NotNull(executionContext, nameof(executionContext)); - Uri proxyUrlWithCred = null; - string proxyUrlWithCredString = null; bool useSelfSignedCACert = false; bool useClientCert = false; string clientCertPrivateKeyAskPassFile = null; @@ -164,25 +162,6 @@ public async Task GetSourceAsync( // 3. git version greater than 2.14.2 if use SChannel for SSL backend (Windows only) RequirementCheck(executionContext, gitCommandManager, gitLfsSupport); - // prepare credentail embedded urls - var runnerProxy = executionContext.GetProxyConfiguration(); - if (runnerProxy != null && !string.IsNullOrEmpty(runnerProxy.ProxyAddress) && !runnerProxy.WebProxy.IsBypassed(repositoryUrl)) - { - proxyUrlWithCred = UrlUtil.GetCredentialEmbeddedUrl(new Uri(runnerProxy.ProxyAddress), runnerProxy.ProxyUsername, runnerProxy.ProxyPassword); - - // uri.absoluteuri will not contains port info if the scheme is http/https and the port is 80/443 - // however, git.exe always require you provide port info, if nothing passed in, it will use 1080 as default - // as result, we need prefer the uri.originalstring when it's different than uri.absoluteuri. - if (string.Equals(proxyUrlWithCred.AbsoluteUri, proxyUrlWithCred.OriginalString, StringComparison.OrdinalIgnoreCase)) - { - proxyUrlWithCredString = proxyUrlWithCred.AbsoluteUri; - } - else - { - proxyUrlWithCredString = proxyUrlWithCred.OriginalString; - } - } - // prepare askpass for client cert private key, if the repository's endpoint url match the runner config url var systemConnection = executionContext.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase)); if (runnerCert != null && Uri.Compare(repositoryUrl, systemConnection.Url, UriComponents.SchemeAndServer, UriFormat.Unescaped, StringComparison.OrdinalIgnoreCase) == 0) @@ -373,13 +352,6 @@ public async Task GetSourceAsync( await RemoveGitConfig(executionContext, gitCommandManager, targetPath, $"http.{repositoryUrl.AbsoluteUri}.extraheader", string.Empty); } - // always remove any possible left proxy setting from git config, the proxy setting may contains credential - if (await gitCommandManager.GitConfigExist(executionContext, targetPath, $"http.proxy")) - { - executionContext.Debug("Remove any proxy setting from git config."); - await RemoveGitConfig(executionContext, gitCommandManager, targetPath, $"http.proxy", string.Empty); - } - List additionalFetchArgs = new List(); List additionalLfsFetchArgs = new List(); @@ -389,15 +361,6 @@ public async Task GetSourceAsync( additionalFetchArgs.Add($"-c http.extraheader=\"AUTHORIZATION: {GenerateBasicAuthHeader(executionContext, accessToken)}\""); } - // Prepare proxy config for fetch. - if (runnerProxy != null && !string.IsNullOrEmpty(runnerProxy.ProxyAddress) && !runnerProxy.WebProxy.IsBypassed(repositoryUrl)) - { - executionContext.Debug($"Config proxy server '{runnerProxy.ProxyAddress}' for git fetch."); - ArgUtil.NotNullOrEmpty(proxyUrlWithCredString, nameof(proxyUrlWithCredString)); - additionalFetchArgs.Add($"-c http.proxy=\"{proxyUrlWithCredString}\""); - additionalLfsFetchArgs.Add($"-c http.proxy=\"{proxyUrlWithCredString}\""); - } - // Prepare ignore ssl cert error config for fetch. if (acceptUntrustedCerts) { @@ -539,14 +502,6 @@ public async Task GetSourceAsync( additionalSubmoduleUpdateArgs.Add($"-c http.{authorityUrl}.extraheader=\"AUTHORIZATION: {GenerateBasicAuthHeader(executionContext, accessToken)}\""); } - // Prepare proxy config for submodule update. - if (runnerProxy != null && !string.IsNullOrEmpty(runnerProxy.ProxyAddress) && !runnerProxy.WebProxy.IsBypassed(repositoryUrl)) - { - executionContext.Debug($"Config proxy server '{runnerProxy.ProxyAddress}' for git submodule update."); - ArgUtil.NotNullOrEmpty(proxyUrlWithCredString, nameof(proxyUrlWithCredString)); - additionalSubmoduleUpdateArgs.Add($"-c http.proxy=\"{proxyUrlWithCredString}\""); - } - // Prepare ignore ssl cert error config for fetch. if (acceptUntrustedCerts) { @@ -637,7 +592,7 @@ private async Task RemoveGitConfig(RunnerActionPluginExecutionContext executionC int exitCode_configUnset = await gitCommandManager.GitConfigUnset(executionContext, targetPath, configKey); if (exitCode_configUnset != 0) { - // if unable to use git.exe unset http.extraheader, http.proxy or core.askpass, modify git config file on disk. make sure we don't left credential. + // if unable to use git.exe unset http.extraheader or core.askpass, modify git config file on disk. make sure we don't left credential. if (!string.IsNullOrEmpty(configValue)) { executionContext.Warning("An unsuccessful attempt was made using git command line to remove \"http.extraheader\" from the git config. Attempting to modify the git config file directly to remove the credential."); @@ -650,9 +605,6 @@ private async Task RemoveGitConfig(RunnerActionPluginExecutionContext executionC string setting = $"extraheader = {configValue}"; gitConfigContent = Regex.Replace(gitConfigContent, setting, string.Empty, RegexOptions.IgnoreCase); - setting = $"proxy = {configValue}"; - gitConfigContent = Regex.Replace(gitConfigContent, setting, string.Empty, RegexOptions.IgnoreCase); - setting = $"askpass = {configValue}"; gitConfigContent = Regex.Replace(gitConfigContent, setting, string.Empty, RegexOptions.IgnoreCase); diff --git a/src/Runner.Plugins/Repository/v1.1/GitSourceProvider.cs b/src/Runner.Plugins/Repository/v1.1/GitSourceProvider.cs index 09492bcda9d..4858b067972 100644 --- a/src/Runner.Plugins/Repository/v1.1/GitSourceProvider.cs +++ b/src/Runner.Plugins/Repository/v1.1/GitSourceProvider.cs @@ -65,8 +65,6 @@ public async Task GetSourceAsync( // Validate args. ArgUtil.NotNull(executionContext, nameof(executionContext)); Dictionary configModifications = new Dictionary(); - Uri proxyUrlWithCred = null; - string proxyUrlWithCredString = null; bool useSelfSignedCACert = false; bool useClientCert = false; string clientCertPrivateKeyAskPassFile = null; @@ -153,18 +151,6 @@ public async Task GetSourceAsync( // 3. git version greater than 2.14.2 if use SChannel for SSL backend (Windows only) RequirementCheck(executionContext, gitCommandManager, gitLfsSupport); - // prepare credentail embedded urls - var runnerProxy = executionContext.GetProxyConfiguration(); - if (runnerProxy != null && !string.IsNullOrEmpty(runnerProxy.ProxyAddress) && !runnerProxy.WebProxy.IsBypassed(repositoryUrl)) - { - proxyUrlWithCred = UrlUtil.GetCredentialEmbeddedUrl(new Uri(runnerProxy.ProxyAddress), runnerProxy.ProxyUsername, runnerProxy.ProxyPassword); - - // uri.absoluteuri will not contains port info if the scheme is http/https and the port is 80/443 - // however, git.exe always require you provide port info, if nothing passed in, it will use 1080 as default - // as result, we need prefer the uri.originalstring over uri.absoluteuri. - proxyUrlWithCredString = proxyUrlWithCred.OriginalString; - } - // prepare askpass for client cert private key, if the repository's endpoint url match the runner config url var systemConnection = executionContext.Endpoints.Single(x => string.Equals(x.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase)); if (runnerCert != null && Uri.Compare(repositoryUrl, systemConnection.Url, UriComponents.SchemeAndServer, UriFormat.Unescaped, StringComparison.OrdinalIgnoreCase) == 0) @@ -355,13 +341,6 @@ public async Task GetSourceAsync( await RemoveGitConfig(executionContext, gitCommandManager, targetPath, $"http.{repositoryUrl.AbsoluteUri}.extraheader", string.Empty); } - // always remove any possible left proxy setting from git config, the proxy setting may contains credential - if (await gitCommandManager.GitConfigExist(executionContext, targetPath, $"http.proxy")) - { - executionContext.Debug("Remove any proxy setting from git config."); - await RemoveGitConfig(executionContext, gitCommandManager, targetPath, $"http.proxy", string.Empty); - } - List additionalFetchArgs = new List(); List additionalLfsFetchArgs = new List(); @@ -376,15 +355,6 @@ public async Task GetSourceAsync( throw new InvalidOperationException($"Git config failed with exit code: {exitCode_config}"); } - // Prepare proxy config for fetch. - if (runnerProxy != null && !string.IsNullOrEmpty(runnerProxy.ProxyAddress) && !runnerProxy.WebProxy.IsBypassed(repositoryUrl)) - { - executionContext.Debug($"Config proxy server '{runnerProxy.ProxyAddress}' for git fetch."); - ArgUtil.NotNullOrEmpty(proxyUrlWithCredString, nameof(proxyUrlWithCredString)); - additionalFetchArgs.Add($"-c http.proxy=\"{proxyUrlWithCredString}\""); - additionalLfsFetchArgs.Add($"-c http.proxy=\"{proxyUrlWithCredString}\""); - } - // Prepare ignore ssl cert error config for fetch. if (acceptUntrustedCerts) { @@ -514,14 +484,6 @@ public async Task GetSourceAsync( List additionalSubmoduleUpdateArgs = new List(); - // Prepare proxy config for submodule update. - if (runnerProxy != null && !string.IsNullOrEmpty(runnerProxy.ProxyAddress) && !runnerProxy.WebProxy.IsBypassed(repositoryUrl)) - { - executionContext.Debug($"Config proxy server '{runnerProxy.ProxyAddress}' for git submodule update."); - ArgUtil.NotNullOrEmpty(proxyUrlWithCredString, nameof(proxyUrlWithCredString)); - additionalSubmoduleUpdateArgs.Add($"-c http.proxy=\"{proxyUrlWithCredString}\""); - } - // Prepare ignore ssl cert error config for fetch. if (acceptUntrustedCerts) { @@ -592,7 +554,7 @@ public async Task CleanupAsync(RunnerActionPluginExecutionContext executionConte GitCliManager gitCommandManager = new GitCliManager(); await gitCommandManager.LoadGitExecutionInfo(executionContext); - executionContext.Debug("Remove any extraheader and proxy setting from git config."); + executionContext.Debug("Remove any extraheader setting from git config."); var configKeys = JsonUtility.FromString>(Environment.GetEnvironmentVariable("STATE_modifiedgitconfig")); if (configKeys?.Count > 0) { @@ -677,7 +639,7 @@ private async Task RemoveGitConfig(RunnerActionPluginExecutionContext executionC int exitCode_configUnset = await gitCommandManager.GitConfigUnset(executionContext, targetPath, configKey); if (exitCode_configUnset != 0) { - // if unable to use git.exe unset http.extraheader, http.proxy or core.askpass, modify git config file on disk. make sure we don't left credential. + // if unable to use git.exe unset http.extraheader or core.askpass, modify git config file on disk. make sure we don't left credential. if (!string.IsNullOrEmpty(configValue)) { executionContext.Warning("An unsuccessful attempt was made using git command line to remove \"http.extraheader\" from the git config. Attempting to modify the git config file directly to remove the credential."); diff --git a/src/Runner.Sdk/ActionPlugin.cs b/src/Runner.Sdk/ActionPlugin.cs index 232f89cc7dc..d29f644ac50 100644 --- a/src/Runner.Sdk/ActionPlugin.cs +++ b/src/Runner.Sdk/ActionPlugin.cs @@ -24,6 +24,7 @@ public class RunnerActionPluginExecutionContext : ITraceWriter { private readonly string DebugEnvironmentalVariable = "ACTIONS_STEP_DEBUG"; private VssConnection _connection; + private RunnerWebProxy _webProxy; private readonly object _stdoutLock = new object(); private readonly ITraceWriter _trace; // for unit tests @@ -57,6 +58,19 @@ public VssConnection VssConnection } } + [JsonIgnore] + public RunnerWebProxy WebProxy + { + get + { + if (_webProxy == null) + { + _webProxy = new RunnerWebProxy(); + } + return _webProxy; + } + } + public VssConnection InitializeVssConnection() { var headerValues = new List(); @@ -84,15 +98,7 @@ public VssConnection InitializeVssConnection() } } - var proxySetting = GetProxyConfiguration(); - if (proxySetting != null) - { - if (!string.IsNullOrEmpty(proxySetting.ProxyAddress)) - { - VssHttpMessageHandler.DefaultWebProxy = new RunnerWebProxyCore(proxySetting.ProxyAddress, proxySetting.ProxyUsername, proxySetting.ProxyPassword, proxySetting.ProxyBypassList); - } - } - + VssHttpMessageHandler.DefaultWebProxy = this.WebProxy; ServiceEndpoint systemConnection = this.Endpoints.FirstOrDefault(e => string.Equals(e.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase)); ArgUtil.NotNull(systemConnection, nameof(systemConnection)); ArgUtil.NotNull(systemConnection.Url, nameof(systemConnection.Url)); @@ -255,29 +261,6 @@ public RunnerCertificateSettings GetCertConfiguration() } } - public RunnerWebProxySettings GetProxyConfiguration() - { - string proxyUrl = GetRunnerContext("ProxyUrl"); - if (!string.IsNullOrEmpty(proxyUrl)) - { - string proxyUsername = GetRunnerContext("ProxyUsername"); - string proxyPassword = GetRunnerContext("ProxyPassword"); - List proxyBypassHosts = StringUtil.ConvertFromJson>(GetRunnerContext("ProxyBypassList") ?? "[]"); - return new RunnerWebProxySettings() - { - ProxyAddress = proxyUrl, - ProxyUsername = proxyUsername, - ProxyPassword = proxyPassword, - ProxyBypassList = proxyBypassHosts, - WebProxy = new RunnerWebProxyCore(proxyUrl, proxyUsername, proxyPassword, proxyBypassHosts) - }; - } - else - { - return null; - } - } - private string Escape(string input) { foreach (var mapping in _commandEscapeMappings) diff --git a/src/Runner.Sdk/RunnerWebProxy.cs b/src/Runner.Sdk/RunnerWebProxy.cs new file mode 100644 index 00000000000..71d9d1e6c0d --- /dev/null +++ b/src/Runner.Sdk/RunnerWebProxy.cs @@ -0,0 +1,224 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text.RegularExpressions; + +namespace GitHub.Runner.Sdk +{ + public struct ByPassInfo + { + public string Host { get; set; } + + public string Port { get; set; } + }; + + public class RunnerWebProxy : IWebProxy + { + private string _httpProxyAddress; + private string _httpProxyUsername; + private string _httpProxyPassword; + + private string _httpsProxyAddress; + private string _httpsProxyUsername; + private string _httpsProxyPassword; + + private readonly List _noProxyList = new List(); + private readonly HashSet _noProxyUnique = new HashSet(StringComparer.OrdinalIgnoreCase); + private readonly Regex _validIpRegex = new Regex("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$", RegexOptions.Compiled); + + public string HttpProxyAddress => _httpProxyAddress; + public string HttpProxyUsername => _httpProxyUsername; + public string HttpProxyPassword => _httpProxyPassword; + + public string HttpsProxyAddress => _httpsProxyAddress; + public string HttpsProxyUsername => _httpsProxyUsername; + public string HttpsProxyPassword => _httpsProxyPassword; + + public List NoProxyList => _noProxyList; + + public ICredentials Credentials { get; set; } + + public RunnerWebProxy() + { + Credentials = new CredentialCache(); + + var httpProxyAddress = Environment.GetEnvironmentVariable("http_proxy"); + if (string.IsNullOrEmpty(httpProxyAddress)) + { + httpProxyAddress = Environment.GetEnvironmentVariable("HTTP_PROXY"); + } + httpProxyAddress = httpProxyAddress?.Trim(); + + var httpsProxyAddress = Environment.GetEnvironmentVariable("https_proxy"); + if (string.IsNullOrEmpty(httpsProxyAddress)) + { + httpsProxyAddress = Environment.GetEnvironmentVariable("HTTPS_PROXY"); + } + httpsProxyAddress = httpsProxyAddress?.Trim(); + + var noProxyList = Environment.GetEnvironmentVariable("no_proxy"); + if (string.IsNullOrEmpty(noProxyList)) + { + noProxyList = Environment.GetEnvironmentVariable("NO_PROXY"); + } + + if (string.IsNullOrEmpty(httpProxyAddress) && string.IsNullOrEmpty(httpsProxyAddress)) + { + return; + } + + if (!string.IsNullOrEmpty(httpProxyAddress) && Uri.TryCreate(httpProxyAddress, UriKind.Absolute, out var proxyHttpUri)) + { + _httpProxyAddress = proxyHttpUri.AbsoluteUri; + + // the proxy url looks like http://[user:pass@]127.0.0.1:8888 + var userInfo = Uri.UnescapeDataString(proxyHttpUri.UserInfo).Split(':', 2, StringSplitOptions.RemoveEmptyEntries); + if (userInfo.Length == 2) + { + _httpProxyUsername = userInfo[0]; + _httpProxyPassword = userInfo[1]; + } + else if (userInfo.Length == 1) + { + _httpProxyUsername = userInfo[0]; + } + + if (!string.IsNullOrEmpty(_httpProxyUsername) || !string.IsNullOrEmpty(_httpProxyPassword)) + { + var credentials = new NetworkCredential(_httpProxyUsername, _httpProxyPassword); + + // Replace the entry in the credential cache if it exists + (Credentials as CredentialCache).Remove(proxyHttpUri, "Basic"); + (Credentials as CredentialCache).Add(proxyHttpUri, "Basic", credentials); + } + } + + if (!string.IsNullOrEmpty(httpsProxyAddress) && Uri.TryCreate(httpsProxyAddress, UriKind.Absolute, out var proxyHttpsUri)) + { + _httpsProxyAddress = proxyHttpsUri.AbsoluteUri; + + // the proxy url looks like http://[user:pass@]127.0.0.1:8888 + var userInfo = Uri.UnescapeDataString(proxyHttpsUri.UserInfo).Split(':', 2, StringSplitOptions.RemoveEmptyEntries); + if (userInfo.Length == 2) + { + _httpsProxyUsername = userInfo[0]; + _httpsProxyPassword = userInfo[1]; + } + else if (userInfo.Length == 1) + { + _httpsProxyUsername = userInfo[0]; + } + + if (!string.IsNullOrEmpty(_httpsProxyUsername) || !string.IsNullOrEmpty(_httpsProxyPassword)) + { + var credentials = new NetworkCredential(_httpsProxyUsername, _httpsProxyPassword); + + // Replace the entry in the credential cache if it exists + (Credentials as CredentialCache).Remove(proxyHttpsUri, "Basic"); + (Credentials as CredentialCache).Add(proxyHttpsUri, "Basic", credentials); + } + } + + if (!string.IsNullOrEmpty(noProxyList)) + { + var noProxyListSplit = noProxyList.Split(',', StringSplitOptions.RemoveEmptyEntries); + foreach (string noProxy in noProxyListSplit) + { + var noProxyTrim = noProxy.Trim(); + if (string.IsNullOrEmpty(noProxyTrim)) + { + continue; + } + else if (_noProxyUnique.Add(noProxyTrim)) + { + var noProxyInfo = new ByPassInfo(); + var noProxyHostPort = noProxyTrim.Split(':', 2, StringSplitOptions.RemoveEmptyEntries); + if (noProxyHostPort.Length == 1) + { + noProxyInfo.Host = noProxyHostPort[0]; + } + else if (noProxyHostPort.Length == 2) + { + noProxyInfo.Host = noProxyHostPort[0]; + noProxyInfo.Port = noProxyHostPort[1]; + } + + // We don't support IP address for no_proxy + if (_validIpRegex.IsMatch(noProxyInfo.Host)) + { + continue; + } + + _noProxyList.Add(noProxyInfo); + } + } + } + } + + public Uri GetProxy(Uri destination) + { + if (IsBypassed(destination)) + { + return null; + } + + if (destination.Scheme == Uri.UriSchemeHttps) + { + return new Uri(_httpsProxyAddress); + } + else + { + return new Uri(_httpProxyAddress); + } + } + + public bool IsBypassed(Uri uri) + { + if (uri.Scheme == Uri.UriSchemeHttps && string.IsNullOrEmpty(_httpsProxyAddress)) + { + return true; + } + + if (uri.Scheme == Uri.UriSchemeHttp && string.IsNullOrEmpty(_httpProxyAddress)) + { + return true; + } + + return uri.IsLoopback || IsUriInBypassList(uri); + } + + private bool IsUriInBypassList(Uri input) + { + foreach (var noProxy in _noProxyList) + { + var matchHost = false; + var matchPort = false; + + if (string.IsNullOrEmpty(noProxy.Port)) + { + matchPort = true; + } + else + { + matchPort = string.Equals(noProxy.Port, input.Port.ToString()); + } + + if (noProxy.Host.StartsWith('.')) + { + matchHost = input.Host.EndsWith(noProxy.Host, StringComparison.OrdinalIgnoreCase); + } + else + { + matchHost = string.Equals(input.Host, noProxy.Host, StringComparison.OrdinalIgnoreCase) || input.Host.EndsWith($".{noProxy.Host}", StringComparison.OrdinalIgnoreCase); + } + + if (matchHost && matchPort) + { + return true; + } + } + + return false; + } + } +} diff --git a/src/Runner.Sdk/RunnerWebProxyCore.cs b/src/Runner.Sdk/RunnerWebProxyCore.cs deleted file mode 100644 index e1fcc729cfa..00000000000 --- a/src/Runner.Sdk/RunnerWebProxyCore.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Text.RegularExpressions; - -namespace GitHub.Runner.Sdk -{ - public class RunnerWebProxySettings - { - public string ProxyAddress { get; set; } - public string ProxyUsername { get; set; } - public string ProxyPassword { get; set; } - public List ProxyBypassList { get; set; } - public IWebProxy WebProxy { get; set; } - } - - public class RunnerWebProxyCore : IWebProxy - { - private string _proxyAddress; - private readonly List _regExBypassList = new List(); - - public ICredentials Credentials { get; set; } - - public RunnerWebProxyCore() - { - } - - public RunnerWebProxyCore(string proxyAddress, string proxyUsername, string proxyPassword, List proxyBypassList) - { - Update(proxyAddress, proxyUsername, proxyPassword, proxyBypassList); - } - - public void Update(string proxyAddress, string proxyUsername, string proxyPassword, List proxyBypassList) - { - _proxyAddress = proxyAddress?.Trim(); - - if (string.IsNullOrEmpty(proxyUsername) || string.IsNullOrEmpty(proxyPassword)) - { - Credentials = CredentialCache.DefaultNetworkCredentials; - } - else - { - Credentials = new NetworkCredential(proxyUsername, proxyPassword); - } - - if (proxyBypassList != null) - { - foreach (string bypass in proxyBypassList) - { - if (string.IsNullOrWhiteSpace(bypass)) - { - continue; - } - else - { - try - { - Regex bypassRegex = new Regex(bypass.Trim(), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.ECMAScript); - _regExBypassList.Add(bypassRegex); - } - catch (Exception) - { - // eat all exceptions - } - } - } - } - } - - public Uri GetProxy(Uri destination) - { - if (IsBypassed(destination)) - { - return destination; - } - else - { - return new Uri(_proxyAddress); - } - } - - public bool IsBypassed(Uri uri) - { - return string.IsNullOrEmpty(_proxyAddress) || uri.IsLoopback || IsMatchInBypassList(uri); - } - - private bool IsMatchInBypassList(Uri input) - { - string matchUriString = input.IsDefaultPort ? - input.Scheme + "://" + input.Host : - input.Scheme + "://" + input.Host + ":" + input.Port.ToString(); - - foreach (Regex r in _regExBypassList) - { - if (r.IsMatch(matchUriString)) - { - return true; - } - } - - return false; - } - } -} diff --git a/src/Runner.Worker/ExecutionContext.cs b/src/Runner.Worker/ExecutionContext.cs index 090a8a7a64b..23e6ad8fa50 100644 --- a/src/Runner.Worker/ExecutionContext.cs +++ b/src/Runner.Worker/ExecutionContext.cs @@ -616,29 +616,6 @@ public void InitializeJob(Pipelines.AgentJobRequestMessage message, Cancellation // PostJobSteps for job ExecutionContext PostJobSteps = new Stack(); - // Proxy variables - // var agentWebProxy = HostContext.GetService(); - // if (!string.IsNullOrEmpty(agentWebProxy.ProxyAddress)) - // { - // SetRunnerContext("proxyurl", agentWebProxy.ProxyAddress); - - // if (!string.IsNullOrEmpty(agentWebProxy.ProxyUsername)) - // { - // SetRunnerContext("proxyusername", agentWebProxy.ProxyUsername); - // } - - // if (!string.IsNullOrEmpty(agentWebProxy.ProxyPassword)) - // { - // HostContext.SecretMasker.AddValue(agentWebProxy.ProxyPassword); - // SetRunnerContext("proxypassword", agentWebProxy.ProxyPassword); - // } - - // if (agentWebProxy.ProxyBypassList.Count > 0) - // { - // SetRunnerContext("proxybypasslist", JsonUtility.ToString(agentWebProxy.ProxyBypassList)); - // } - // } - // // Certificate variables // var agentCert = HostContext.GetService(); // if (agentCert.SkipServerCertificateValidation) diff --git a/src/Runner.Worker/JobExtension.cs b/src/Runner.Worker/JobExtension.cs index 2e7f857e7e5..0dfeac73605 100644 --- a/src/Runner.Worker/JobExtension.cs +++ b/src/Runner.Worker/JobExtension.cs @@ -55,10 +55,13 @@ public async Task> InitializeJob(IExecutionContext jobContext, Pipel context.Debug($"Primary repository: {repoFullName}"); // Print proxy setting information for better diagnostic experience - var runnerWebProxy = HostContext.GetService(); - if (!string.IsNullOrEmpty(runnerWebProxy.ProxyAddress)) + if (!string.IsNullOrEmpty(HostContext.WebProxy.HttpProxyAddress)) { - context.Output($"Runner is running behind proxy server: '{runnerWebProxy.ProxyAddress}'"); + context.Output($"Runner is running behind proxy server '{HostContext.WebProxy.HttpProxyAddress}' for all HTTP requests."); + } + if (!string.IsNullOrEmpty(HostContext.WebProxy.HttpsProxyAddress)) + { + context.Output($"Runner is running behind proxy server '{HostContext.WebProxy.HttpsProxyAddress}' for all HTTPS requests."); } // Prepare the workflow directory diff --git a/src/Runner.Worker/Worker.cs b/src/Runner.Worker/Worker.cs index 26d1a895aa6..bb57b4fdcae 100644 --- a/src/Runner.Worker/Worker.cs +++ b/src/Runner.Worker/Worker.cs @@ -40,9 +40,8 @@ public async Task RunAsync(string pipeIn, string pipeOut) // Validate args. ArgUtil.NotNullOrEmpty(pipeIn, nameof(pipeIn)); ArgUtil.NotNullOrEmpty(pipeOut, nameof(pipeOut)); - var runnerWebProxy = HostContext.GetService(); var runnerCertManager = HostContext.GetService(); - VssUtil.InitializeVssClientSettings(HostContext.UserAgent, runnerWebProxy.WebProxy, runnerCertManager.VssClientCertificateManager); + VssUtil.InitializeVssClientSettings(HostContext.UserAgent, HostContext.WebProxy, runnerCertManager.VssClientCertificateManager); var jobRunner = HostContext.CreateService(); using (var channel = HostContext.CreateService()) diff --git a/src/Test/L0/HostContextL0.cs b/src/Test/L0/HostContextL0.cs index 93bcff38b0c..4b5bbf6d172 100644 --- a/src/Test/L0/HostContextL0.cs +++ b/src/Test/L0/HostContextL0.cs @@ -107,6 +107,35 @@ public void DefaultSecretMaskers() } } + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void SecretMaskerForProxy() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://user:password123@127.0.0.1:8888"); + + // Arrange. + Setup(); + + // Assert. + var logFile = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), $"trace_{nameof(HostContextL0)}_{nameof(SecretMaskerForProxy)}.log"); + var tempFile = Path.GetTempFileName(); + File.Delete(tempFile); + File.Copy(logFile, tempFile); + var content = File.ReadAllText(tempFile); + Assert.DoesNotContain("password123", content); + Assert.Contains("http://user:***@127.0.0.1:8888", content); + } + finally + { + Environment.SetEnvironmentVariable("http_proxy", null); + // Cleanup. + Teardown(); + } + } + private void Setup([CallerMemberName] string testName = "") { _tokenSource = new CancellationTokenSource(); diff --git a/src/Test/L0/Listener/Configuration/ConfigurationManagerL0.cs b/src/Test/L0/Listener/Configuration/ConfigurationManagerL0.cs index c538ea4f679..0f4c55c720e 100644 --- a/src/Test/L0/Listener/Configuration/ConfigurationManagerL0.cs +++ b/src/Test/L0/Listener/Configuration/ConfigurationManagerL0.cs @@ -26,8 +26,6 @@ public class ConfigurationManagerL0 private Mock _promptManager; private Mock _store; private Mock _extnMgr; - // private Mock _machineGroupServer; - private Mock _runnerWebProxy; private Mock _cert; #if OS_WINDOWS @@ -59,8 +57,6 @@ public ConfigurationManagerL0() _store = new Mock(); _extnMgr = new Mock(); _rsaKeyManager = new Mock(); - // _machineGroupServer = new Mock(); - _runnerWebProxy = new Mock(); _cert = new Mock(); #if OS_WINDOWS @@ -134,7 +130,6 @@ private TestHostContext CreateTestContext([CallerMemberName] String testName = " tc.SetSingleton(_extnMgr.Object); tc.SetSingleton(_agentServer.Object); tc.SetSingleton(_locationServer.Object); - tc.SetSingleton(_runnerWebProxy.Object); tc.SetSingleton(_cert.Object); #if OS_WINDOWS diff --git a/src/Test/L0/ProxyConfigL0.cs b/src/Test/L0/ProxyConfigL0.cs deleted file mode 100644 index 673b5c6e313..00000000000 --- a/src/Test/L0/ProxyConfigL0.cs +++ /dev/null @@ -1,116 +0,0 @@ -using GitHub.Runner.Common.Util; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using Xunit; -using System; -using GitHub.Runner.Sdk; - -namespace GitHub.Runner.Common.Tests -{ - public sealed class ProxyConfigL0 - { - private static readonly Regex NewHttpClientHandlerRegex = new Regex("New\\s+HttpClientHandler\\s*\\(", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private static readonly Regex NewHttpClientRegex = new Regex("New\\s+HttpClient\\s*\\(\\s*\\)", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private static readonly List SkippedFiles = new List() - { - "Runner.Common\\HostContext.cs", - "Runner.Common/HostContext.cs" - }; - - [Fact] - [Trait("Level", "L0")] - [Trait("Category", "Common")] - public void IsNotUseRawHttpClientHandler() - { - List sourceFiles = Directory.GetFiles( - TestUtil.GetProjectPath("Runner.Common"), - "*.cs", - SearchOption.AllDirectories).ToList(); - sourceFiles.AddRange(Directory.GetFiles( - TestUtil.GetProjectPath("Runner.Listener"), - "*.cs", - SearchOption.AllDirectories)); - sourceFiles.AddRange(Directory.GetFiles( - TestUtil.GetProjectPath("Runner.Worker"), - "*.cs", - SearchOption.AllDirectories)); - - List badCode = new List(); - foreach (string sourceFile in sourceFiles) - { - // Skip skipped files. - if (SkippedFiles.Any(s => sourceFile.Contains(s))) - { - continue; - } - - // Skip files in the obj directory. - if (sourceFile.Contains(StringUtil.Format("{0}obj{0}", Path.DirectorySeparatorChar))) - { - continue; - } - - int lineCount = 0; - foreach (string line in File.ReadAllLines(sourceFile)) - { - lineCount++; - if (NewHttpClientHandlerRegex.IsMatch(line)) - { - badCode.Add($"{sourceFile} (line {lineCount})"); - } - } - } - - Assert.True(badCode.Count == 0, $"The following code is using Raw HttpClientHandler() which will not follow the proxy setting agent have. Please use HostContext.CreateHttpClientHandler() instead.\n {string.Join("\n", badCode)}"); - } - - [Fact] - [Trait("Level", "L0")] - [Trait("Category", "Common")] - public void IsNotUseRawHttpClient() - { - List sourceFiles = Directory.GetFiles( - TestUtil.GetProjectPath("Runner.Common"), - "*.cs", - SearchOption.AllDirectories).ToList(); - sourceFiles.AddRange(Directory.GetFiles( - TestUtil.GetProjectPath("Runner.Listener"), - "*.cs", - SearchOption.AllDirectories)); - sourceFiles.AddRange(Directory.GetFiles( - TestUtil.GetProjectPath("Runner.Worker"), - "*.cs", - SearchOption.AllDirectories)); - - List badCode = new List(); - foreach (string sourceFile in sourceFiles) - { - // Skip skipped files. - if (SkippedFiles.Any(s => sourceFile.Contains(s))) - { - continue; - } - - // Skip files in the obj directory. - if (sourceFile.Contains(StringUtil.Format("{0}obj{0}", Path.DirectorySeparatorChar))) - { - continue; - } - - int lineCount = 0; - foreach (string line in File.ReadAllLines(sourceFile)) - { - lineCount++; - if (NewHttpClientRegex.IsMatch(line)) - { - badCode.Add($"{sourceFile} (line {lineCount})"); - } - } - } - - Assert.True(badCode.Count == 0, $"The following code is using Raw HttpClient() which will not follow the proxy setting agent have. Please use New HttpClient(HostContext.CreateHttpClientHandler()) instead.\n {string.Join("\n", badCode)}"); - } - } -} diff --git a/src/Test/L0/RunnerWebProxyL0.cs b/src/Test/L0/RunnerWebProxyL0.cs new file mode 100644 index 00000000000..b83371d6ad5 --- /dev/null +++ b/src/Test/L0/RunnerWebProxyL0.cs @@ -0,0 +1,416 @@ +using GitHub.Runner.Common.Util; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using Xunit; +using System; +using GitHub.Runner.Sdk; + +namespace GitHub.Runner.Common.Tests +{ + public sealed class RunnerWebProxyL0 + { + private static readonly Regex NewHttpClientHandlerRegex = new Regex("New\\s+HttpClientHandler\\s*\\(", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly Regex NewHttpClientRegex = new Regex("New\\s+HttpClient\\s*\\(\\s*\\)", RegexOptions.Compiled | RegexOptions.IgnoreCase); + private static readonly List SkippedFiles = new List() + { + "Runner.Common\\HostContext.cs", + "Runner.Common/HostContext.cs" + }; + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void IsNotUseRawHttpClientHandler() + { + List sourceFiles = Directory.GetFiles( + TestUtil.GetProjectPath("Runner.Common"), + "*.cs", + SearchOption.AllDirectories).ToList(); + sourceFiles.AddRange(Directory.GetFiles( + TestUtil.GetProjectPath("Runner.Listener"), + "*.cs", + SearchOption.AllDirectories)); + sourceFiles.AddRange(Directory.GetFiles( + TestUtil.GetProjectPath("Runner.Worker"), + "*.cs", + SearchOption.AllDirectories)); + + List badCode = new List(); + foreach (string sourceFile in sourceFiles) + { + // Skip skipped files. + if (SkippedFiles.Any(s => sourceFile.Contains(s))) + { + continue; + } + + // Skip files in the obj directory. + if (sourceFile.Contains(StringUtil.Format("{0}obj{0}", Path.DirectorySeparatorChar))) + { + continue; + } + + int lineCount = 0; + foreach (string line in File.ReadAllLines(sourceFile)) + { + lineCount++; + if (NewHttpClientHandlerRegex.IsMatch(line)) + { + badCode.Add($"{sourceFile} (line {lineCount})"); + } + } + } + + Assert.True(badCode.Count == 0, $"The following code is using Raw HttpClientHandler() which will not follow the proxy setting agent have. Please use HostContext.CreateHttpClientHandler() instead.\n {string.Join("\n", badCode)}"); + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void IsNotUseRawHttpClient() + { + List sourceFiles = Directory.GetFiles( + TestUtil.GetProjectPath("Runner.Common"), + "*.cs", + SearchOption.AllDirectories).ToList(); + sourceFiles.AddRange(Directory.GetFiles( + TestUtil.GetProjectPath("Runner.Listener"), + "*.cs", + SearchOption.AllDirectories)); + sourceFiles.AddRange(Directory.GetFiles( + TestUtil.GetProjectPath("Runner.Worker"), + "*.cs", + SearchOption.AllDirectories)); + + List badCode = new List(); + foreach (string sourceFile in sourceFiles) + { + // Skip skipped files. + if (SkippedFiles.Any(s => sourceFile.Contains(s))) + { + continue; + } + + // Skip files in the obj directory. + if (sourceFile.Contains(StringUtil.Format("{0}obj{0}", Path.DirectorySeparatorChar))) + { + continue; + } + + int lineCount = 0; + foreach (string line in File.ReadAllLines(sourceFile)) + { + lineCount++; + if (NewHttpClientRegex.IsMatch(line)) + { + badCode.Add($"{sourceFile} (line {lineCount})"); + } + } + } + + Assert.True(badCode.Count == 0, $"The following code is using Raw HttpClient() which will not follow the proxy setting agent have. Please use New HttpClient(HostContext.CreateHttpClientHandler()) instead.\n {string.Join("\n", badCode)}"); + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariables() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://127.0.0.1:8888"); + Environment.SetEnvironmentVariable("https_proxy", "http://user:pass@127.0.0.1:9999"); + Environment.SetEnvironmentVariable("no_proxy", "github.com, google.com,"); + var proxy = new RunnerWebProxy(); + + Assert.Equal("http://127.0.0.1:8888/", proxy.HttpProxyAddress); + Assert.Null(proxy.HttpProxyUsername); + Assert.Null(proxy.HttpProxyPassword); + + Assert.Equal("http://user:pass@127.0.0.1:9999/", proxy.HttpsProxyAddress); + Assert.Equal("user", proxy.HttpsProxyUsername); + Assert.Equal("pass", proxy.HttpsProxyPassword); + + Assert.Equal(2, proxy.NoProxyList.Count); + Assert.Equal("github.com", proxy.NoProxyList[0].Host); + Assert.Equal("google.com", proxy.NoProxyList[1].Host); + } + finally + { + CleanProxyEnv(); + } + } + +#if !OS_WINDOWS + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariablesPreferLowerCase() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://127.0.0.1:7777"); + Environment.SetEnvironmentVariable("HTTP_PROXY", "http://127.0.0.1:8888"); + Environment.SetEnvironmentVariable("https_proxy", "http://user:pass@127.0.0.1:8888"); + Environment.SetEnvironmentVariable("HTTPS_PROXY", "http://user:pass@127.0.0.1:9999"); + Environment.SetEnvironmentVariable("no_proxy", "github.com, github.com "); + Environment.SetEnvironmentVariable("NO_PROXY", "github.com, google.com,"); + var proxy = new RunnerWebProxy(); + + Assert.Equal("http://127.0.0.1:7777/", proxy.HttpProxyAddress); + Assert.Null(proxy.HttpProxyUsername); + Assert.Null(proxy.HttpProxyPassword); + + Assert.Equal("http://user:pass@127.0.0.1:8888/", proxy.HttpsProxyAddress); + Assert.Equal("user", proxy.HttpsProxyUsername); + Assert.Equal("pass", proxy.HttpsProxyPassword); + + Assert.Equal(1, proxy.NoProxyList.Count); + Assert.Equal("github.com", proxy.NoProxyList[0].Host); + } + finally + { + CleanProxyEnv(); + } + } +#endif + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariablesInvalidString() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "127.0.0.1:7777"); + Environment.SetEnvironmentVariable("https_proxy", "127.0.0.1"); + var proxy = new RunnerWebProxy(); + + Assert.Null(proxy.HttpProxyAddress); + Assert.Null(proxy.HttpProxyUsername); + Assert.Null(proxy.HttpProxyPassword); + + Assert.Null(proxy.HttpsProxyAddress); + Assert.Null(proxy.HttpsProxyUsername); + Assert.Null(proxy.HttpsProxyPassword); + + Assert.Equal(0, proxy.NoProxyList.Count); + } + finally + { + CleanProxyEnv(); + } + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariablesProxyCredentials() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://user1@127.0.0.1:8888"); + Environment.SetEnvironmentVariable("https_proxy", "http://user2:pass@127.0.0.1:9999"); + Environment.SetEnvironmentVariable("no_proxy", "github.com, google.com,"); + var proxy = new RunnerWebProxy(); + + Assert.Equal("http://user1@127.0.0.1:8888/", proxy.HttpProxyAddress); + Assert.Equal("user1", proxy.HttpProxyUsername); + Assert.Null(proxy.HttpProxyPassword); + + var cred = proxy.Credentials.GetCredential(new Uri("http://user1@127.0.0.1:8888/"), "Basic"); + Assert.Equal("user1", cred.UserName); + Assert.Equal(string.Empty, cred.Password); + + Assert.Equal("http://user2:pass@127.0.0.1:9999/", proxy.HttpsProxyAddress); + Assert.Equal("user2", proxy.HttpsProxyUsername); + Assert.Equal("pass", proxy.HttpsProxyPassword); + + cred = proxy.Credentials.GetCredential(new Uri("http://user2:pass@127.0.0.1:9999/"), "Basic"); + Assert.Equal("user2", cred.UserName); + Assert.Equal("pass", cred.Password); + + Assert.Equal(2, proxy.NoProxyList.Count); + Assert.Equal("github.com", proxy.NoProxyList[0].Host); + Assert.Equal("google.com", proxy.NoProxyList[1].Host); + } + finally + { + CleanProxyEnv(); + } + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariablesProxyCredentialsEncoding() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://user1:pass1%40@127.0.0.1:8888"); + Environment.SetEnvironmentVariable("https_proxy", "http://user2:pass2%40@127.0.0.1:9999"); + Environment.SetEnvironmentVariable("no_proxy", "github.com, google.com,"); + var proxy = new RunnerWebProxy(); + + Assert.Equal("http://user1:pass1%40@127.0.0.1:8888/", proxy.HttpProxyAddress); + Assert.Equal("user1", proxy.HttpProxyUsername); + Assert.Equal("pass1@", proxy.HttpProxyPassword); + + var cred = proxy.Credentials.GetCredential(new Uri("http://user1:pass1%40@127.0.0.1:8888/"), "Basic"); + Assert.Equal("user1", cred.UserName); + Assert.Equal("pass1@", cred.Password); + + Assert.Equal("http://user2:pass2%40@127.0.0.1:9999/", proxy.HttpsProxyAddress); + Assert.Equal("user2", proxy.HttpsProxyUsername); + Assert.Equal("pass2@", proxy.HttpsProxyPassword); + + cred = proxy.Credentials.GetCredential(new Uri("http://user2:pass2%40@127.0.0.1:9999/"), "Basic"); + Assert.Equal("user2", cred.UserName); + Assert.Equal("pass2@", cred.Password); + + Assert.Equal(2, proxy.NoProxyList.Count); + Assert.Equal("github.com", proxy.NoProxyList[0].Host); + Assert.Equal("google.com", proxy.NoProxyList[1].Host); + } + finally + { + CleanProxyEnv(); + } + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariablesByPassEmptyProxy() + { + var proxy = new RunnerWebProxy(); + Assert.True(proxy.IsBypassed(new Uri("https://github.com"))); + Assert.True(proxy.IsBypassed(new Uri("https://github.com"))); + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariablesGetProxyEmptyHttpProxy() + { + try + { + Environment.SetEnvironmentVariable("https_proxy", "http://user2:pass2%40@127.0.0.1:9999"); + var proxy = new RunnerWebProxy(); + + Assert.Null(proxy.GetProxy(new Uri("http://github.com"))); + Assert.Null(proxy.GetProxy(new Uri("http://example.com:444"))); + + Assert.Equal("http://user2:pass2%40@127.0.0.1:9999/", proxy.GetProxy(new Uri("https://something.com")).AbsoluteUri); + Assert.Equal("http://user2:pass2%40@127.0.0.1:9999/", proxy.GetProxy(new Uri("https://www.something2.com")).AbsoluteUri); + } + finally + { + CleanProxyEnv(); + } + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariablesGetProxyEmptyHttpsProxy() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://user1:pass1%40@127.0.0.1:8888"); + var proxy = new RunnerWebProxy(); + + Assert.Null(proxy.GetProxy(new Uri("https://github.com/owner/repo"))); + Assert.Null(proxy.GetProxy(new Uri("https://mails.google.com"))); + + Assert.Equal("http://user1:pass1%40@127.0.0.1:8888/", proxy.GetProxy(new Uri("http://something.com")).AbsoluteUri); + Assert.Equal("http://user1:pass1%40@127.0.0.1:8888/", proxy.GetProxy(new Uri("http://www.something2.com")).AbsoluteUri); + } + finally + { + CleanProxyEnv(); + } + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariablesNoProxy() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://user1:pass1%40@127.0.0.1:8888"); + Environment.SetEnvironmentVariable("https_proxy", "http://user2:pass2%40@127.0.0.1:9999"); + Environment.SetEnvironmentVariable("no_proxy", "github.com, .google.com, example.com:444, 192.168.0.123:123, 192.168.1.123"); + var proxy = new RunnerWebProxy(); + + Assert.False(proxy.IsBypassed(new Uri("https://actions.com"))); + Assert.False(proxy.IsBypassed(new Uri("https://ggithub.com"))); + Assert.False(proxy.IsBypassed(new Uri("https://github.comm"))); + Assert.False(proxy.IsBypassed(new Uri("https://google.com"))); + Assert.False(proxy.IsBypassed(new Uri("https://example.com"))); + Assert.False(proxy.IsBypassed(new Uri("http://example.com:333"))); + Assert.False(proxy.IsBypassed(new Uri("http://192.168.0.123:123"))); + Assert.False(proxy.IsBypassed(new Uri("http://192.168.1.123/home"))); + + Assert.True(proxy.IsBypassed(new Uri("https://github.com"))); + Assert.True(proxy.IsBypassed(new Uri("https://GITHUB.COM"))); + Assert.True(proxy.IsBypassed(new Uri("https://github.com/owner/repo"))); + Assert.True(proxy.IsBypassed(new Uri("https://actions.github.com"))); + Assert.True(proxy.IsBypassed(new Uri("https://mails.google.com"))); + Assert.True(proxy.IsBypassed(new Uri("https://MAILS.GOOGLE.com"))); + Assert.True(proxy.IsBypassed(new Uri("https://mails.v2.google.com"))); + Assert.True(proxy.IsBypassed(new Uri("http://mails.v2.v3.google.com/inbox"))); + Assert.True(proxy.IsBypassed(new Uri("https://example.com:444"))); + Assert.True(proxy.IsBypassed(new Uri("http://example.com:444"))); + Assert.True(proxy.IsBypassed(new Uri("http://example.COM:444"))); + } + finally + { + CleanProxyEnv(); + } + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void WebProxyFromEnvironmentVariablesGetProxy() + { + try + { + Environment.SetEnvironmentVariable("http_proxy", "http://user1:pass1%40@127.0.0.1:8888"); + Environment.SetEnvironmentVariable("https_proxy", "http://user2:pass2%40@127.0.0.1:9999"); + Environment.SetEnvironmentVariable("no_proxy", "github.com, .google.com, example.com:444"); + var proxy = new RunnerWebProxy(); + + Assert.Null(proxy.GetProxy(new Uri("http://github.com"))); + Assert.Null(proxy.GetProxy(new Uri("https://github.com/owner/repo"))); + Assert.Null(proxy.GetProxy(new Uri("https://mails.google.com"))); + Assert.Null(proxy.GetProxy(new Uri("http://example.com:444"))); + + + Assert.Equal("http://user1:pass1%40@127.0.0.1:8888/", proxy.GetProxy(new Uri("http://something.com")).AbsoluteUri); + Assert.Equal("http://user1:pass1%40@127.0.0.1:8888/", proxy.GetProxy(new Uri("http://www.something2.com")).AbsoluteUri); + + Assert.Equal("http://user2:pass2%40@127.0.0.1:9999/", proxy.GetProxy(new Uri("https://something.com")).AbsoluteUri); + Assert.Equal("http://user2:pass2%40@127.0.0.1:9999/", proxy.GetProxy(new Uri("https://www.something2.com")).AbsoluteUri); + } + finally + { + CleanProxyEnv(); + } + } + + private void CleanProxyEnv() + { + Environment.SetEnvironmentVariable("http_proxy", null); + Environment.SetEnvironmentVariable("https_proxy", null); + Environment.SetEnvironmentVariable("HTTP_PROXY", null); + Environment.SetEnvironmentVariable("HTTPS_PROXY", null); + Environment.SetEnvironmentVariable("no_proxy", null); + Environment.SetEnvironmentVariable("NO_PROXY", null); + } + } +} diff --git a/src/Test/L0/TestHostContext.cs b/src/Test/L0/TestHostContext.cs index 4f14729bbf4..0a7657cc6d5 100644 --- a/src/Test/L0/TestHostContext.cs +++ b/src/Test/L0/TestHostContext.cs @@ -90,6 +90,8 @@ public StartupType StartupType public ProductInfoHeaderValue UserAgent => new ProductInfoHeaderValue("L0Test", "0.0"); + public RunnerWebProxy WebProxy => new RunnerWebProxy(); + public async Task Delay(TimeSpan delay, CancellationToken token) { await Task.Delay(TimeSpan.Zero); @@ -274,24 +276,6 @@ public string GetConfigFile(WellKnownConfigFile configFile) ".certificates"); break; - case WellKnownConfigFile.Proxy: - path = Path.Combine( - GetDirectory(WellKnownDirectory.Root), - ".proxy"); - break; - - case WellKnownConfigFile.ProxyCredentials: - path = Path.Combine( - GetDirectory(WellKnownDirectory.Root), - ".proxycredentials"); - break; - - case WellKnownConfigFile.ProxyBypass: - path = Path.Combine( - GetDirectory(WellKnownDirectory.Root), - ".proxybypass"); - break; - case WellKnownConfigFile.Options: path = Path.Combine( GetDirectory(WellKnownDirectory.Root), diff --git a/src/Test/L0/Worker/ActionManagerL0.cs b/src/Test/L0/Worker/ActionManagerL0.cs index db9a85b1c74..046b9c6bf5c 100644 --- a/src/Test/L0/Worker/ActionManagerL0.cs +++ b/src/Test/L0/Worker/ActionManagerL0.cs @@ -1688,10 +1688,6 @@ private void Setup([CallerMemberName] string name = "") _hc.SetSingleton(_pluginManager.Object); _hc.SetSingleton(actionManifest); - var proxy = new RunnerWebProxy(); - proxy.Initialize(_hc); - _hc.SetSingleton(proxy); - _configurationStore = new Mock(); _configurationStore .Setup(x => x.GetSettings()) diff --git a/src/Test/L0/Worker/ExecutionContextL0.cs b/src/Test/L0/Worker/ExecutionContextL0.cs index d494bd79b10..0660c4a7429 100644 --- a/src/Test/L0/Worker/ExecutionContextL0.cs +++ b/src/Test/L0/Worker/ExecutionContextL0.cs @@ -256,10 +256,6 @@ private TestHostContext CreateTestContext([CallerMemberName] String testName = " configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings()); hc.SetSingleton(configurationStore.Object); - // Arrange: Setup the proxy configation. - var proxy = new Mock(); - hc.SetSingleton(proxy.Object); - // Arrange: Setup the cert configation. var cert = new Mock(); hc.SetSingleton(cert.Object); diff --git a/src/Test/L0/Worker/JobRunnerL0.cs b/src/Test/L0/Worker/JobRunnerL0.cs index c64a6eac0e7..f2c9a9609e6 100644 --- a/src/Test/L0/Worker/JobRunnerL0.cs +++ b/src/Test/L0/Worker/JobRunnerL0.cs @@ -22,7 +22,6 @@ public sealed class JobRunnerL0 private CancellationTokenSource _tokenSource; private Mock _jobServer; private Mock _jobServerQueue; - private Mock _proxyConfig; private Mock _cert; private Mock _config; private Mock _extensions; @@ -43,7 +42,6 @@ private TestHostContext CreateTestContext([CallerMemberName] String testName = " _jobExtension = new Mock(); _jobServer = new Mock(); _jobServerQueue = new Mock(); - _proxyConfig = new Mock(); _cert = new Mock(); _stepRunner = new Mock(); _logger = new Mock(); @@ -95,9 +93,6 @@ private TestHostContext CreateTestContext([CallerMemberName] String testName = " _jobExtension.Setup(x => x.InitializeJob(It.IsAny(), It.IsAny())). Returns(Task.FromResult(_initResult)); - _proxyConfig.Setup(x => x.ProxyAddress) - .Returns(string.Empty); - var settings = new RunnerSettings { AgentId = 1, @@ -114,7 +109,6 @@ private TestHostContext CreateTestContext([CallerMemberName] String testName = " hc.SetSingleton(_config.Object); hc.SetSingleton(_jobServer.Object); hc.SetSingleton(_jobServerQueue.Object); - hc.SetSingleton(_proxyConfig.Object); hc.SetSingleton(_cert.Object); hc.SetSingleton(_stepRunner.Object); hc.SetSingleton(_extensions.Object); diff --git a/src/Test/L0/Worker/WorkerL0.cs b/src/Test/L0/Worker/WorkerL0.cs index f0d75ac5c69..0bebcec4c0f 100644 --- a/src/Test/L0/Worker/WorkerL0.cs +++ b/src/Test/L0/Worker/WorkerL0.cs @@ -16,14 +16,12 @@ public sealed class WorkerL0 { private Mock _processChannel; private Mock _jobRunner; - private Mock _proxy; private Mock _cert; public WorkerL0() { _processChannel = new Mock(); _jobRunner = new Mock(); - _proxy = new Mock(); _cert = new Mock(); } @@ -92,7 +90,6 @@ public async void DispatchRunNewJob() var worker = new GitHub.Runner.Worker.Worker(); hc.EnqueueInstance(_processChannel.Object); hc.EnqueueInstance(_jobRunner.Object); - hc.SetSingleton(_proxy.Object); hc.SetSingleton(_cert.Object); worker.Initialize(hc); var jobMessage = CreateJobRequestMessage("job1"); @@ -145,7 +142,6 @@ public async void DispatchCancellation() var worker = new GitHub.Runner.Worker.Worker(); hc.EnqueueInstance(_processChannel.Object); hc.EnqueueInstance(_jobRunner.Object); - hc.SetSingleton(_proxy.Object); hc.SetSingleton(_cert.Object); worker.Initialize(hc); var jobMessage = CreateJobRequestMessage("job1");