Starting a process with a user name and password

32,204

Solution 1

The ProcessStartInfo.Password is not a simple string that you can write down and assign to the property. What you need is a SecureString instance and a SecureString cannot be created passing a simple string to its constructor. Obviously the OS has no API or method that allows a non trusted program to retrieve the password of the current user (it would be the biggest security bug ever heard of).

So, in my thinking, you are left with only one option. Ask your user to type again the password and the resulting input should be transformed into a SecureString

This example is an extension method for the string class that I have seen here

using System.Security;

// ...

public static SecureString ConvertToSecureString(this string password)
{
    if (password == null)
        throw new ArgumentNullException("password");

    unsafe
    {
        fixed (char* passwordChars = password)
        {
            var securePassword = new SecureString(passwordChars, password.Length);
            securePassword.MakeReadOnly();
            return securePassword;
        }
    }
}

you could use it to transform the password typed by your user and start the process

using(frmGetPassword fgp = new frmGetPassword())
{
     if(DialogResult.OK == fgp.ShowDialog())
     {
         SecureString ss = fgp.Password.ConvertToSecureString();
         var processInfo = new ProcessStartInfo
         {
             WorkingDirectory = workingDirectory,
             FileName = "a name",
             UserName = loggedUserName, 
             Password = ss,
             Domain = userNameDomain,
             UseShellExecute = false,
         };
         Process.Start(processInfo);
     }
}

Solution 2

I use the windows Password store to manage such passwords. Check out the http://credentialmanagement.codeplex.com/ library which wraps around the windows API. Either your Setup-Routine or Admin can add the password to the store, which can then be retrieved at runtime from the application. Only drawback is that the store is user-specific. You can't create a password which can be used across multiple users.

It's as simple as that:

        _credentials = new CredentialSet("myApp:*");
        if (_credentials.Count == 0)
        {
            //TODO: ask user for password, supply it here, or use windows UI to set password (rundll32.exe keymgr.dll, KRShowKeyMgr)
            var c = new Credential()
            {
                Target = "myApp:Production",
                Username = "SomeUser",
                Description = "Credentials for doing something...",
                PersistanceType = PersistanceType.LocalComputer,
                Type = CredentialType.DomainPassword
            };
            c.Save();
            _credentials.Add(c);
        }
Share:
32,204
Yonatan Nir
Author by

Yonatan Nir

SOreadytohelp A Software Engineer. Currently working with Android and Server Side (PHP), but my main preference is .NET which is in my opinion far superior to other technologies out there.

Updated on March 07, 2021

Comments

  • Yonatan Nir
    Yonatan Nir about 3 years

    I know that you can run a process with a given username/password in the following way:

    var processInfo = new ProcessStartInfo
    {
        WorkingDirectory = workingDirectory,
        FileName = "a name",
        UserName = loggedUserName, 
        Password = "password",
        Domain = userNameDomain,
        UseShellExecute = false,
    };
    Process.Start(processInfo);
    

    The problem I'm facing is that I don't want to write the actual password as a part of the code and the process won't start if I leave the Password attribute empty... How can I safely start the process without exposing the password as a hard coded string in the code?

  • Matt Johnson-Pint
    Matt Johnson-Pint over 5 years
    Keep in mind that any sort of ConvertToSecureString method has the problem that the value is in a regular string to begin with - thus already in memory and defeating the purpose of using a SecureString. Also there's a ProcessStartInfo.PasswordInClearText property from .NET 4.6.1 forward. Might as well use that if you have a cleartext password already.
  • Admin
    Admin almost 3 years
    @MattJohnson-Pint thank you, indeed passing the password in clear text helped me to skip all of this answer (and btw there was no need of unsafe because one could have appended chars one by one)