/// <summary>
        /// 
        /// </summary>
        /// <param name="tokenScope"></param>
        /// <param name="personalAccessTokenStore"></param>
        public GithubAuthentication(
            GithubTokenScope tokenScope,
            ICredentialStore personalAccessTokenStore,
            AcquireCredentialsDelegate acquireCredentialsCallback,
            AcquireAuthenticationCodeDelegate acquireAuthenticationCodeCallback,
            AuthenticationResultDelegate authenticationResultCallback)
        {
            if (tokenScope == null)
                throw new ArgumentNullException("tokenScope", "The parameter `tokenScope` is null or invalid.");
            if (personalAccessTokenStore == null)
                throw new ArgumentNullException("personalAccessTokenStore", "The parameter `personalAccessTokenStore` is null or invalid.");
            if (acquireCredentialsCallback == null)
                throw new ArgumentNullException("acquireCredentialsCallback", "The parameter `acquireCredentialsCallback` is null or invalid.");
            if (acquireAuthenticationCodeCallback == null)
                throw new ArgumentNullException("acquireAuthenticationCodeCallback", "The parameter `acquireAuthenticationCodeCallback` is null or invalid.");

            TokenScope = tokenScope;

            PersonalAccessTokenStore = personalAccessTokenStore;
            GithubAuthority = new GithubAuthority();

            AcquireCredentialsCallback = acquireCredentialsCallback;
            AcquireAuthenticationCodeCallback = acquireAuthenticationCodeCallback;
            AuthenticationResultCallback = authenticationResultCallback;
        }
Example #2
0
        /// <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);
        }
Example #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="tokenScope"></param>
        /// <param name="personalAccessTokenStore"></param>
        public GithubAuthentication(
            GithubTokenScope tokenScope,
            ICredentialStore personalAccessTokenStore,
            AcquireCredentialsDelegate acquireCredentialsCallback,
            AcquireAuthenticationCodeDelegate acquireAuthenticationCodeCallback,
            AuthenticationResultDelegate authenticationResultCallback)
        {
            if (tokenScope == null)
            {
                throw new ArgumentNullException("tokenScope", "The parameter `tokenScope` is null or invalid.");
            }
            if (personalAccessTokenStore == null)
            {
                throw new ArgumentNullException("personalAccessTokenStore", "The parameter `personalAccessTokenStore` is null or invalid.");
            }
            if (acquireCredentialsCallback == null)
            {
                throw new ArgumentNullException("acquireCredentialsCallback", "The parameter `acquireCredentialsCallback` is null or invalid.");
            }
            if (acquireAuthenticationCodeCallback == null)
            {
                throw new ArgumentNullException("acquireAuthenticationCodeCallback", "The parameter `acquireAuthenticationCodeCallback` is null or invalid.");
            }

            TokenScope = tokenScope;

            PersonalAccessTokenStore = personalAccessTokenStore;
            GithubAuthority          = new GithubAuthority();

            AcquireCredentialsCallback        = acquireCredentialsCallback;
            AcquireAuthenticationCodeCallback = acquireAuthenticationCodeCallback;
            AuthenticationResultCallback      = authenticationResultCallback;
        }
Example #4
0
        /// <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);
        }
Example #5
0
        /// <summary>
        /// Validates that a set of credentials grants access to the target resource.
        /// </summary>
        /// <param name="targetUri">The unique identifier for the resource for which credentials
        /// are being validated against.</param>
        /// <param name="credentials">The credentials to validate.</param>
        /// <returns>True is successful; otherwise false.</returns>
        public async Task <bool> ValidateCredentials(Uri targetUri, Credential credentials)
        {
            BaseSecureStore.ValidateTargetUri(targetUri);
            Credential.Validate(credentials);

            Trace.WriteLine("GithubAuthentication::ValidateCredentials");

            return(await GithubAuthority.ValidateCredentials(targetUri, credentials));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tokenScope"></param>
        /// <param name="personalAccessTokenStore"></param>
        public GithubAuthentication(GithubTokenScope tokenScope, ICredentialStore personalAccessTokenStore)
        {
            if (tokenScope == null)
                throw new ArgumentNullException("tokenScope", "The parameter `tokenScope` is null or invalid.");
            if (personalAccessTokenStore == null)
                throw new ArgumentNullException("personalAccessTokenStore", "The parameter `personalAccessTokenStore` is null or invalid.");

            TokenScope = tokenScope;

            PersonalAccessTokenStore = personalAccessTokenStore;
            GithubAuthority = new GithubAuthority();
        }
Example #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="tokenScope"></param>
        /// <param name="personalAccessTokenStore"></param>
        public GithubAuthentication(GithubTokenScope tokenScope, ICredentialStore personalAccessTokenStore)
        {
            if (tokenScope == null)
            {
                throw new ArgumentNullException("tokenScope", "The parameter `tokenScope` is null or invalid.");
            }
            if (personalAccessTokenStore == null)
            {
                throw new ArgumentNullException("personalAccessTokenStore", "The parameter `personalAccessTokenStore` is null or invalid.");
            }

            TokenScope = tokenScope;

            PersonalAccessTokenStore = personalAccessTokenStore;
            GithubAuthority          = new GithubAuthority();
        }
Example #8
0
        /// <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);
        }