views:

311

answers:

1

Lately I've been working in an office with a wireless network which uses an annoying authentication scheme: every few hours, you need to open up a browser and type a username/password into an authentication web page, or you lose network access. (When the time expires, your next browser request will redirect to the auth page, and if your creds pass muster, then you'll be redirected back to the page you were trying to get to originally).

This kind of annoyance may be OK for an airport or coffee shop wireless, but in an office it's infuriating-- especially if you're working with network services (e.g. SVN, email) which suddenly stop working every few hours unless you bring up a browser.

So I have written a tiny C# console app which will log in for me by sending an HTTP request to the login form with my credentials.

This is obviously insecure-- my password is sitting inside my source code for all to see. I'd prefer to be able to save my credentials using the same mechanism that IE, for example, uses to save and re-fill passwords in web forms.

Ideally, I'd like a re-usable component for entering, saving, and retrieving credentials(including the UI with an optional "save creds" checkbox) so that my app can simply do something like this (in pseudocode):

// retrieve any saved credentials from some secure place
Credentials creds = GetCreds(some parameters go here);

// if none stored, then show the user an "enter and optionally save credentials" dialog
if (creds == null)
    creds = GetCredsDialog(some parameters go here);

// POST to the authentication page
if (creds != null)
{
    string authUrl = "https://somehost/login/";
    string postDataPattern = "post data pattern here";

    // use SecureString here instead?
    string postData = string.Format (postDataPattern, HttpUtility.HtmlEncode(creds.Username), HttpUtility.HtmlEncode(creds.Password));
    WebClient wc = new WebClient();
    string html = wc.UploadString (authUrl, "POST", postData);

    // TODO: if html indicates login failure, clear stored credentials 
    // and ask for new creds. then retry.
}

Essentially I want to shift the burden of securely storing creds from my app to Windows, under the assumption that the Windows guys will be better at this than I will be. :-)

I'm not looking for iron-clad security here, just something comparable to what IE is using to secure my other stored passwords for other websites. I just don't want to keep plain text passwords in my code!

Of course, the right solution here is to work with the IT department to get them to get a real authentication scheme for Wireless, but in the meantime I'm on my own.

A .NET solution would be preferable, but a Win32 solution would be OK too-- I could simply port the app to C++ without much trouble.

+4  A: 

To store the credentials, use the ProtectedData class in System.Security.dll.
By passing DataProtectionScope.CurrentUser, no other user will be able to decrypt the data.

EDIT: For the dialog, you can use the CredUIPromptForCredentials API function

See here for a .Net wrapper.

SLaks
That is one of the greatest and most usable encryption classes in .NET. When that was released a million developers' internal static classes died an honorable death.
Josh Einstein
Unless you need to send data across machines.
SLaks
Obviously, but that's such a less common scenario than the "I need to protect data for my own app" one.
Josh Einstein