public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share)
        {
            using (TransactionScope scope = new TransactionScope())
                using (KtmTransactionHandle ktmTx = KtmTransactionHandle.CreateKtmTransactionHandle())
                {
                    NativeMethods.FileMode   internalMode   = TranslateFileMode(mode);
                    NativeMethods.FileShare  internalShare  = TranslateFileShare(share);
                    NativeMethods.FileAccess internalAccess = TranslateFileAccess(access);

                    SafeFileHandle hFile = NativeMethods.CreateFileTransacted(
                        path,
                        internalAccess,
                        internalShare,
                        IntPtr.Zero,
                        internalMode,
                        0,
                        IntPtr.Zero,
                        ktmTx,
                        IntPtr.Zero,
                        IntPtr.Zero);
                    if (hFile.IsInvalid)
                    {
                        NativeMethods.HandleCOMError(Marshal.GetLastWin32Error());
                    }

                    FileStream stream = new FileStream(hFile, access);
                    scope.Complete();

                    return(stream);
                }
        }
 public static extern SafeFileHandle CreateFile(
     string lpFileName,
     [MarshalAs(UnmanagedType.U4)] NativeMethods.FileAccess dwDesiredAccess,
     [MarshalAs(UnmanagedType.U4)] NativeMethods.FileShare dwShareMode,
     IntPtr lpSecurityAttributes,
     [MarshalAs(UnmanagedType.U4)] NativeMethods.CreationDisposition dwCreationDisposition,
     [MarshalAs(UnmanagedType.U4)] NativeMethods.FileAttributes dwFlagsAndAttributes,
     IntPtr hTemplateFile);
 internal static extern SafeFileHandle CreateFile(
     [In] string lpFileName,
     [In] NativeMethods.FileAccess dwDesiredAccess,
     [In] NativeMethods.FileShare dwShareMode,
     [In] IntPtr lpSecurityAttributes,
     [In] NativeMethods.FileMode dwCreationDisposition,
     [In] int dwFlagsAndAttributes,
     [In] IntPtr hTemplateFile);
 internal static extern SafeFileHandle CreateFileTransacted(
     [In] string lpFileName,
     [In] NativeMethods.FileAccess dwDesiredAccess,
     [In] NativeMethods.FileShare dwShareMode,
     [In] IntPtr lpSecurityAttributes,
     [In] NativeMethods.FileMode dwCreationDisposition,
     [In] int dwFlagsAndAttributes,
     [In] IntPtr hTemplateFile,
     [In] KtmTransactionHandle hTransaction,
     [In] IntPtr pusMiniVersion,
     [In] IntPtr pExtendedParameter);
Example #5
0
        public static bool AuthCodePrompt(Program program, TargetUri targetUri, Github.GitHubAuthenticationResultType resultType, string username, out string authenticationCode)
        {
            // ReadConsole 32768 fail, 32767 ok @linquize [https://github.com/Microsoft/Git-Credential-Manager-for-Windows/commit/a62b9a19f430d038dcd85a610d97e5f763980f85]
            const int BufferReadSize = 16 * 1024;

            Debug.Assert(targetUri != null);

            StringBuilder buffer  = new StringBuilder(BufferReadSize);
            uint          read    = 0;
            uint          written = 0;

            authenticationCode = null;

            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(NativeMethods.ConsoleOutName, fileAccessFlags, fileShareFlags, IntPtr.Zero, fileCreationDisposition, fileAttributes, IntPtr.Zero))
                using (SafeFileHandle stdin = NativeMethods.CreateFile(NativeMethods.ConsoleInName, fileAccessFlags, fileShareFlags, IntPtr.Zero, fileCreationDisposition, fileAttributes, IntPtr.Zero))
                {
                    string type = resultType == Github.GitHubAuthenticationResultType.TwoFactorApp
                    ? "app"
                    : "sms";

                    Git.Trace.WriteLine($"2fa type = '{type}'.");

                    buffer.AppendLine()
                    .Append("authcode (")
                    .Append(type)
                    .Append("): ");

                    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 (" + NativeMethods.Win32Error.GetText(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 (" + NativeMethods.Win32Error.GetText(error) + ").");
                    }

                    authenticationCode = buffer.ToString(0, (int)read);
                    authenticationCode = authenticationCode.Trim(Program.NewLineChars);
                }

            return(authenticationCode != null);
        }
Example #6
0
        public static SafeFileHandle Open(
            string path,
            FileMode mode,
            FileAccess access,
            FileShare share)
        {
            using (KtmTransactionHandle ktmTx = KtmTransactionHandle.CreateKtmTransactionHandle())
            {
                // Translate the managed flags to unmanaged flags.
                NativeMethods.FileMode internalMode = TranslateFileMode(mode);

                NativeMethods.FileShare internalShare = TranslateFileShare(share);

                NativeMethods.FileAccess internalAccess = TranslateFileAccess(access);

                // Create the transacted file using P/Invoke.
                SafeFileHandle hFile = NativeMethods.CreateFileTransacted(
                    path,
                    internalAccess,
                    internalShare,
                    IntPtr.Zero,
                    internalMode,
                    0,
                    IntPtr.Zero,
                    ktmTx,
                    IntPtr.Zero,
                    IntPtr.Zero);
                {
                    // Throw an exception if an error occured.
                    if (hFile.IsInvalid)
                    {
                        hFile = NativeMethods.CreateFile(
                            path,
                            internalAccess,
                            internalShare,
                            IntPtr.Zero,
                            internalMode,
                            0,
                            IntPtr.Zero);

                        if (hFile.IsInvalid)
                        {
                            NativeMethods.HandleCOMError(Marshal.GetLastWin32Error());
                        }
                    }

                    return(hFile);
                }
            }
        }
Example #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="reparsePoint"></param>
        /// <param name="accessMode"></param>
        /// <returns></returns>
        private static SafeFileHandle OpenReparsePoint(string reparsePoint, NativeMethods.FileAccess accessMode)
        {
            var handle = NativeMethods.CreateFile(reparsePoint, accessMode,
                                                  NativeMethods.FileShares.Read | NativeMethods.FileShares.Write | NativeMethods.FileShares.Delete,
                                                  IntPtr.Zero, NativeMethods.CreationDisposition.OpenExisting,
                                                  NativeMethods.FileAttributes.BackupSemantics | NativeMethods.FileAttributes.OpenReparsePoint, IntPtr.Zero);

            if (Marshal.GetLastWin32Error() != 0)
            {
                ThrowLastWin32Error("Unable to open reparse point.");
            }

            SafeFileHandle reparsePointHandle = new SafeFileHandle(handle, true);

            return(reparsePointHandle);
        }
Example #8
0
        private static SafeFileHandle OpenReparsePoint(string path, bool writable)
        {
            AdjustToken();

            NativeMethods.FileAccess access = NativeMethods.FileAccess.GenericRead;

            if (writable)
            {
                access |= NativeMethods.FileAccess.GenericWrite;
            }

            return(NativeMethods.CreateFile(
                       path,
                       access,
                       NativeMethods.FileShare.None,
                       IntPtr.Zero,
                       NativeMethods.CreationDisposition.OpenExisting,
                       NativeMethods.FileAttributes.BackupSemantics |
                       NativeMethods.FileAttributes.OpenReparsePoint,
                       IntPtr.Zero));
        }
Example #9
0
        public static FileStream OpenFile(string path, FileMode mode, FileAccess access, FileShare share)
        {
            NativeMethods.FileAccess nativeAccess =
                access == FileAccess.Read ? NativeMethods.FileAccess.GENERIC_READ :
                access == FileAccess.Write ? NativeMethods.FileAccess.GENERIC_WRITE :
                access == FileAccess.ReadWrite ? NativeMethods.FileAccess.GENERIC_READ | NativeMethods.FileAccess.GENERIC_WRITE : 0;

            var handle = NativeMethods.CreateFile(
                path,
                nativeAccess,
                (NativeMethods.FileShare)share,
                IntPtr.Zero,
                (NativeMethods.FileMode)mode,
                0, // Returns the directory handle
                IntPtr.Zero);

            if (handle.IsInvalid)
            {
                throw new Win32Exception();
            }

            return(new FileStream(handle, access));
        }
        public static Credential CredentialPrompt(Program program, TargetUri targetUri, string titleMessage)
        {
            // ReadConsole 32768 fail, 32767 OK @linquize [https://github.com/Microsoft/Git-Credential-Manager-for-Windows/commit/a62b9a19f430d038dcd85a610d97e5f763980f85]
            const int BufferReadSize = 16 * 1024;

            if (program is null)
            {
                throw new ArgumentNullException(nameof(program));
            }
            if (targetUri is null)
            {
                throw new ArgumentNullException(nameof(targetUri));
            }

            titleMessage = titleMessage ?? "Please enter your credentials for ";

            StringBuilder buffer  = new StringBuilder(BufferReadSize);
            uint          read    = 0;
            uint          written = 0;

            NativeMethods.ConsoleMode             consoleMode             = 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(NativeMethods.ConsoleOutName, fileAccessFlags, fileShareFlags, IntPtr.Zero, fileCreationDisposition, fileAttributes, IntPtr.Zero))
                using (SafeFileHandle stdin = NativeMethods.CreateFile(NativeMethods.ConsoleInName, fileAccessFlags, fileShareFlags, IntPtr.Zero, fileCreationDisposition, fileAttributes, IntPtr.Zero))
                {
                    // Read the current console mode.
                    if (stdin.IsInvalid || stdout.IsInvalid)
                    {
                        program.Trace.WriteLine("not a tty detected, abandoning prompt.");
                        return(null);
                    }
                    else if (!NativeMethods.GetConsoleMode(stdin, out consoleMode))
                    {
                        int error = Marshal.GetLastWin32Error();
                        throw new Win32Exception(error, "Unable to determine console mode (" + NativeMethods.Win32Error.GetText(error) + ").");
                    }

                    program.Trace.WriteLine($"console mode = '{consoleMode}'.");

                    string username = null;
                    string password = null;

                    // Instruct the user as to what they are expected to do.
                    buffer.Append(titleMessage)
                    .Append(targetUri)
                    .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 (" + NativeMethods.Win32Error.GetText(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 (" + NativeMethods.Win32Error.GetText(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 (" + NativeMethods.Win32Error.GetText(error) + ").");
                    }

                    // Record input from the user into local storage, stripping any EOL chars.
                    username = buffer.ToString(0, (int)read);
                    username = username.Trim(program.Settings.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;

                    try
                    {
                        if (!NativeMethods.SetConsoleMode(stdin, consoleMode2))
                        {
                            int error = Marshal.GetLastWin32Error();
                            throw new Win32Exception(error, "Unable to set console mode (" + NativeMethods.Win32Error.GetText(error) + ").");
                        }

                        program.Trace.WriteLine($"console mode = '{(consoleMode2 & NativeMethods.ConsoleMode.AllFlags)}'.");

                        // Prompt the user for password.
                        buffer.Append("password: "******"Unable to write to standard output (" + NativeMethods.Win32Error.GetText(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 (" + NativeMethods.Win32Error.GetText(error) + ").");
                        }

                        // Record input from the user into local storage, stripping any EOL chars.
                        password = buffer.ToString(0, (int)read);
                        password = password.Trim(program.Settings.NewLine.ToCharArray());
                    }
                    finally
                    {
                        // Restore the console mode to its original value.
                        NativeMethods.SetConsoleMode(stdin, consoleMode);

                        program.Trace.WriteLine($"console mode = '{consoleMode}'.");
                    }

                    if (username != null && password != null)
                    {
                        return(new Credential(username, password));
                    }
                }

            return(null);
        }
Example #11
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);
        }