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 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) { 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.UserPromptDialog prompt = new Gui.UserPromptDialog(promptKind, resource); application.Run(prompt); if (!prompt.Failed && !string.IsNullOrEmpty(prompt.Response)) { string passphase = prompt.Response; 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; // only check within the credential portion of the url, don't look past the '@' because the port token // is the same as the username / password seperator. int credentialLength = credentialTerminator - schemeTerminator; credentialLength = Math.Max(0, credentialLength); int passwordTerminator = targetUrl.IndexOf(':', schemeTerminator + 1, credentialLength); 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.Impl(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."); } if ((match = AskAuthenticityRegex.Match(args[0])).Success) { string host = match.Groups[1].Value; string fingerprint = match.Groups[2].Value; Git.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) { Git.Trace.WriteLine("denied authorization of host."); Console.Out.Write("no\n"); } else { Git.Trace.WriteLine("approved authorization of host."); Console.Out.Write("yes\n"); } return; } Git.Trace.WriteLine("failed to acquire credentials."); }