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?
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);
}
}
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With