public static void EnableTraceLoggingFile(Program program, OperationArguments operationArguments, string logFilePath) { const int LogFileMaxLength = 8 * 1024 * 1024; // 8 MB if (program is null) { throw new ArgumentNullException(nameof(program)); } if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } if (logFilePath is null) { throw new ArgumentNullException(nameof(logFilePath)); } string logFileName = Path.Combine(logFilePath, Path.ChangeExtension(Program.ConfigPrefix, ".log")); var logFileInfo = new FileInfo(logFileName); if (logFileInfo.Exists && logFileInfo.Length > LogFileMaxLength) { for (int i = 1; i < int.MaxValue; i++) { string moveName = string.Format("{0}{1:000}.log", Program.ConfigPrefix, i); string movePath = Path.Combine(logFilePath, moveName); if (!File.Exists(movePath)) { logFileInfo.MoveTo(movePath); break; } } } Git.Trace.WriteLine($"trace log destination is '{logFilePath}'."); using (var fileStream = File.Open(logFileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)) { var listener = new StreamWriter(fileStream, Encoding.UTF8); Git.Trace.AddListener(listener); // write a small header to help with identifying new log entries listener.Write('\n'); listener.Write($"{DateTime.Now:yyyy.MM.dd HH:mm:ss} Microsoft {program.Title} version {program.Version.ToString(3)}\n"); } }
internal void Get() { Task.Run(async() => { var operationArguments = new OperationArguments(_context); // Parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html using (var stdin = InStream) { await operationArguments.ReadInput(stdin); } if (operationArguments.TargetUri is null) { var inner = new ArgumentNullException(nameof(operationArguments.TargetUri)); throw new ArgumentException(inner.Message, nameof(operationArguments), inner); } // Load operation arguments. await LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); // Read the details of any git-remote-http(s).exe parent process, but only if // an override hasn't been set which would override the git-remote details. if (string.IsNullOrEmpty(operationArguments.UrlOverride)) { ReadGitRemoteDetails(operationArguments); } // Set the parent window handle. ParentHwnd = operationArguments.ParentHwnd; Credential credentials; if ((credentials = await QueryCredentials(operationArguments)) == null) { Exit(-1, LogonFailedMessage); } else { using (var stdout = OutStream) { operationArguments.WriteToStream(stdout); } } }).Wait(); }
internal void Store() { // parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html using (var stdin = InStream) { OperationArguments operationArguments = new OperationArguments(stdin); Debug.Assert(operationArguments != null, "The operationArguments is null"); Debug.Assert(operationArguments.Username != null, "The operaionArgument.Username is null"); Debug.Assert(operationArguments.TargetUri != null, "The operationArgument.TargetUri is null"); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); var credentials = operationArguments.Credentials; var task = Task.Run(async() => { return(await CreateAuthentication(operationArguments)); }); BaseAuthentication authentication = task.Result; switch (operationArguments.Authority) { default: case AuthorityType.Basic: Git.Trace.WriteLine($"storing basic credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.Bitbucket: Git.Trace.WriteLine($"storing Bitbucket credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.AzureDirectory: case AuthorityType.MicrosoftAccount: Git.Trace.WriteLine($"storing VSTS credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.GitHub: Git.Trace.WriteLine($"storing GitHub credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.Ntlm: Git.Trace.WriteLine($"storing NTLM credentials for '{operationArguments.TargetUri}'."); break; } authentication.SetCredentials(operationArguments.TargetUri, credentials); } }
public static void ReadGitRemoteDetails(Program program, OperationArguments operationArguments) { if (program is null) { throw new ArgumentNullException(nameof(program)); } if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } if (program.Utilities.TryReadGitRemoteHttpDetails(out string commandLine, out _)) { operationArguments.GitRemoteHttpCommandLine = commandLine; } }
public static async Task <bool> DeleteCredentials(Program program, OperationArguments operationArguments) { if (program is null) { throw new ArgumentNullException(nameof(program)); } if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } BaseAuthentication authentication = await program.CreateAuthentication(operationArguments); switch (operationArguments.Authority) { default: case AuthorityType.Basic: { program.Trace.WriteLine($"deleting basic credentials for '{operationArguments.TargetUri}'."); return(await authentication.DeleteCredentials(operationArguments.TargetUri)); } case AuthorityType.AzureDirectory: case AuthorityType.MicrosoftAccount: { program.Trace.WriteLine($"deleting VSTS credentials for '{operationArguments.TargetUri}'."); var vstsAuth = authentication as Vsts.Authentication; return(await vstsAuth.DeleteCredentials(operationArguments.TargetUri)); } case AuthorityType.GitHub: { program.Trace.WriteLine($"deleting GitHub credentials for '{operationArguments.TargetUri}'."); var ghAuth = authentication as Github.Authentication; return(await ghAuth.DeleteCredentials(operationArguments.TargetUri)); } case AuthorityType.Bitbucket: { program.Trace.WriteLine($"deleting Bitbucket credentials for '{operationArguments.TargetUri}'."); var bbAuth = authentication as Bitbucket.Authentication; return(await bbAuth.DeleteCredentials(operationArguments.TargetUri, operationArguments.Username)); } } }
internal void Get() { // Parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html using (var stdin = InStream) { OperationArguments operationArguments = new OperationArguments(_context); Task.Run(async() => { await operationArguments.ReadInput(stdin); if (operationArguments.TargetUri is null) { var inner = new ArgumentNullException(nameof(operationArguments.TargetUri)); throw new ArgumentException(inner.Message, nameof(operationArguments), inner); } // Load operation arguments. await LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); // Read the details of any git-remote-http(s).exe parent process. ReadGitRemoteDetails(operationArguments); // Set the parent window handle. ParentHwnd = operationArguments.ParentHwnd; Credential credentials; if ((credentials = await QueryCredentials(operationArguments)) == null) { Exit(-1, "Logon failed, use ctrl+c to cancel basic credential prompt."); } else { using (var stdout = OutStream) { operationArguments.WriteToStream(stdout); } } }).Wait(); } }
internal void Erase() { // parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html using (var stdin = InStream) { var operationArguments = new OperationArguments(_context); Task.Run(async() => { await operationArguments.ReadInput(stdin); if (operationArguments.TargetUri is null) { var inner = new ArgumentNullException(nameof(operationArguments.TargetUri)); throw new ArgumentException(inner.Message, nameof(operationArguments), inner); } // Load operation arguments. await LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); // Read the details of any git-remote-http(s).exe parent process, but only if // an override hasn't been set which would override the git-remote details. if (string.IsNullOrEmpty(operationArguments.UrlOverride)) { ReadGitRemoteDetails(operationArguments); } // Set the parent window handle. ParentHwnd = operationArguments.ParentHwnd; if (operationArguments.PreserveCredentials) { _context.Trace.WriteLine($"{KeyTypeName(KeyType.PreserveCredentials)} = true, canceling erase request."); return; } await DeleteCredentials(operationArguments); }).Wait(); } }
private static void Store() { // parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html using (var stdin = Console.OpenStandardInput()) { OperationArguments operationArguments = new OperationArguments(stdin); Debug.Assert(operationArguments != null, "The operationArguments is null"); Debug.Assert(operationArguments.CredUsername != null, "The operaionArgument.Username is null"); Debug.Assert(operationArguments.TargetUri != null, "The operationArgument.TargetUri is null"); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); Credential credentials = new Credential(operationArguments.CredUsername, operationArguments.CredPassword); BaseAuthentication authentication = CreateAuthentication(operationArguments); switch (operationArguments.Authority) { default: case AuthorityType.Basic: Git.Trace.WriteLine($"storing basic credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.AzureDirectory: case AuthorityType.MicrosoftAccount: Git.Trace.WriteLine($"storing VSTS credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.GitHub: Git.Trace.WriteLine($"storing GitHub credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.Ntlm: Git.Trace.WriteLine($"storing NTLM credentials for '{operationArguments.TargetUri}'."); break; } authentication.SetCredentials(operationArguments.TargetUri, credentials); } }
public static void EnableTraceLogging(Program program, OperationArguments operationArguments) { if (program is null) { throw new ArgumentNullException(nameof(program)); } if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } if (operationArguments.WriteLog) { program.Trace.WriteLine("trace logging enabled."); string gitConfigPath; if (program.Where.GitLocalConfig(out gitConfigPath)) { program.Trace.WriteLine($"git local config found at '{gitConfigPath}'."); string gitDirPath = Path.GetDirectoryName(gitConfigPath); if (program.Storage.DirectoryExists(gitDirPath)) { program.EnableTraceLogging(operationArguments, gitDirPath); } } else if (program.Where.GitGlobalConfig(out gitConfigPath)) { program.Trace.WriteLine($"git global config found at '{gitConfigPath}'."); string homeDirPath = Path.GetDirectoryName(gitConfigPath); if (program.Storage.DirectoryExists(homeDirPath)) { program.EnableTraceLogging(operationArguments, homeDirPath); } } } #if DEBUG program.Trace.WriteLine($"GCM arguments:{Environment.NewLine}{operationArguments}"); #endif }
private static void Store() { // parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html var stdin = Console.OpenStandardInput(); OperationArguments operationArguments = new OperationArguments(stdin); Debug.Assert(operationArguments != null, "The operationArguments is null"); Debug.Assert(operationArguments.CredUsername != null, "The operaionArgument.Username is null"); Debug.Assert(operationArguments.TargetUri != null, "The operationArgument.TargetUri is null"); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); BaseAuthentication authentication = CreateAuthentication(operationArguments); Credential credentials = new Credential(operationArguments.CredUsername, operationArguments.CredPassword); authentication.SetCredentials(operationArguments.TargetUri, credentials); }
private static void Get() { // parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html using (var stdin = Console.OpenStandardInput()) { OperationArguments operationArguments = new OperationArguments(stdin); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); QueryCredentials(operationArguments); using (var stdout = Console.OpenStandardOutput()) { operationArguments.WriteToStream(stdout); } } }
private static void Erase() { // parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html var stdin = Console.OpenStandardInput(); OperationArguments operationArguments = new OperationArguments(stdin); Debug.Assert(operationArguments != null, "The operationArguments is null"); Debug.Assert(operationArguments.TargetUri != null, "The operationArgument.TargetUri is null"); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); if (operationArguments.PreserveCredentials) { Git.Trace.WriteLine($"{ConfigPreserveCredentialsKey} = true, canceling erase request."); return; } DeleteCredentials(operationArguments); }
public static void DeleteCredentials(Program program, OperationArguments operationArguments) { if (operationArguments is null) { throw new ArgumentNullException("operationArguments"); } var task = Task.Run(async() => { return(await program.CreateAuthentication(operationArguments)); }); BaseAuthentication authentication = task.Result; switch (operationArguments.Authority) { default: case AuthorityType.Basic: Git.Trace.WriteLine($"deleting basic credentials for '{operationArguments.TargetUri}'."); authentication.DeleteCredentials(operationArguments.TargetUri); break; case AuthorityType.AzureDirectory: case AuthorityType.MicrosoftAccount: Git.Trace.WriteLine($"deleting VSTS credentials for '{operationArguments.TargetUri}'."); var vstsAuth = authentication as BaseVstsAuthentication; vstsAuth.DeleteCredentials(operationArguments.TargetUri); break; case AuthorityType.GitHub: Git.Trace.WriteLine($"deleting GitHub credentials for '{operationArguments.TargetUri}'."); var ghAuth = authentication as Github.Authentication; ghAuth.DeleteCredentials(operationArguments.TargetUri); break; case AuthorityType.Bitbucket: Git.Trace.WriteLine($"deleting Bitbucket credentials for '{operationArguments.TargetUri}'."); var bbAuth = authentication as Bitbucket.Authentication; bbAuth.DeleteCredentials(operationArguments.TargetUri, operationArguments.CredUsername); break; } }
public static bool TryReadString(Program program, OperationArguments operationArguments, KeyType key, out string value) { if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } if (program.ConfigurationKeys.TryGetValue(key, out string configKey) | program.EnvironmentKeys.TryGetValue(key, out string environKey)) { var envars = operationArguments.EnvironmentVariables; // Look for an entry in the environment variables. string localVal; if (!string.IsNullOrWhiteSpace(environKey) && envars.TryGetValue(environKey, out localVal) && !string.IsNullOrWhiteSpace(localVal)) { value = localVal; return(true); } Git.Configuration config = operationArguments.GitConfiguration; // Look for an entry in the git config. Git.Configuration.Entry entry; if (!string.IsNullOrWhiteSpace(configKey) && config.TryGetEntry(Program.ConfigPrefix, operationArguments.QueryUri, configKey, out entry) && !string.IsNullOrWhiteSpace(entry.Value)) { value = entry.Value; return(true); } } value = null; return(false); }
internal void Erase() { // parse the operations arguments from stdin (this is how git sends commands) // see: https://www.kernel.org/pub/software/scm/git/docs/technical/api-credentials.html // see: https://www.kernel.org/pub/software/scm/git/docs/git-credential.html using (var stdin = InStream) { OperationArguments operationArguments = new OperationArguments(stdin); Debug.Assert(operationArguments != null, "The operationArguments is null"); Debug.Assert(operationArguments.TargetUri != null, "The operationArgument.TargetUri is null"); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); if (operationArguments.PreserveCredentials) { Git.Trace.WriteLine($"{KeyTypeName(KeyType.PreserveCredentials)} = true, canceling erase request."); return; } DeleteCredentials(operationArguments); } }
internal void EnableTraceLogging(OperationArguments operationArguments) => _enableTraceLogging(this, operationArguments);
private static void Delete() { Trace.WriteLine("Program::Erase"); string[] args = Environment.GetCommandLineArgs(); if (args.Length < 3) { goto error_parse; } string url = args[2]; Uri uri = null; if (Uri.IsWellFormedUriString(url, UriKind.Absolute)) { if (!Uri.TryCreate(url, UriKind.Absolute, out uri)) { goto error_parse; } } else { url = String.Format("{0}://{1}", Uri.UriSchemeHttps, url); if (!Uri.TryCreate(url, UriKind.Absolute, out uri)) { goto error_parse; } } var stdin = Console.OpenStandardInput(); OperationArguments operationArguments = new OperationArguments(stdin); operationArguments.QueryUri = uri; LoadOperationArguments(operationArguments); BaseAuthentication authentication = CreateAuthentication(operationArguments); switch (operationArguments.Authority) { default: case AuthorityType.Basic: Trace.WriteLine(" deleting basic credentials"); authentication.DeleteCredentials(operationArguments.TargetUri); break; case AuthorityType.AzureDirectory: case AuthorityType.MicrosoftAccount: Trace.WriteLine(" deleting VSTS credentials"); BaseVstsAuthentication vstsAuth = authentication as BaseVstsAuthentication; vstsAuth.DeleteCredentials(operationArguments.TargetUri); // call delete twice to purge any stored ADA tokens vstsAuth.DeleteCredentials(operationArguments.TargetUri); break; case AuthorityType.GitHub: Trace.WriteLine(" deleting GitHub credentials"); GitHubAuthentication ghAuth = authentication as GitHubAuthentication; ghAuth.DeleteCredentials(operationArguments.TargetUri); break; } return; error_parse: Console.Error.WriteLine("Fatal: unable to parse target URI."); }
private static void Askpass(string[] args) { if (args == null || args.Length == 0) throw new ArgumentException("Arguments cannot be empty."); Match match; if ((match = AskPasswordRegex.Match(args[0])).Success || (match = AskPassphraseRegex.Match(args[0])).Success) { Git.Trace.WriteLine("querying for passphrase key."); if (match.Groups.Count < 2) throw new ArgumentException("Unable to understand command."); string request = match.Groups[0].Value; string resource = match.Groups[1].Value; Git.Trace.WriteLine($"open dialog for '{resource}'."); System.Windows.Application application = new System.Windows.Application(); Gui.PassphraseWindow prompt = new Gui.PassphraseWindow(resource); application.Run(prompt); if (!prompt.Cancelled && !string.IsNullOrEmpty(prompt.Passphrase)) { string passphase = prompt.Passphrase; Git.Trace.WriteLine("passphase acquired."); Console.Out.Write(passphase + "\n"); return; } Git.Trace.WriteLine("failed to interactively acquire credentials."); } if ((match = AskCredentialRegex.Match(args[0])).Success) { Git.Trace.WriteLine("querying for HTTPS credentials."); if (match.Groups.Count < 3) throw new ArgumentException("Unable to understand command."); string seeking = match.Groups[1].Value; string targetUrl = match.Groups[2].Value; Uri targetUri; if (Uri.TryCreate(targetUrl, UriKind.Absolute, out targetUri)) { Git.Trace.WriteLine($"success parsing URL, targetUri = '{targetUri}'."); // config stored credentials come in the format of <username>[:<password>]@<url> with password being optional // scheme terminator is actually "://" so we need adjust to get the correct index int schemeTerminator = targetUrl.IndexOf(':') + 2; int credentialTerminator = targetUrl.IndexOf('@', schemeTerminator + 1); if (credentialTerminator > 0) { Git.Trace.WriteLine("'@' symbol found in URL, assuming credential prefix."); string username = null; string password = null; int passwordTerminator = targetUrl.IndexOf(':', schemeTerminator + 1); if (passwordTerminator > 0) { Git.Trace.WriteLine("':' symbol found in URL, assuming credential prefix contains password."); username = targetUrl.Substring(schemeTerminator + 1, passwordTerminator - schemeTerminator - 1); password = targetUrl.Substring(passwordTerminator + 1, credentialTerminator - passwordTerminator + 1); // print the password if it sought if (seeking.Equals("Password", StringComparison.OrdinalIgnoreCase)) { Console.Out.Write(password + '\n'); return; } } else { username = targetUrl.Substring(schemeTerminator + 1, credentialTerminator - schemeTerminator - 1); } // print the username if it sought if (seeking.Equals("Username", StringComparison.OrdinalIgnoreCase)) { Console.Out.Write(username + '\n'); return; } } // create a target Url with the credential portion stripped, because Git doesn't report hosts with credentials targetUrl = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}://{1}", targetUri.Scheme, targetUri.Host); // retain the port if specified if (!targetUri.IsDefaultPort) { targetUrl += $":{targetUri.Port}"; } // retain the path if specified if (!String.IsNullOrWhiteSpace(targetUri.LocalPath)) { targetUrl += targetUri.LocalPath; } if (Uri.TryCreate(targetUrl, UriKind.Absolute, out targetUri)) { Git.Trace.WriteLine($"success parsing URL, targetUri = '{targetUri}'."); OperationArguments operationArguments = new OperationArguments(targetUri); // load up the operation arguments, enable tracing, and query for credentials LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); if (QueryCredentials(operationArguments)) { if (seeking.Equals("Username", StringComparison.OrdinalIgnoreCase)) { Git.Trace.WriteLine($"username for '{targetUrl}' asked for and found."); Console.Out.Write(operationArguments.CredUsername + '\n'); return; } if (seeking.Equals("Password", StringComparison.OrdinalIgnoreCase)) { Git.Trace.WriteLine($"password for '{targetUrl}' asked for and found."); Console.Out.Write(operationArguments.CredPassword + '\n'); return; } } } else { Git.Trace.WriteLine("error: unable to parse target URL."); } } else { Git.Trace.WriteLine("error: unable to parse supplied URL."); } Git.Trace.WriteLine($"failed to detect {seeking} in target URL."); } Git.Trace.WriteLine("failed to acquire credentials."); }
internal void Askpass(string[] args) { if (args == null || args.Length == 0) { throw new ArgumentException("Arguments cannot be empty."); } Gui.UserPromptKind promptKind = Gui.UserPromptKind.SshPassphrase; Match match; if ((match = AskPasswordRegex.Match(args[0])).Success) { promptKind = Gui.UserPromptKind.CredentialsPassword; } else if ((match = AskPassphraseRegex.Match(args[0])).Success) { promptKind = Gui.UserPromptKind.SshPassphrase; } if (match.Success) { _context.Trace.WriteLine("querying for passphrase key."); if (match.Groups.Count < 2) { throw new ArgumentException("Unable to understand command."); } // string request = match.Groups[0].Value; string resource = match.Groups[1].Value; _context.Trace.WriteLine($"open dialog for '{resource}'."); System.Windows.Application application = new System.Windows.Application(); Gui.UserPromptDialog prompt = new Gui.UserPromptDialog(promptKind, resource); application.Run(prompt); if (!prompt.Failed && !string.IsNullOrEmpty(prompt.Response)) { string passphase = prompt.Response; _context.Trace.WriteLine("passphase acquired."); Out.Write(passphase + "\n"); return; } Die("failed to interactively acquire credentials."); } if ((match = AskCredentialRegex.Match(args[0])).Success) { _context.Trace.WriteLine("querying for basic credentials."); if (match.Groups.Count < 3) { throw new ArgumentException("Unable to understand command."); } string seeking = match.Groups[1].Value; string targetUrl = match.Groups[2].Value; string username = string.Empty; string password = string.Empty; Uri targetUri = null; // Since we're looking for HTTP(s) credentials, we can use NetFx `Uri` class. if (Uri.TryCreate(targetUrl, UriKind.Absolute, out targetUri)) { _context.Trace.WriteLine($"success parsing URL, targetUri = '{targetUri}'."); if (TryParseUrlCredentials(targetUrl, out username, out password)) { if (password != null && seeking.Equals("Password", StringComparison.OrdinalIgnoreCase)) { Out.Write(password + '\n'); return; } // print the username if it sought if (seeking.Equals("Username", StringComparison.OrdinalIgnoreCase)) { Out.Write(username + '\n'); return; } } // create a target Url with the credential portion stripped, because Git doesn't // report hosts with credentials targetUrl = targetUri.Scheme + "://"; // Add the username@ portion of the url if it exists if (username != null) { targetUrl += Uri.EscapeDataString(username); targetUrl += '@'; } targetUrl += targetUri.Host; // retain the port if specified if (!targetUri.IsDefaultPort) { targetUrl += $":{targetUri.Port}"; } // retain the path if specified if (!string.IsNullOrWhiteSpace(targetUri.LocalPath)) { targetUrl += targetUri.LocalPath; } if (Uri.TryCreate(targetUrl, UriKind.Absolute, out targetUri)) { _context.Trace.WriteLine($"success parsing URL, targetUri = '{targetUri}'."); OperationArguments operationArguments = new OperationArguments(_context, targetUri); operationArguments.SetCredentials(username ?? string.Empty, password ?? string.Empty); // Load up the operation arguments, enable tracing, and query for credentials. Task.Run(async() => { await LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); Credential credentials; if ((credentials = await QueryCredentials(operationArguments)) != null) { if (seeking.Equals("Username", StringComparison.OrdinalIgnoreCase)) { _context.Trace.WriteLine($"username for '{targetUrl}' asked for and found."); Out.Write(credentials.Username + '\n'); return; } if (seeking.Equals("Password", StringComparison.OrdinalIgnoreCase)) { _context.Trace.WriteLine($"password for '{targetUrl}' asked for and found."); Out.Write(credentials.Password + '\n'); return; } } else { _context.Trace.WriteLine($"user cancelled credential dialog."); return; } }).Wait(); } else { _context.Trace.WriteLine("error: unable to parse target URL."); } } else { _context.Trace.WriteLine("error: unable to parse supplied URL."); } Die($"failed to detect {seeking} in target URL."); } if ((match = AskAuthenticityRegex.Match(args[0])).Success) { string host = match.Groups[1].Value; string fingerprint = match.Groups[2].Value; _context.Trace.WriteLine($"requesting authorization to add {host} ({fingerprint}) to known hosts."); System.Windows.Application application = new System.Windows.Application(); Gui.UserPromptDialog prompt = new Gui.UserPromptDialog(host, fingerprint); application.Run(prompt); if (prompt.Failed) { _context.Trace.WriteLine("denied authorization of host."); Out.Write("no\n"); } else { _context.Trace.WriteLine("approved authorization of host."); Out.Write("yes\n"); } return; } Die("failed to acquire credentials."); }
private static void Delete() { string[] args = Environment.GetCommandLineArgs(); if (args.Length < 3) { goto error_parse; } string url = args[2]; Uri uri = null; if (Uri.IsWellFormedUriString(url, UriKind.Absolute)) { if (!Uri.TryCreate(url, UriKind.Absolute, out uri)) { goto error_parse; } } else { url = String.Format("{0}://{1}", Uri.UriSchemeHttps, url); if (!Uri.TryCreate(url, UriKind.Absolute, out uri)) { goto error_parse; } } using (var stdin = Console.OpenStandardInput()) { OperationArguments operationArguments = new OperationArguments(stdin); operationArguments.QueryUri = uri; LoadOperationArguments(operationArguments); BaseAuthentication authentication = CreateAuthentication(operationArguments); switch (operationArguments.Authority) { default: case AuthorityType.Basic: Git.Trace.WriteLine($"deleting basic credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.AzureDirectory: case AuthorityType.MicrosoftAccount: Git.Trace.WriteLine($"deleting VSTS credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.GitHub: Git.Trace.WriteLine($"deleting GitHub credentials for '{operationArguments.TargetUri}'."); break; case AuthorityType.Ntlm: Git.Trace.WriteLine($"deleting NTLM credentials for '{operationArguments.TargetUri}'."); break; } authentication.DeleteCredentials(operationArguments.TargetUri); } return; error_parse: Die("Unable to parse target URI."); }
public static async Task LoadOperationArguments(Program program, OperationArguments operationArguments) { if (program is null) { throw new ArgumentNullException(nameof(program)); } if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } if (operationArguments.TargetUri == null) { program.Die("No host information, unable to continue."); } string value; bool? yesno; if (program.TryReadBoolean(operationArguments, KeyType.ConfigNoLocal, out yesno)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.ConfigNoLocal)} = '{yesno}'."); operationArguments.UseConfigLocal = yesno.Value; } if (program.TryReadBoolean(operationArguments, KeyType.ConfigNoSystem, out yesno)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.ConfigNoSystem)} = '{yesno}'."); operationArguments.UseConfigSystem = yesno.Value; } // Load/re-load the Git configuration after setting the use local/system config values. await operationArguments.LoadConfiguration(); // If a user-agent has been specified in the environment, set it globally. if (program.TryReadString(operationArguments, KeyType.HttpUserAgent, out value)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.HttpUserAgent)} = '{value}'."); Global.UserAgent = value; } // Look for authority settings. if (program.TryReadString(operationArguments, KeyType.Authority, out value)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.Authority)} = '{value}'."); if (Program.ConfigKeyComparer.Equals(value, "MSA") || Program.ConfigKeyComparer.Equals(value, "Microsoft") || Program.ConfigKeyComparer.Equals(value, "MicrosoftAccount") || Program.ConfigKeyComparer.Equals(value, "Live") || Program.ConfigKeyComparer.Equals(value, "LiveConnect") || Program.ConfigKeyComparer.Equals(value, "LiveID")) { operationArguments.Authority = AuthorityType.MicrosoftAccount; } else if (Program.ConfigKeyComparer.Equals(value, "AAD") || Program.ConfigKeyComparer.Equals(value, "Azure") || Program.ConfigKeyComparer.Equals(value, "AzureDirectory")) { operationArguments.Authority = AuthorityType.AzureDirectory; } else if (Program.ConfigKeyComparer.Equals(value, "Integrated") || Program.ConfigKeyComparer.Equals(value, "Windows") || Program.ConfigKeyComparer.Equals(value, "TFS") || Program.ConfigKeyComparer.Equals(value, "Kerberos") || Program.ConfigKeyComparer.Equals(value, "NTLM") || Program.ConfigKeyComparer.Equals(value, "SSO")) { operationArguments.Authority = AuthorityType.Ntlm; } else if (Program.ConfigKeyComparer.Equals(value, "GitHub")) { operationArguments.Authority = AuthorityType.GitHub; } else if (Program.ConfigKeyComparer.Equals(value, "Atlassian") || Program.ConfigKeyComparer.Equals(value, "Bitbucket")) { operationArguments.Authority = AuthorityType.Bitbucket; } else { operationArguments.Authority = AuthorityType.Basic; } } // Look for interactivity config settings. if (program.TryReadString(operationArguments, KeyType.Interactive, out value)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.Interactive)} = '{value}'."); if (Program.ConfigKeyComparer.Equals(value, "always") || Program.ConfigKeyComparer.Equals(value, "true") || Program.ConfigKeyComparer.Equals(value, "force")) { operationArguments.Interactivity = Interactivity.Always; } else if (Program.ConfigKeyComparer.Equals(value, "never") || Program.ConfigKeyComparer.Equals(value, "false")) { operationArguments.Interactivity = Interactivity.Never; } } // Look for credential validation config settings. if (program.TryReadBoolean(operationArguments, KeyType.Validate, out yesno)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.Validate)} = '{yesno}'."); operationArguments.ValidateCredentials = yesno.Value; } // Look for write log config settings. if (program.TryReadBoolean(operationArguments, KeyType.Writelog, out yesno)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.Writelog)} = '{yesno}'."); operationArguments.WriteLog = yesno.Value; } // Look for modal prompt config settings. if (program.TryReadBoolean(operationArguments, KeyType.ModalPrompt, out yesno)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.ModalPrompt)} = '{yesno}'."); operationArguments.UseModalUi = yesno.Value; } // Look for credential preservation config settings. if (program.TryReadBoolean(operationArguments, KeyType.PreserveCredentials, out yesno)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.PreserveCredentials)} = '{yesno}'."); operationArguments.PreserveCredentials = yesno.Value; } else if (operationArguments.EnvironmentVariables.TryGetValue("GCM_PRESERVE_CREDS", out value)) { if (StringComparer.OrdinalIgnoreCase.Equals(value, "true") || StringComparer.OrdinalIgnoreCase.Equals(value, "yes") || StringComparer.OrdinalIgnoreCase.Equals(value, "1") || StringComparer.OrdinalIgnoreCase.Equals(value, "on")) { program.Trace.WriteLine($"GCM_PRESERVE_CREDS = '{yesno}'."); operationArguments.PreserveCredentials = true; program.Trace.WriteLine($"WARNING: the 'GCM_PRESERVE_CREDS' variable has been deprecated, use '{ program.KeyTypeName(KeyType.PreserveCredentials) }' instead."); } } // Look for HTTP path usage config settings. if (program.TryReadBoolean(operationArguments, KeyType.HttpPath, out yesno)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.HttpPath)} = '{value}'."); operationArguments.UseHttpPath = yesno.Value; } // Look for HTTP proxy config settings. if ((operationArguments.TargetUri.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase) && program.TryReadString(operationArguments, KeyType.HttpsProxy, out value)) || program.TryReadString(operationArguments, KeyType.HttpProxy, out value)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.HttpProxy)} = '{value}'."); operationArguments.SetProxy(value); } // Check environment variables just-in-case. else if ((operationArguments.EnvironmentVariables.TryGetValue("GCM_HTTP_PROXY", out value) && !string.IsNullOrWhiteSpace(value))) { program.Trace.WriteLine($"GCM_HTTP_PROXY = '{value}'."); var keyName = (operationArguments.TargetUri.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) ? "HTTPS_PROXY" : "HTTP_PROXY"; var warning = $"WARNING: the 'GCM_HTTP_PROXY' variable has been deprecated, use '{ keyName }' instead."; program.Trace.WriteLine(warning); program.WriteLine(warning); operationArguments.SetProxy(value); } // Check the git-config http.proxy setting just-in-case. else { Git.Configuration.Entry entry; if (operationArguments.GitConfiguration.TryGetEntry("http", operationArguments.QueryUri, "proxy", out entry) && !string.IsNullOrWhiteSpace(entry.Value)) { program.Trace.WriteLine($"http.proxy = '{entry.Value}'."); operationArguments.SetProxy(entry.Value); } } // Look for custom namespace config settings. if (program.TryReadString(operationArguments, KeyType.Namespace, out value)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.Namespace)} = '{value}'."); operationArguments.CustomNamespace = value; } // Look for custom token duration settings. if (program.TryReadString(operationArguments, KeyType.TokenDuration, out value)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.TokenDuration)} = '{value}'."); int hours; if (int.TryParse(value, out hours)) { operationArguments.TokenDuration = TimeSpan.FromHours(hours); } } // Look for custom VSTS scope settings. if (program.TryReadString(operationArguments, KeyType.VstsScope, out value)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.VstsScope)} = '{value}'."); VstsTokenScope vstsTokenScope = VstsTokenScope.None; var scopes = value.Split(TokenScopeSeparatorCharacters.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < scopes.Length; i += 1) { scopes[i] = scopes[i].Trim(); if (VstsTokenScope.Find(scopes[i], out VstsTokenScope scope)) { vstsTokenScope = vstsTokenScope | scope; } else { program.Trace.WriteLine($"Unknown VSTS Token scope: '{scopes[i]}'."); } } operationArguments.VstsTokenScope = vstsTokenScope; } // Check for configuration supplied user-info. if (program.TryReadString(operationArguments, KeyType.Username, out value)) { program.Trace.WriteLine($"{program.KeyTypeName(KeyType.Username)} = '{value}'."); operationArguments.Username = value; } }
public static async Task <Credential> QueryCredentials(Program program, OperationArguments operationArguments) { if (program is null) { throw new ArgumentNullException(nameof(program)); } if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } if (operationArguments.TargetUri is null) { var innerException = new NullReferenceException($"{operationArguments.TargetUri} cannot be null."); throw new ArgumentException(innerException.Message, nameof(operationArguments), innerException); } BaseAuthentication authentication = await program.CreateAuthentication(operationArguments); Credential credentials = null; switch (operationArguments.Authority) { default: case AuthorityType.Basic: { var basicAuth = authentication as BasicAuthentication; // Attempt to get cached credentials or acquire credentials if interactivity is allowed. if ((operationArguments.Interactivity != Interactivity.Always && (credentials = await authentication.GetCredentials(operationArguments.TargetUri)) != null) || (operationArguments.Interactivity != Interactivity.Never && (credentials = await basicAuth.AcquireCredentials(operationArguments.TargetUri)) != null)) { program.Trace.WriteLine("credentials found."); // No need to save the credentials explicitly, as Git will call back // with a store command if the credentials are valid. } else { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.AzureDirectory: { var aadAuth = authentication as VstsAadAuthentication; var patOptions = new PersonalAccessTokenOptions() { RequireCompactToken = true, TokenDuration = operationArguments.TokenDuration, TokenScope = null, }; // Attempt to get cached credentials -> non-interactive logon -> interactive // logon note that AAD "credentials" are always scoped access tokens. if (((operationArguments.Interactivity != Interactivity.Always && ((credentials = await aadAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) || (operationArguments.Interactivity != Interactivity.Always && ((credentials = await aadAuth.NoninteractiveLogon(operationArguments.TargetUri, patOptions)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await aadAuth.InteractiveLogon(operationArguments.TargetUri, patOptions)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); program.LogEvent($"Azure Directory credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve Azure Directory credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.MicrosoftAccount: { var msaAuth = authentication as VstsMsaAuthentication; var patOptions = new PersonalAccessTokenOptions() { RequireCompactToken = true, TokenDuration = operationArguments.TokenDuration, TokenScope = null, }; // Attempt to get cached credentials -> interactive logon note that MSA // "credentials" are always scoped access tokens. if (((operationArguments.Interactivity != Interactivity.Always && ((credentials = await msaAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await msaAuth.InteractiveLogon(operationArguments.TargetUri, patOptions)) != null) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); program.LogEvent($"Microsoft Live credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve Microsoft Live credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.GitHub: { var ghAuth = authentication as Github.Authentication; if ((operationArguments.Interactivity != Interactivity.Always && ((credentials = await ghAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await ghAuth.InteractiveLogon(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); program.LogEvent($"GitHub credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); program.LogEvent($"Failed to retrieve GitHub credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.Bitbucket: { var bbcAuth = authentication as Bitbucket.Authentication; if (((operationArguments.Interactivity != Interactivity.Always) && ((credentials = await bbcAuth.GetCredentials(operationArguments.TargetUri, operationArguments.Username)) != null) && (!operationArguments.ValidateCredentials || ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.Username, credentials)) != null))) || ((operationArguments.Interactivity != Interactivity.Never) && ((credentials = await bbcAuth.InteractiveLogon(operationArguments.TargetUri, operationArguments.Username)) != null) && (!operationArguments.ValidateCredentials || ((credentials = await bbcAuth.ValidateCredentials(operationArguments.TargetUri, operationArguments.Username, credentials)) != null)))) { program.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); // Bitbucket relies on a username + secret, so make sure there is a // username to return. if (operationArguments.Username != null) { credentials = new Credential(operationArguments.Username, credentials.Password); } program.LogEvent($"Bitbucket credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { program.LogEvent($"Failed to retrieve Bitbucket credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } } break; case AuthorityType.Ntlm: { program.Trace.WriteLine($"'{operationArguments.TargetUri}' is NTLM."); credentials = BasicAuthentication.NtlmCredentials; } break; } if (credentials != null) { operationArguments.Credentials = credentials; } return(credentials); }
private static bool TryReadBoolean(OperationArguments operationArguments, string configKey, string environKey, out bool? value) { if (ReferenceEquals(operationArguments, null)) throw new ArgumentNullException(nameof(operationArguments)); var envars = operationArguments.EnvironmentVariables; // look for an entry in the environment variables string localVal = null; if (!String.IsNullOrWhiteSpace(environKey) && envars.TryGetValue(environKey, out localVal) && !String.IsNullOrWhiteSpace(localVal)) { goto parse_localval; } var config = operationArguments.GitConfiguration; // look for an entry in the git config Configuration.Entry entry; if (!String.IsNullOrWhiteSpace(configKey) && config.TryGetEntry(ConfigPrefix, operationArguments.QueryUri, configKey, out entry) && !String.IsNullOrWhiteSpace(entry.Value)) { goto parse_localval; } // parse the value into a bool parse_localval: bool result; if (bool.TryParse(localVal, out result)) { value = result; return true; } else { if (ConfigValueComparer.Equals(localVal, "no")) { value = false; return true; } else if (ConfigValueComparer.Equals(localVal, "yes")) { value = true; return true; } } value = null; return false; }
private static bool QueryCredentials(OperationArguments operationArguments) { const string AadMsaAuthFailureMessage = "Logon failed, use ctrl+c to cancel basic credential prompt."; const string BasicAuthFaulureMessage = "Logon failed, use ctrl+c to cancel basic credential prompt."; const string GitHubAuthFailureMessage = "Logon failed, use ctrl+c to cancel basic credential prompt."; if (ReferenceEquals(operationArguments, null)) throw new ArgumentNullException("operationArguments"); if (ReferenceEquals(operationArguments.TargetUri, null)) throw new ArgumentNullException("operationArguments.TargetUri"); bool credentialsFound = false; BaseAuthentication authentication = CreateAuthentication(operationArguments); Credential credentials = null; switch (operationArguments.Authority) { default: case AuthorityType.Basic: { BasicAuthentication basicAuth = authentication as BasicAuthentication; Task.Run(async () => { // attempt to get cached creds or acquire creds if interactivity is allowed if ((operationArguments.Interactivity != Interactivity.Always && (credentials = authentication.GetCredentials(operationArguments.TargetUri)) != null) || (operationArguments.Interactivity != Interactivity.Never && (credentials = await basicAuth.AcquireCredentials(operationArguments.TargetUri)) != null)) { Git.Trace.WriteLine("credentials found."); // set the credentials object // no need to save the credentials explicitly, as Git will call back // with a store command if the credentials are valid. operationArguments.SetCredentials(credentials); credentialsFound = true; } else { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); Program.WriteLine(BasicAuthFaulureMessage); LogEvent($"Failed to retrieve credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } }).Wait(); } break; case AuthorityType.AzureDirectory: { VstsAadAuthentication aadAuth = authentication as VstsAadAuthentication; Task.Run(async () => { // attempt to get cached creds -> non-interactive logon -> interactive logon // note that AAD "credentials" are always scoped access tokens if (((operationArguments.Interactivity != Interactivity.Always && ((credentials = aadAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) || (operationArguments.Interactivity != Interactivity.Always && ((credentials = await aadAuth.NoninteractiveLogon(operationArguments.TargetUri, true)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await aadAuth.InteractiveLogon(operationArguments.TargetUri, true)) != null) && (!operationArguments.ValidateCredentials || await aadAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); operationArguments.SetCredentials(credentials); credentialsFound = true; LogEvent($"Azure Directory credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); Program.WriteLine(AadMsaAuthFailureMessage); LogEvent($"Failed to retrieve Azure Directory credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } }).Wait(); } break; case AuthorityType.MicrosoftAccount: { VstsMsaAuthentication msaAuth = authentication as VstsMsaAuthentication; Task.Run(async () => { // attempt to get cached creds -> interactive logon // note that MSA "credentials" are always scoped access tokens if (((operationArguments.Interactivity != Interactivity.Always && ((credentials = msaAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await msaAuth.InteractiveLogon(operationArguments.TargetUri, true)) != null) && (!operationArguments.ValidateCredentials || await msaAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); operationArguments.SetCredentials(credentials); credentialsFound = true; LogEvent($"Microsoft Live credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); Program.WriteLine(AadMsaAuthFailureMessage); LogEvent($"Failed to retrieve Microsoft Live credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } }).Wait(); } break; case AuthorityType.GitHub: { GitHubAuthentication ghAuth = authentication as GitHubAuthentication; Task.Run(async () => { if ((operationArguments.Interactivity != Interactivity.Always && ((credentials = ghAuth.GetCredentials(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials))) || (operationArguments.Interactivity != Interactivity.Never && ((credentials = await ghAuth.InteractiveLogon(operationArguments.TargetUri)) != null) && (!operationArguments.ValidateCredentials || await ghAuth.ValidateCredentials(operationArguments.TargetUri, credentials)))) { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' found."); operationArguments.SetCredentials(credentials); credentialsFound = true; LogEvent($"GitHub credentials for '{operationArguments.TargetUri}' successfully retrieved.", EventLogEntryType.SuccessAudit); } else { Git.Trace.WriteLine($"credentials for '{operationArguments.TargetUri}' not found."); Program.WriteLine(GitHubAuthFailureMessage); LogEvent($"Failed to retrieve GitHub credentials for '{operationArguments.TargetUri}'.", EventLogEntryType.FailureAudit); } }).Wait(); } break; case AuthorityType.Ntlm: { Git.Trace.WriteLine($"'{operationArguments.TargetUri}' is NTLM."); operationArguments.SetCredentials(BasicAuthentication.NtlmCredentials); credentialsFound = true; } break; } return credentialsFound; }
private static bool TryReadString(OperationArguments operationArguments, string configKey, string environKey, out string value) { if (ReferenceEquals(operationArguments, null)) throw new ArgumentNullException(nameof(operationArguments)); var envars = operationArguments.EnvironmentVariables; // look for an entry in the environment variables string localVal; if (!String.IsNullOrWhiteSpace(environKey) && envars.TryGetValue(environKey, out localVal) && !String.IsNullOrWhiteSpace(localVal)) { value = localVal; return true; } var config = operationArguments.GitConfiguration; // look for an entry in the git config Configuration.Entry entry; if (!String.IsNullOrWhiteSpace(configKey) && config.TryGetEntry(ConfigPrefix, operationArguments.QueryUri, configKey, out entry) && !String.IsNullOrWhiteSpace(entry.Value)) { value = entry.Value; return true; } value = null; return false; }
private static BaseAuthentication CreateAuthentication(OperationArguments operationArguments) { Debug.Assert(operationArguments != null, "The operationArguments is null"); Debug.Assert(operationArguments.TargetUri != null, "The operationArgument.TargetUri is null"); var secretsNamespace = operationArguments.CustomNamespace ?? SecretsNamespace; var secrets = new SecretStore(secretsNamespace, null, null, Secret.UriToName); BaseAuthentication authority = null; var basicCredentialCallback = (operationArguments.UseModalUi) ? new AcquireCredentialsDelegate(Program.ModalPromptForCredentials) : new AcquireCredentialsDelegate(Program.BasicCredentialPrompt); var githubCredentialCallback = (operationArguments.UseModalUi) ? new GitHubAuthentication.AcquireCredentialsDelegate(GitHub.Authentication.AuthenticationPrompts.CredentialModalPrompt) : new GitHubAuthentication.AcquireCredentialsDelegate(Program.GitHubCredentialPrompt); var githubAuthcodeCallback = (operationArguments.UseModalUi) ? new GitHubAuthentication.AcquireAuthenticationCodeDelegate(GitHub.Authentication.AuthenticationPrompts.AuthenticationCodeModalPrompt) : new GitHubAuthentication.AcquireAuthenticationCodeDelegate(Program.GitHubAuthCodePrompt); NtlmSupport basicNtlmSupport = NtlmSupport.Auto; switch (operationArguments.Authority) { case AuthorityType.Auto: Git.Trace.WriteLine($"detecting authority type for '{operationArguments.TargetUri}'."); // detect the authority authority = BaseVstsAuthentication.GetAuthentication(operationArguments.TargetUri, VstsCredentialScope, secrets) ?? GitHubAuthentication.GetAuthentication(operationArguments.TargetUri, GitHubCredentialScope, secrets, githubCredentialCallback, githubAuthcodeCallback, null); if (authority != null) { // set the authority type based on the returned value if (authority is VstsMsaAuthentication) { operationArguments.Authority = AuthorityType.MicrosoftAccount; goto case AuthorityType.MicrosoftAccount; } else if (authority is VstsAadAuthentication) { operationArguments.Authority = AuthorityType.AzureDirectory; goto case AuthorityType.AzureDirectory; } else if (authority is GitHubAuthentication) { operationArguments.Authority = AuthorityType.GitHub; goto case AuthorityType.GitHub; } } operationArguments.Authority = AuthorityType.Basic; goto case AuthorityType.Basic; case AuthorityType.AzureDirectory: Git.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is Azure Directory."); Guid tenantId = Guid.Empty; // return the allocated authority or a generic AAD backed VSTS authentication object return authority ?? new VstsAadAuthentication(Guid.Empty, VstsCredentialScope, secrets); case AuthorityType.Basic: // enforce basic authentication only basicNtlmSupport = NtlmSupport.Never; goto default; case AuthorityType.GitHub: Git.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is GitHub."); // return a GitHub authentication object return authority ?? new GitHubAuthentication(GitHubCredentialScope, secrets, githubCredentialCallback, githubAuthcodeCallback, null); case AuthorityType.MicrosoftAccount: Git.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is Microsoft Live."); // return the allocated authority or a generic MSA backed VSTS authentication object return authority ?? new VstsMsaAuthentication(VstsCredentialScope, secrets); case AuthorityType.Ntlm: // enforce NTLM authentication only basicNtlmSupport = NtlmSupport.Always; goto default; default: Git.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is basic with NTLM={basicNtlmSupport}."); // return a generic username + password authentication object return authority ?? new BasicAuthentication(secrets, basicNtlmSupport, basicCredentialCallback, null); } }
private static void DeleteCredentials(OperationArguments operationArguments) { if (ReferenceEquals(operationArguments, null)) throw new ArgumentNullException("operationArguments"); BaseAuthentication authentication = CreateAuthentication(operationArguments); switch (operationArguments.Authority) { default: case AuthorityType.Basic: Git.Trace.WriteLine($"deleting basic credentials for '{operationArguments.TargetUri}'."); authentication.DeleteCredentials(operationArguments.TargetUri); break; case AuthorityType.AzureDirectory: case AuthorityType.MicrosoftAccount: Git.Trace.WriteLine($"deleting VSTS credentials for '{operationArguments.TargetUri}'."); BaseVstsAuthentication vstsAuth = authentication as BaseVstsAuthentication; vstsAuth.DeleteCredentials(operationArguments.TargetUri); break; case AuthorityType.GitHub: Git.Trace.WriteLine($"deleting GitHub credentials for '{operationArguments.TargetUri}'."); GitHubAuthentication ghAuth = authentication as GitHubAuthentication; ghAuth.DeleteCredentials(operationArguments.TargetUri); break; } }
private static void EnableTraceLogging(OperationArguments operationArguments) { if (operationArguments.WriteLog) { Git.Trace.WriteLine("trace logging enabled."); string gitConfigPath; if (Where.GitLocalConfig(out gitConfigPath)) { Git.Trace.WriteLine($"git local config found at '{gitConfigPath}'."); string gitDirPath = Path.GetDirectoryName(gitConfigPath); if (Directory.Exists(gitDirPath)) { EnableTraceLogging(operationArguments, gitDirPath); } } else if (Where.GitGlobalConfig(out gitConfigPath)) { Git.Trace.WriteLine($"git global config found at '{gitConfigPath}'."); string homeDirPath = Path.GetDirectoryName(gitConfigPath); if (Directory.Exists(homeDirPath)) { EnableTraceLogging(operationArguments, homeDirPath); } } } }
private static void EnableTraceLogging(OperationArguments operationArguments, string logFilePath) { const int LogFileMaxLength = 8 * 1024 * 1024; // 8 MB string logFileName = Path.Combine(logFilePath, Path.ChangeExtension(ConfigPrefix, ".log")); FileInfo logFileInfo = new FileInfo(logFileName); if (logFileInfo.Exists && logFileInfo.Length > LogFileMaxLength) { for (int i = 1; i < Int32.MaxValue; i++) { string moveName = String.Format("{0}{1:000}.log", ConfigPrefix, i); string movePath = Path.Combine(logFilePath, moveName); if (!File.Exists(movePath)) { logFileInfo.MoveTo(movePath); break; } } } Git.Trace.WriteLine($"trace log destination is '{logFilePath}'."); var fileStream = File.Open(logFileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite); var listener = new StreamWriter(fileStream, Encoding.UTF8); Git.Trace.AddListener(listener); // write a small header to help with identifying new log entries listener.Write('\n'); listener.Write($"{DateTime.Now:YYYY.MM.dd HH:mm:ss} Microsoft {Program.Title} version {Version.ToString(3)}\n"); }
public static async Task <BaseAuthentication> CreateAuthentication(Program program, OperationArguments operationArguments) { if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } if (operationArguments.TargetUri is null) { var innerException = new NullReferenceException($"`{operationArguments.TargetUri}` cannot be null."); throw new ArgumentException(innerException.Message, nameof(operationArguments), innerException); } var secretsNamespace = operationArguments.CustomNamespace ?? Program.SecretsNamespace; BaseAuthentication authority = null; var basicCredentialCallback = (operationArguments.UseModalUi) ? new AcquireCredentialsDelegate(program.ModalPromptForCredentials) : new AcquireCredentialsDelegate(program.BasicCredentialPrompt); var bitbucketPrompts = new Bitbucket.AuthenticationPrompts(program.Context); var bitbucketCredentialCallback = (operationArguments.UseModalUi) ? bitbucketPrompts.CredentialModalPrompt : new Bitbucket.Authentication.AcquireCredentialsDelegate(program.BitbucketCredentialPrompt); var bitbucketOauthCallback = (operationArguments.UseModalUi) ? bitbucketPrompts.AuthenticationOAuthModalPrompt : new Bitbucket.Authentication.AcquireAuthenticationOAuthDelegate(program.BitbucketOAuthPrompt); var githubPrompts = new Github.AuthenticationPrompts(program.Context); var githubCredentialCallback = (operationArguments.UseModalUi) ? new Github.Authentication.AcquireCredentialsDelegate(githubPrompts.CredentialModalPrompt) : new Github.Authentication.AcquireCredentialsDelegate(program.GitHubCredentialPrompt); var githubAuthcodeCallback = (operationArguments.UseModalUi) ? new Github.Authentication.AcquireAuthenticationCodeDelegate(githubPrompts.AuthenticationCodeModalPrompt) : new Github.Authentication.AcquireAuthenticationCodeDelegate(program.GitHubAuthCodePrompt); NtlmSupport basicNtlmSupport = NtlmSupport.Auto; switch (operationArguments.Authority) { case AuthorityType.Auto: program.Trace.WriteLine($"detecting authority type for '{operationArguments.TargetUri}'."); // Detect the authority. authority = await BaseVstsAuthentication.GetAuthentication(program.Context, operationArguments.TargetUri, Program.VstsCredentialScope, new SecretStore(program.Context, secretsNamespace, BaseVstsAuthentication.UriNameConversion)) ?? Github.Authentication.GetAuthentication(program.Context, operationArguments.TargetUri, Program.GitHubCredentialScope, new SecretStore(program.Context, secretsNamespace, Secret.UriToName), githubCredentialCallback, githubAuthcodeCallback, null) ?? Bitbucket.Authentication.GetAuthentication(program.Context, operationArguments.TargetUri, new SecretStore(program.Context, secretsNamespace, Secret.UriToIdentityUrl), bitbucketCredentialCallback, bitbucketOauthCallback); if (authority != null) { // Set the authority type based on the returned value. if (authority is VstsMsaAuthentication) { operationArguments.Authority = AuthorityType.MicrosoftAccount; goto case AuthorityType.MicrosoftAccount; } else if (authority is VstsAadAuthentication) { operationArguments.Authority = AuthorityType.AzureDirectory; goto case AuthorityType.AzureDirectory; } else if (authority is Github.Authentication) { operationArguments.Authority = AuthorityType.GitHub; goto case AuthorityType.GitHub; } else if (authority is Bitbucket.Authentication) { operationArguments.Authority = AuthorityType.Bitbucket; goto case AuthorityType.Bitbucket; } } goto default; case AuthorityType.AzureDirectory: program.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is Azure Directory."); Guid tenantId = Guid.Empty; // Get the identity of the tenant. var result = await BaseVstsAuthentication.DetectAuthority(program.Context, operationArguments.TargetUri); if (result.HasValue) { tenantId = result.Value; } // Return the allocated authority or a generic AAD backed VSTS authentication object. return(authority ?? new VstsAadAuthentication(program.Context, tenantId, operationArguments.VstsTokenScope, new SecretStore(program.Context, secretsNamespace, VstsAadAuthentication.UriNameConversion))); case AuthorityType.Basic: // Enforce basic authentication only. basicNtlmSupport = NtlmSupport.Never; goto default; case AuthorityType.GitHub: program.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is GitHub."); // Return a GitHub authentication object. return(authority ?? new Github.Authentication(program.Context, operationArguments.TargetUri, Program.GitHubCredentialScope, new SecretStore(program.Context, secretsNamespace, Secret.UriToName), githubCredentialCallback, githubAuthcodeCallback, null)); case AuthorityType.Bitbucket: program.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is Bitbucket"); // Return a Bitbucket authentication object. return(authority ?? new Bitbucket.Authentication(program.Context, new SecretStore(program.Context, secretsNamespace, Secret.UriToIdentityUrl), bitbucketCredentialCallback, bitbucketOauthCallback)); case AuthorityType.MicrosoftAccount: program.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is Microsoft Live."); // Return the allocated authority or a generic MSA backed VSTS authentication object. return(authority ?? new VstsMsaAuthentication(program.Context, operationArguments.VstsTokenScope, new SecretStore(program.Context, secretsNamespace, VstsMsaAuthentication.UriNameConversion))); case AuthorityType.Ntlm: // Enforce NTLM authentication only. basicNtlmSupport = NtlmSupport.Always; goto default; default: program.Trace.WriteLine($"authority for '{operationArguments.TargetUri}' is basic with NTLM={basicNtlmSupport}."); // Return a generic username + password authentication object. return(authority ?? new BasicAuthentication(program.Context, new SecretStore(program.Context, secretsNamespace, Secret.UriToIdentityUrl), basicNtlmSupport, basicCredentialCallback, null)); } }
internal void EnableTraceLogging(OperationArguments operationArguments, string logFilePath) => _enableTraceLoggingFile(this, operationArguments, logFilePath);
public static bool TryReadBoolean(Program program, OperationArguments operationArguments, KeyType key, out bool?value) { if (operationArguments is null) { throw new ArgumentNullException(nameof(operationArguments)); } if (program.ConfigurationKeys.TryGetValue(key, out string configKey) | program.EnvironmentKeys.TryGetValue(key, out string environKey)) { var envars = operationArguments.EnvironmentVariables; // Look for an entry in the environment variables. string localVal = null; if (!string.IsNullOrWhiteSpace(environKey) && envars.TryGetValue(environKey, out localVal)) { goto parse_localval; } var config = operationArguments.GitConfiguration; // Look for an entry in the git config. Git.Configuration.Entry entry; if (!string.IsNullOrWhiteSpace(configKey) && config.TryGetEntry(Program.ConfigPrefix, operationArguments.QueryUri, configKey, out entry)) { localVal = entry.Value; goto parse_localval; } // Parse the value into a bool. parse_localval: // An empty value is unset / should not be there, so treat it as if it isn't. if (string.IsNullOrWhiteSpace(localVal)) { value = null; return(false); } // Test `localValue` for a Git 'true' equivalent value. if (Program.ConfigValueComparer.Equals(localVal, "yes") || Program.ConfigValueComparer.Equals(localVal, "true") || Program.ConfigValueComparer.Equals(localVal, "1") || Program.ConfigValueComparer.Equals(localVal, "on")) { value = true; return(true); } // Test `localValue` for a Git 'false' equivalent value. if (Program.ConfigValueComparer.Equals(localVal, "no") || Program.ConfigValueComparer.Equals(localVal, "false") || Program.ConfigValueComparer.Equals(localVal, "0") || Program.ConfigValueComparer.Equals(localVal, "off")) { value = false; return(true); } } value = null; return(false); }
internal void ReadGitRemoteDetails(OperationArguments operationArguments) => _readGitRemoteDetails(this, operationArguments);
internal void Config() { string[] args = Environment.GetCommandLineArgs(); // Attempt to parse a target URI from the command line arguments. if (args.Length < 3 || !Uri.TryCreate(args[2], UriKind.Absolute, out Uri targetUri)) { targetUri = new Uri("file://localhost"); } // Create operation arguments, and load configuration data. OperationArguments operationArguments = new OperationArguments(targetUri); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); // Create a set of irrelevant environment variable entries. var irrelevantEntries = new HashSet <string>(StringComparer.OrdinalIgnoreCase) { "ToastSettings" }; // Write out the environment variables. WriteLine("Environment Variables:"); foreach (var entry in operationArguments.EnvironmentVariables) { // Skip well-known, irrelevant entries. if (irrelevantEntries.Contains(entry.Key)) { continue; } WriteLine($" {entry.Key} = {entry.Value}"); } WriteLine(); // Write out the Git configuration. WriteLine("Git Configuration:"); foreach (var entry in operationArguments.GitConfiguration) { WriteLine($" [{entry.Level}] {entry.Key} = {entry.Value}"); } WriteLine(); // Write out the effective settings for GCM. WriteLine($"Effective Manager Configuration for {operationArguments.QueryUri.ToString()}:"); WriteLine($" Executable = {AssemblyTitle} v{Version.ToString(4)} ({ExecutablePath})"); WriteLine($" Authority = {operationArguments.Authority}"); WriteLine($" CustomNamespace = {operationArguments.CustomNamespace}"); WriteLine($" Interactivity = {operationArguments.Interactivity}"); WriteLine($" PreserveCredentials = {operationArguments.PreserveCredentials}"); WriteLine($" QueryUri = {operationArguments.QueryUri}"); WriteLine($" TargetUri = {operationArguments.TargetUri}"); WriteLine($" TokenDuration = {operationArguments.TokenDuration}"); WriteLine($" UseConfigLocal = {operationArguments.UseConfigLocal}"); WriteLine($" UseConfigSystem = {operationArguments.UseConfigSystem}"); WriteLine($" UseHttpPath = {operationArguments.UseHttpPath}"); WriteLine($" UseModalUi = {operationArguments.UseModalUi}"); WriteLine($" ValidateCredentials = {operationArguments.ValidateCredentials}"); WriteLine($" WriteLog = {operationArguments.WriteLog}"); }
internal bool TryReadBoolean(OperationArguments operationArguments, KeyType key, out bool?value) => _tryReadBoolean(this, operationArguments, key, out value);
internal bool TryReadString(OperationArguments operationArguments, KeyType key, out string value) => _tryReadString(this, operationArguments, key, out value);
private static void LoadOperationArguments(OperationArguments operationArguments) { if (operationArguments.TargetUri == null) { Die("No host information, unable to continue."); } string value; bool? yesno; if (TryReadBoolean(operationArguments, null, EnvironConfigNoLocalKey, out yesno)) { operationArguments.UseConfigLocal = yesno.Value; } if (TryReadBoolean(operationArguments, null, EnvironConfigNoSystemKey, out yesno)) { operationArguments.UseConfigSystem = yesno.Value; } // load/re-load the Git configuration after setting the use local/system config values operationArguments.LoadConfiguration(); // if a user-agent has been specified in the environment, set it globally if (TryReadString(operationArguments, null, EnvironHttpUserAgent, out value)) { Global.UserAgent = value; } // look for authority settings if (TryReadString(operationArguments, ConfigAuthortyKey, EnvironAuthorityKey, out value)) { Git.Trace.WriteLine($"{ConfigAuthortyKey} = '{value}'."); if (ConfigKeyComparer.Equals(value, "MSA") || ConfigKeyComparer.Equals(value, "Microsoft") || ConfigKeyComparer.Equals(value, "MicrosoftAccount") || ConfigKeyComparer.Equals(value, "Live") || ConfigKeyComparer.Equals(value, "LiveConnect") || ConfigKeyComparer.Equals(value, "LiveID")) { operationArguments.Authority = AuthorityType.MicrosoftAccount; } else if (ConfigKeyComparer.Equals(value, "AAD") || ConfigKeyComparer.Equals(value, "Azure") || ConfigKeyComparer.Equals(value, "AzureDirectory")) { operationArguments.Authority = AuthorityType.AzureDirectory; } else if (ConfigKeyComparer.Equals(value, "Integrated") || ConfigKeyComparer.Equals(value, "Windows") || ConfigKeyComparer.Equals(value, "TFS") || ConfigKeyComparer.Equals(value, "Kerberos") || ConfigKeyComparer.Equals(value, "NTLM") || ConfigKeyComparer.Equals(value, "SSO")) { operationArguments.Authority = AuthorityType.Ntlm; } else if (ConfigKeyComparer.Equals(value, "GitHub")) { operationArguments.Authority = AuthorityType.GitHub; } else { operationArguments.Authority = AuthorityType.Basic; } } // look for interactivity config settings if (TryReadString(operationArguments, ConfigInteractiveKey, EnvironInteractiveKey, out value)) { Git.Trace.WriteLine($"{EnvironInteractiveKey} = '{value}'."); if (ConfigKeyComparer.Equals(value, "always") || ConfigKeyComparer.Equals(value, "true") || ConfigKeyComparer.Equals(value, "force")) { operationArguments.Interactivity = Interactivity.Always; } else if (ConfigKeyComparer.Equals(value, "never") || ConfigKeyComparer.Equals(value, "false")) { operationArguments.Interactivity = Interactivity.Never; } } // look for credential validation config settings if (TryReadBoolean(operationArguments, ConfigValidateKey, EnvironValidateKey, out yesno)) { operationArguments.ValidateCredentials = yesno.Value; } // look for write log config settings if (TryReadBoolean(operationArguments, ConfigWritelogKey, EnvironWritelogKey, out yesno)) { operationArguments.WriteLog = yesno.Value; } // look for modal prompt config settings if (TryReadBoolean(operationArguments, ConfigUseModalPromptKey, EnvironModalPromptKey, out yesno)) { operationArguments.UseModalUi = yesno.Value; } // look for credential preservation config settings if (TryReadBoolean(operationArguments, ConfigPreserveCredentialsKey, EnvironPreserveCredentialsKey, out yesno)) { operationArguments.PreserveCredentials = yesno.Value; } // look for http path usage config settings if (TryReadBoolean(operationArguments, ConfigUseHttpPathKey, null, out yesno)) { operationArguments.UseHttpPath = yesno.Value; } // look for http proxy config settings if (TryReadString(operationArguments, ConfigHttpProxyKey, EnvironHttpProxyKey, out value)) { Git.Trace.WriteLine($"{ConfigHttpProxyKey} = '{value}'."); operationArguments.SetProxy(value); } else { // check the git-config http.proxy setting just-in-case Configuration.Entry entry; if (operationArguments.GitConfiguration.TryGetEntry("http", operationArguments.QueryUri, "proxy", out entry) && !String.IsNullOrWhiteSpace(entry.Value)) { Git.Trace.WriteLine($"http.proxy = '{entry.Value}'."); operationArguments.SetProxy(entry.Value); } } // look for custom namespace config settings if (TryReadString(operationArguments, ConfigNamespaceKey, EnvironNamespaceKey, out value)) { Git.Trace.WriteLine($"{ConfigNamespaceKey} = '{value}'."); operationArguments.CustomNamespace = value; } }
private static void Clear() { var args = Environment.GetCommandLineArgs(); string url = null; bool forced = false; if (args.Length <= 2) { if (!StandardInputIsTty) { Git.Trace.WriteLine("standard input is not TTY, abandoning prompt."); return; } Git.Trace.WriteLine("prompting user for url."); Program.WriteLine(" Target Url:"); url = Console.In.ReadLine(); } else { url = args[2]; if (args.Length > 3) { bool.TryParse(args[3], out forced); } } Uri uri; if (Uri.TryCreate(url, UriKind.Absolute, out uri)) { Git.Trace.WriteLine($"converted '{url}' to '{uri.AbsoluteUri}'."); OperationArguments operationArguments = new OperationArguments(uri); LoadOperationArguments(operationArguments); EnableTraceLogging(operationArguments); if (operationArguments.PreserveCredentials && !forced) { Git.Trace.WriteLine("attempting to delete preserved credentials without force, prompting user for interactivity."); if (!StandardInputIsTty || !StandardErrorIsTty) { Git.Trace.WriteLine("standard input is not TTY, abandoning prompt."); return; } Program.WriteLine(" credentials are protected by perserve flag, clear anyways? [Y]es, [N]o."); ConsoleKeyInfo key; while ((key = Program.ReadKey(true)).Key != ConsoleKey.Escape) { if (key.KeyChar == 'N' || key.KeyChar == 'n') { return; } if (key.KeyChar == 'Y' || key.KeyChar == 'y') { break; } } } DeleteCredentials(operationArguments); } else { Git.Trace.WriteLine($"unable to parse input '{url}'."); } }
internal Task <bool> DeleteCredentials(OperationArguments operationArguments) => _deleteCredentials(this, operationArguments);