/// <summary> /// <para></para> /// <para>Tokens acquired are stored in the secure secret store provided during /// initialization.</para> /// </summary> /// <param name="targetUri">The unique identifier for the resource for which access is to /// be acquired.</param> /// <param name="username">The username of the account for which access is to be acquired.</param> /// <param name="password">The password of the account for which access is to be acquired.</param> /// <param name="authenticationCode">The two-factor authentication code for use in access acquision.</param> /// <returns>True if success; otherwise false.</returns> public async Task <bool> NoninteractiveLogonWithCredentials(Uri targetUri, string username, string password, string authenticationCode = null) { BaseSecureStore.ValidateTargetUri(targetUri); if (String.IsNullOrWhiteSpace(username)) { throw new ArgumentNullException("username", "The `username` parameter is null or invalid."); } if (String.IsNullOrWhiteSpace(password)) { throw new ArgumentNullException("username", "The `password` parameter is null or invalid."); } Trace.WriteLine("GithubAuthentication::NoninteractiveLogonWithCredentials"); GithubAuthenticationResult result; if (result = await GithubAuthority.AcquireToken(targetUri, username, password, authenticationCode, this.TokenScope)) { Trace.WriteLine(" token aquisition succeeded"); PersonalAccessTokenStore.WriteCredentials(targetUri, (Credential)result.Token); return(true); } Trace.WriteLine(" non-interactive logon failed"); return(false); }
/// <summary> /// <para></para> /// <para>Tokens acquired are stored in the secure secret store provided during /// initialization.</para> /// </summary> /// <param name="targetUri">The unique identifier for the resource for which access is to /// be acquired.</param> /// <param name="credentials">(out) Credentials when acquision is successful; null otherwise.</param> /// <returns>True if success; otherwise false.</returns> public bool InteractiveLogon(Uri targetUri, out Credential credentials) { string username; string password; if (AcquireCredentialsCallback(targetUri, out username, out password)) { GithubAuthenticationResult result; if (result = GithubAuthority.AcquireToken(targetUri, username, password, null, this.TokenScope).Result) { Trace.WriteLine(" token aquisition succeeded"); credentials = (Credential)result.Token; this.PersonalAccessTokenStore.WriteCredentials(targetUri, credentials); // if a result callback was registered, call it if (AuthenticationResultCallback != null) { AuthenticationResultCallback(targetUri, result); } return(true); } else if (result == GithubAuthenticationResultType.TwoFactorApp || result == GithubAuthenticationResultType.TwoFactorSms) { string authenticationCode; if (AcquireAuthenticationCodeCallback(targetUri, result, out authenticationCode)) { if (result = GithubAuthority.AcquireToken(targetUri, username, password, authenticationCode, this.TokenScope).Result) { Trace.WriteLine(" token aquisition succeeded"); credentials = (Credential)result.Token; this.PersonalAccessTokenStore.WriteCredentials(targetUri, credentials); // if a result callback was registered, call it if (AuthenticationResultCallback != null) { AuthenticationResultCallback(targetUri, result); } return(true); } } } // if a result callback was registered, call it if (AuthenticationResultCallback != null) { AuthenticationResultCallback(targetUri, result); } } Trace.WriteLine(" interactive logon failed"); credentials = null; return(false); }
/// <summary> /// <para></para> /// <para>Tokens acquired are stored in the secure secret store provided during /// initialization.</para> /// </summary> /// <param name="targetUri">The unique identifier for the resource for which access is to /// be acquired.</param> /// <param name="credentials">(out) Credentials when acquision is successful; null otherwise.</param> /// <returns>True if success; otherwise false.</returns> public bool InteractiveLogon(Uri targetUri, out Credential credentials) { // ReadConsole 32768 fail, 32767 ok // @linquize [https://github.com/Microsoft/Git-Credential-Manager-for-Windows/commit/a62b9a19f430d038dcd85a610d97e5f763980f85] const int BufferReadSize = 32 * 1024 - 7; StringBuilder buffer = new StringBuilder(BufferReadSize); uint read = 0; uint written = 0; NativeMethods.FileAccess fileAccessFlags = NativeMethods.FileAccess.GenericRead | NativeMethods.FileAccess.GenericWrite; NativeMethods.FileAttributes fileAttributes = NativeMethods.FileAttributes.Normal; NativeMethods.FileCreationDisposition fileCreationDisposition = NativeMethods.FileCreationDisposition.OpenExisting; NativeMethods.FileShare fileShareFlags = NativeMethods.FileShare.Read | NativeMethods.FileShare.Write; using (SafeFileHandle stdout = NativeMethods.CreateFile("CONOUT$", fileAccessFlags, fileShareFlags, IntPtr.Zero, fileCreationDisposition, fileAttributes, IntPtr.Zero)) using (SafeFileHandle stdin = NativeMethods.CreateFile("CONIN$", fileAccessFlags, fileShareFlags, IntPtr.Zero, fileCreationDisposition, fileAttributes, IntPtr.Zero)) { // read the current console mode NativeMethods.ConsoleMode consoleMode; if (!NativeMethods.GetConsoleMode(stdin, out consoleMode)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to determine console mode (" + error + ")."); } // instruct the user as to what they are expected to do buffer.Append("Please enter your GitHub credentials for ") .Append(targetUri.Scheme) .Append("://") .Append(targetUri.DnsSafeHost) .Append("/") .Append(targetUri.PathAndQuery) .AppendLine(); if (!NativeMethods.WriteConsole(stdout, buffer, (uint)buffer.Length, out written, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to write to standard output (" + error + ")."); } // clear the buffer for the next operation buffer.Clear(); // prompt the user for the username wanted buffer.Append("username: "******"Unable to write to standard output (" + error + ")."); } // clear the buffer for the next operation buffer.Clear(); // read input from the user if (!NativeMethods.ReadConsole(stdin, buffer, BufferReadSize, out read, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to read from standard input (" + error + ")."); } // record input from the user into local storage, stripping any eol chars string username = buffer.ToString(0, (int)read); username = username.Trim(Environment.NewLine.ToCharArray()); // clear the buffer for the next operation buffer.Clear(); // set the console mode to current without echo input NativeMethods.ConsoleMode consoleMode2 = consoleMode ^ NativeMethods.ConsoleMode.EchoInput; if (!NativeMethods.SetConsoleMode(stdin, consoleMode2)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to set console mode (" + error + ")."); } // prompt the user for password buffer.Append("password: "******"Unable to write to standard output (" + error + ")."); } // clear the buffer for the next operation buffer.Clear(); // read input from the user if (!NativeMethods.ReadConsole(stdin, buffer, BufferReadSize, out read, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to read from standard input (" + error + ")."); } // record input from the user into local storage, stripping any eol chars string password = buffer.ToString(0, (int)read); password = password.Trim(Environment.NewLine.ToCharArray()); // clear the buffer for the next operation buffer.Clear(); // restore the console mode to its original value if (!NativeMethods.SetConsoleMode(stdin, consoleMode)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to set console mode (" + error + ")."); } GithubAuthenticationResult result; if (result = GithubAuthority.AcquireToken(targetUri, username, password, null, this.TokenScope).Result) { Trace.WriteLine(" token aquisition succeeded"); credentials = (Credential)result.Token; this.PersonalAccessTokenStore.WriteCredentials(targetUri, credentials); return(true); } else if (result == GithubAuthenticationResultType.TwoFactorApp || result == GithubAuthenticationResultType.TwoFactorSms) { buffer.Clear() .AppendLine() .Append("authcode: "); if (!NativeMethods.WriteConsole(stdout, buffer, (uint)buffer.Length, out written, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to write to standard output (" + error + ")."); } buffer.Clear(); // read input from the user if (!NativeMethods.ReadConsole(stdin, buffer, BufferReadSize, out read, IntPtr.Zero)) { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error, "Unable to read from standard input (" + error + ")."); } string authenticationCode = buffer.ToString(0, (int)read); authenticationCode = authenticationCode.Trim(Environment.NewLine.ToCharArray()); if (result = GithubAuthority.AcquireToken(targetUri, username, password, authenticationCode, this.TokenScope).Result) { Trace.WriteLine(" token aquisition succeeded"); credentials = (Credential)result.Token; this.PersonalAccessTokenStore.WriteCredentials(targetUri, credentials); return(true); } } } Trace.WriteLine(" interactive logon failed"); credentials = null; return(false); }