diff --git a/AdysTech.CredentialManager/AdysTech.CredentialManager.csproj b/AdysTech.CredentialManager/AdysTech.CredentialManager.csproj
index fa6f505..d99300c 100644
--- a/AdysTech.CredentialManager/AdysTech.CredentialManager.csproj
+++ b/AdysTech.CredentialManager/AdysTech.CredentialManager.csproj
@@ -41,7 +41,7 @@
-
+
diff --git a/AdysTech.CredentialManager/Credential.cs b/AdysTech.CredentialManager/Credential.cs
index 89c2122..3632922 100644
--- a/AdysTech.CredentialManager/Credential.cs
+++ b/AdysTech.CredentialManager/Credential.cs
@@ -10,13 +10,13 @@ namespace AdysTech.CredentialManager
internal class Credential
{
public UInt32 Flags;
- public NativeStructs.CredentialType Type;
+ public NativeCode.CredentialType Type;
public string TargetName;
public string Comment;
public DateTime LastWritten;
public UInt32 CredentialBlobSize;
public string CredentialBlob;
- public NativeStructs.Persistance Persist;
+ public NativeCode.Persistance Persist;
public UInt32 AttributeCount;
public IntPtr Attributes;
public string TargetAlias;
@@ -27,7 +27,7 @@ public Credential()
}
- internal Credential(NativeStructs.NativeCredential ncred)
+ internal Credential(NativeCode.NativeCredential ncred)
{
CredentialBlobSize = ncred.CredentialBlobSize;
CredentialBlob = Marshal.PtrToStringUni (ncred.CredentialBlob,
@@ -37,7 +37,7 @@ internal Credential(NativeStructs.NativeCredential ncred)
TargetAlias = Marshal.PtrToStringUni (ncred.TargetAlias);
Type = ncred.Type;
Flags = ncred.Flags;
- Persist = (NativeStructs.Persistance) ncred.Persist;
+ Persist = (NativeCode.Persistance) ncred.Persist;
LastWritten = DateTime.FromFileTime ((long) ( (ulong) ncred.LastWritten.dwHighDateTime << 32 | (ulong) ncred.LastWritten.dwLowDateTime ));
}
@@ -50,8 +50,8 @@ public Credential(System.Net.NetworkCredential credential)
Attributes = IntPtr.Zero;
Comment = null;
TargetAlias = null;
- Type = NativeStructs.CredentialType.GENERIC;
- Persist = NativeStructs.Persistance.SESSION;
+ Type = NativeCode.CredentialType.Generic;
+ Persist = NativeCode.Persistance.Session;
}
///
@@ -60,9 +60,9 @@ public Credential(System.Net.NetworkCredential credential)
/// The managed Credential counterpart containing data to be stored.
/// A NativeCredential instance that is derived from the given Credential
/// instance.
- internal NativeStructs.NativeCredential GetNativeCredential()
+ internal NativeCode.NativeCredential GetNativeCredential()
{
- NativeStructs.NativeCredential ncred = new NativeStructs.NativeCredential ();
+ NativeCode.NativeCredential ncred = new NativeCode.NativeCredential ();
ncred.AttributeCount = 0;
ncred.Attributes = IntPtr.Zero;
ncred.Comment = IntPtr.Zero;
diff --git a/AdysTech.CredentialManager/CredentialManager.cs b/AdysTech.CredentialManager/CredentialManager.cs
index 7989038..5635bb3 100644
--- a/AdysTech.CredentialManager/CredentialManager.cs
+++ b/AdysTech.CredentialManager/CredentialManager.cs
@@ -1,12 +1,9 @@
-using Microsoft.Win32.SafeHandles;
-using System;
-using System.Collections.Generic;
+using System;
using System.ComponentModel;
-using System.Linq;
+using System.Diagnostics;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
-using System.Threading.Tasks;
namespace AdysTech.CredentialManager
{
@@ -20,14 +17,15 @@ public static class CredentialManager
/// Opens OS Version specific Window prompting for credentials
///
/// A descriptive text for where teh credentials being asked are used for
+ /// Whether or not to offer the checkbox to save the credentials
/// NetworkCredential object containing the user name,
- public static NetworkCredential PromptForCredentials(string Target)
+ public static NetworkCredential PromptForCredentials(string Target, ref bool save)
{
var username = String.Empty;
var passwd = String.Empty;
var domain = String.Empty;
- if ( !PromptForCredentials (Target, out username, out passwd, out domain) )
+ if ( !PromptForCredentials (Target, ref save, out username, out passwd, out domain) )
return null;
return new NetworkCredential (username, passwd, domain);
}
@@ -36,73 +34,165 @@ public static NetworkCredential PromptForCredentials(string Target)
/// Opens OS Version specific Window prompting for credentials
///
/// A descriptive text for where teh credentials being asked are used for
+ /// Whether or not to offer the checkbox to save the credentials
/// A brief message to display in the dialog box
/// Title for the dialog box
/// NetworkCredential object containing the user name,
- public static NetworkCredential PromptForCredentials(string Target, string Message, string Caption)
+ public static NetworkCredential PromptForCredentials(string Target, ref bool save, string Message, string Caption)
{
var username = String.Empty;
var passwd = String.Empty;
var domain = String.Empty;
- if ( !PromptForCredentials (Target, Message, Caption, out username, out passwd, out domain) )
+ if ( !PromptForCredentials (Target, ref save, Message, Caption, out username, out passwd, out domain) )
return null;
return new NetworkCredential (username, passwd, domain);
}
- internal static bool PromptForCredentials(string target, out string user, out string password, out string domain)
+ internal static bool PromptForCredentials(string target, ref bool save, out string user, out string password, out string domain)
{
- return PromptForCredentials (target, new NativeStructs.CredentialUIInfo (), out user, out password, out domain);
+ return PromptForCredentials (target, new NativeCode.CredentialUIInfo (), ref save, out user, out password, out domain);
}
- internal static bool PromptForCredentials(string target, string Message, string Caption, out string user, out string password, out string domain)
+ internal static bool PromptForCredentials(string target, ref bool save, string Message, string Caption, out string user, out string password, out string domain)
{
- NativeStructs.CredentialUIInfo credUI = new NativeStructs.CredentialUIInfo ();
+ NativeCode.CredentialUIInfo credUI = new NativeCode.CredentialUIInfo ();
credUI.pszMessageText = Message;
credUI.pszCaptionText = Caption;
- return PromptForCredentials (target, credUI, out user, out password, out domain);
+ return PromptForCredentials (target, credUI, ref save, out user, out password, out domain);
}
- private static bool PromptForCredentials(string target, NativeStructs.CredentialUIInfo credUI, out string user, out string password, out string domain)
+ private static bool PromptForCredentials(string target, NativeCode.CredentialUIInfo credUI, ref bool save, out string user, out string password, out string domain)
{
+ user = String.Empty;
+ password = String.Empty;
+ domain = String.Empty;
+
+
+
// Setup the flags and variables
- StringBuilder userPassword = new StringBuilder (), userID = new StringBuilder ();
credUI.cbSize = Marshal.SizeOf (credUI);
+ int errorcode = 0;
+ uint dialogReturn;
+ uint authPackage = 0;
+
+ IntPtr outCredBuffer = new IntPtr ();
+ uint outCredSize;
+ var flags = NativeCode.PromptForWindowsCredentialsFlags.GenericCredentials | NativeCode.PromptForWindowsCredentialsFlags.EnumerateCurrentUser;
+ flags = save ? flags | NativeCode.PromptForWindowsCredentialsFlags.ShowCheckbox : flags;
+
+ // Setup the flags and variables
+ int result = NativeCode.CredUIPromptForWindowsCredentials (ref credUI,
+ errorcode,
+ ref authPackage,
+ IntPtr.Zero,
+ 0,
+ out outCredBuffer,
+ out outCredSize,
+ ref save,
+ flags);
+
+ var usernameBuf = new StringBuilder (100);
+ var passwordBuf = new StringBuilder (100);
+ var domainBuf = new StringBuilder (100);
+
+ int maxUserName = 100;
+ int maxDomain = 100;
+ int maxPassword = 100;
+ if ( result == 0 )
+ {
+ if ( NativeCode.CredUnPackAuthenticationBuffer (0, outCredBuffer, outCredSize, usernameBuf, ref maxUserName,
+ domainBuf, ref maxDomain, passwordBuf, ref maxPassword) )
+ {
+ user = usernameBuf.ToString ();
+ password = passwordBuf.ToString ();
+ domain = domainBuf.ToString ();
+ if ( String.IsNullOrWhiteSpace (domain) )
+ {
+ Debug.WriteLine ("Domain null");
+ if ( !ParseUserName (usernameBuf.ToString (), maxUserName, maxDomain, out user, out password) )
+ user = usernameBuf.ToString ();
+ }
+ }
+
+ //mimic SecureZeroMem function to make sure buffer is zeroed out. SecureZeroMem is not an exported function, neither is RtlSecureZeroMemory
+ var zeroBytes = new byte[outCredSize];
+ Marshal.Copy (zeroBytes, 0, outCredBuffer, (int) outCredSize);
+
+ //clear the memory allocated by CredUIPromptForWindowsCredentials
+ NativeCode.CoTaskMemFree (outCredBuffer);
+ return true;
+ }
+
+ user = null;
+ domain = null;
+ return false;
+ }
+
+ private static bool ParseUserName(string usernameBuf, int maxUserName, int maxDomain, out string user, out string domain)
+ {
+ StringBuilder userBuilder = new StringBuilder ();
+ StringBuilder domainBuilder = new StringBuilder ();
+ user = String.Empty;
+ domain = String.Empty;
+
+ var returnCode = NativeCode.CredUIParseUserName (usernameBuf, userBuilder, maxUserName, domainBuilder, maxDomain);
+ Debug.WriteLine (returnCode);
+ switch ( returnCode )
+ {
+ case NativeCode.CredentialUIReturnCodes.Success: // The username is valid.
+ user = userBuilder.ToString ();
+ domain = domainBuilder.ToString ();
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Accepts credentials in a console window
+ ///
+ /// A descriptive text for where teh credentials being asked are used for
+ /// NetworkCredential object containing the user name,
+ public static NetworkCredential PromptForCredentialsConsole(string target)
+ {
+ var user = String.Empty;
+ var password = String.Empty;
+ var domain = String.Empty;
+
+ // Setup the flags and variables
+ StringBuilder userPassword = new StringBuilder (), userID = new StringBuilder ();
bool save = true;
- NativeStructs.CredentialUIFlags flags = NativeStructs.CredentialUIFlags.COMPLETE_USERNAME | NativeStructs.CredentialUIFlags.PERSIST | NativeStructs.CredentialUIFlags.EXCLUDE_CERTIFICATES;
+ NativeCode.CredentialUIFlags flags = NativeCode.CredentialUIFlags.CompleteUsername | NativeCode.CredentialUIFlags.ExcludeCertificates;
// Prompt the user
- NativeStructs.CredentialUIReturnCodes returnCode = NativeStructs.CredUIPromptForCredentials (ref credUI, target, IntPtr.Zero, 0, userID, 100, userPassword, 100, ref save, flags);
+ NativeCode.CredentialUIReturnCodes returnCode = NativeCode.CredUICmdLinePromptForCredentials (target, IntPtr.Zero, 0, userID, 100, userPassword, 100, ref save, flags);
password = userPassword.ToString ();
StringBuilder userBuilder = new StringBuilder ();
StringBuilder domainBuilder = new StringBuilder ();
- returnCode = NativeStructs.CredUIParseUserName (userID.ToString (), userBuilder, int.MaxValue, domainBuilder, int.MaxValue);
+ returnCode = NativeCode.CredUIParseUserName (userID.ToString (), userBuilder, int.MaxValue, domainBuilder, int.MaxValue);
switch ( returnCode )
{
- case NativeStructs.CredentialUIReturnCodes.NO_ERROR: // The username is valid.
+ case NativeCode.CredentialUIReturnCodes.Success: // The username is valid.
user = userBuilder.ToString ();
domain = domainBuilder.ToString ();
- return true;
+ break;
- case NativeStructs.CredentialUIReturnCodes.ERROR_INVALID_ACCOUNT_NAME: // The username is not valid.
+ case NativeCode.CredentialUIReturnCodes.InvalidAccountName: // The username is not valid.
user = userID.ToString ();
domain = null;
- return false;
+ break;
- case NativeStructs.CredentialUIReturnCodes.ERROR_INSUFFICIENT_BUFFER: // One of the buffers is too small.
+ case NativeCode.CredentialUIReturnCodes.InsufficientBuffer: // One of the buffers is too small.
throw new OutOfMemoryException ();
- case NativeStructs.CredentialUIReturnCodes.ERROR_INVALID_PARAMETER: // ulUserMaxChars or ulDomainMaxChars is zero OR userName, user, or domain is NULL.
+ case NativeCode.CredentialUIReturnCodes.InvalidParameter: // ulUserMaxChars or ulDomainMaxChars is zero OR userName, user, or domain is NULL.
throw new ArgumentNullException ("userName");
- default:
- user = null;
- domain = null;
- return false;
}
+ return new NetworkCredential (user, password, domain);
}
@@ -118,10 +208,10 @@ public static bool SaveCredentials(string Target, NetworkCredential credential)
// Go ahead with what we have are stuff it into the CredMan structures.
Credential cred = new Credential (credential);
cred.TargetName = Target;
- cred.Persist = NativeStructs.Persistance.ENTERPRISE;
- NativeStructs.NativeCredential ncred = cred.GetNativeCredential ();
+ cred.Persist = NativeCode.Persistance.Entrprise;
+ NativeCode.NativeCredential ncred = cred.GetNativeCredential ();
// Write the info into the CredMan storage.
- bool written = NativeStructs.CredWrite (ref ncred, 0);
+ bool written = NativeCode.CredWrite (ref ncred, 0);
int lastError = Marshal.GetLastWin32Error ();
if ( written )
{
@@ -148,7 +238,7 @@ public static NetworkCredential GetCredentials(string Target)
var domain = String.Empty;
// Make the API call using the P/Invoke signature
- bool ret = NativeStructs.CredRead (Target, NativeStructs.CredentialType.GENERIC, 0, out nCredPtr);
+ bool ret = NativeCode.CredRead (Target, NativeCode.CredentialType.Generic, 0, out nCredPtr);
int lastError = Marshal.GetLastWin32Error ();
if ( !ret )
throw new Win32Exception (lastError, "CredDelete throw an error");
@@ -163,12 +253,12 @@ public static NetworkCredential GetCredentials(string Target)
var user = cred.UserName;
StringBuilder userBuilder = new StringBuilder ();
StringBuilder domainBuilder = new StringBuilder ();
- var ret1 = NativeStructs.CredUIParseUserName (user, userBuilder, int.MaxValue, domainBuilder, int.MaxValue);
+ var ret1 = NativeCode.CredUIParseUserName (user, userBuilder, int.MaxValue, domainBuilder, int.MaxValue);
lastError = Marshal.GetLastWin32Error ();
//assuming invalid account name to be not meeting condition for CredUIParseUserName
//"The name must be in UPN or down-level format, or a certificate"
- if ( ret1 == NativeStructs.CredentialUIReturnCodes.ERROR_INVALID_ACCOUNT_NAME )
+ if ( ret1 == NativeCode.CredentialUIReturnCodes.InvalidAccountName )
userBuilder.Append (user);
else if ( (uint) ret1 > 0 )
throw new Win32Exception (lastError, "CredUIParseUserName throw an error");
@@ -190,7 +280,7 @@ public static NetworkCredential GetCredentials(string Target)
public static bool RemoveCredentials(string Target)
{
// Make the API call using the P/Invoke signature
- var ret = NativeStructs.CredDelete (Target, NativeStructs.CredentialType.GENERIC, 0);
+ var ret = NativeCode.CredDelete (Target, NativeCode.CredentialType.Generic, 0);
int lastError = Marshal.GetLastWin32Error ();
if ( !ret )
throw new Win32Exception (lastError, "CredDelete throw an error");
diff --git a/AdysTech.CredentialManager/CriticalCredentialHandle.cs b/AdysTech.CredentialManager/CriticalCredentialHandle.cs
index 35fc1ca..065dece 100644
--- a/AdysTech.CredentialManager/CriticalCredentialHandle.cs
+++ b/AdysTech.CredentialManager/CriticalCredentialHandle.cs
@@ -21,8 +21,8 @@ internal Credential GetCredential()
if ( !IsInvalid )
{
// Get the Credential from the mem location
- NativeStructs.NativeCredential ncred = (NativeStructs.NativeCredential) Marshal.PtrToStructure (handle,
- typeof (NativeStructs.NativeCredential));
+ NativeCode.NativeCredential ncred = (NativeCode.NativeCredential) Marshal.PtrToStructure (handle,
+ typeof (NativeCode.NativeCredential));
// Create a managed Credential type and fill it with data from the native counterpart.
Credential cred = new Credential (ncred);
@@ -46,7 +46,7 @@ override protected bool ReleaseHandle()
{
// NOTE: We should also ZERO out the memory allocated to the handle, before free'ing it
// so there are no traces of the sensitive data left in memory.
- NativeStructs.CredFree (handle);
+ NativeCode.CredFree (handle);
// Mark the handle as invalid for future users.
SetHandleAsInvalid ();
return true;
diff --git a/AdysTech.CredentialManager/NativeStructs.cs b/AdysTech.CredentialManager/NativeStructs.cs
deleted file mode 100644
index 951f2ca..0000000
--- a/AdysTech.CredentialManager/NativeStructs.cs
+++ /dev/null
@@ -1,120 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace AdysTech.CredentialManager
-{
- internal static class NativeStructs
- {
- [Flags]
- internal enum CredentialUIFlags
- {
- INCORRECT_PASSWORD = 0x1,
- DO_NOT_PERSIST = 0x2,
- REQUEST_ADMINISTRATOR = 0x4,
- EXCLUDE_CERTIFICATES = 0x8,
- REQUIRE_CERTIFICATE = 0x10,
- SHOW_SAVE_CHECK_BOX = 0x40,
- ALWAYS_SHOW_UI = 0x80,
- REQUIRE_SMARTCARD = 0x100,
- PASSWORD_ONLY_OK = 0x200,
- VALIDATE_USERNAME = 0x400,
- COMPLETE_USERNAME = 0x800,
- PERSIST = 0x1000,
- SERVER_CREDENTIAL = 0x4000,
- EXPECT_CONFIRMATION = 0x20000,
- GENERIC_CREDENTIALS = 0x40000,
- USERNAME_TARGET_CREDENTIALS = 0x80000,
- KEEP_USERNAME = 0x100000,
- }
-
- internal enum CredentialUIReturnCodes : uint
- {
- NO_ERROR = 0,
- ERROR_CANCELLED = 1223,
- ERROR_NO_SUCH_LOGON_SESSION = 1312,
- ERROR_NOT_FOUND = 1168,
- ERROR_INVALID_ACCOUNT_NAME = 1315,
- ERROR_INSUFFICIENT_BUFFER = 122,
- ERROR_INVALID_PARAMETER = 87,
- ERROR_INVALID_FLAGS = 1004,
- }
-
- [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- internal struct CredentialUIInfo
- {
- public int cbSize;
- public IntPtr hwndParent;
- public string pszMessageText;
- public string pszCaptionText;
- public IntPtr hbmBanner;
- }
-
- [DllImport ("credui")]
- internal static extern CredentialUIReturnCodes CredUIPromptForCredentials(ref CredentialUIInfo creditUR,
- string targetName,
- IntPtr reserved1,
- int iError,
- StringBuilder userName,
- int maxUserName,
- StringBuilder password,
- int maxPassword,
- [MarshalAs (UnmanagedType.Bool)] ref bool pfSave,
- CredentialUIFlags flags);
-
- [DllImport ("credui.dll", EntryPoint = "CredUIParseUserNameW", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern CredentialUIReturnCodes CredUIParseUserName(
- string userName,
- StringBuilder user,
- int userMaxChars,
- StringBuilder domain,
- int domainMaxChars);
-
- internal enum CredentialType : uint
- {
- GENERIC = 1,
- DOMAIN_PASSWORD = 2,
- DOMAIN_CERTIFICATE = 3
- }
-
- internal enum Persistance : uint
- {
- SESSION = 1,
- LOCAL_MACHINE = 2,
- ENTERPRISE = 3
- }
-
- [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- internal struct NativeCredential
- {
- public UInt32 Flags;
- public CredentialType Type;
- public IntPtr TargetName;
- public IntPtr Comment;
- public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
- public UInt32 CredentialBlobSize;
- public IntPtr CredentialBlob;
- public UInt32 Persist;
- public UInt32 AttributeCount;
- public IntPtr Attributes;
- public IntPtr TargetAlias;
- public IntPtr UserName;
-
- }
-
- [DllImport ("Advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern bool CredDelete(string target, CredentialType type, int reservedFlag);
-
- [DllImport ("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern bool CredRead(string target, CredentialType type, int reservedFlag, out IntPtr CredentialPtr);
-
- [DllImport ("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
- internal static extern bool CredWrite([In] ref NativeCredential userCredential, [In] UInt32 flags);
-
- [DllImport ("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
- internal static extern bool CredFree([In] IntPtr cred);
- }
-}
diff --git a/CredentialManager.Test/CredentialManagerTest.cs b/CredentialManager.Test/CredentialManagerTest.cs
index b4aaa2e..a9b759a 100644
--- a/CredentialManager.Test/CredentialManagerTest.cs
+++ b/CredentialManager.Test/CredentialManagerTest.cs
@@ -2,6 +2,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using AdysTech.CredentialManager;
using System.Net;
+using System.Diagnostics;
namespace CredentialManagerTest
{
@@ -15,6 +16,8 @@ public void TestSaveCredentials()
{
var cred = new NetworkCredential ("TestUser", "Pwd");
Assert.IsTrue (CredentialManager.SaveCredentials ("TestSystem", cred), "SaveCredential failed");
+
+
}
catch ( Exception e )
{
@@ -31,7 +34,8 @@ public void TestGetCredentials()
try
{
- Assert.IsNotNull (CredentialManager.GetCredentials ("localhost:8086"), "GetCredential failed");
+ Assert.IsNotNull (CredentialManager.GetCredentials ("TestSystem"), "GetCredential failed");
+
}
catch ( Exception e )
{
@@ -40,5 +44,75 @@ public void TestGetCredentials()
return;
}
}
+
+ [TestMethod]
+ public void TestPromptForCredentials()
+ {
+
+ try
+ {
+ bool save = false;
+ Assert.IsNotNull (CredentialManager.PromptForCredentials ("Some Webservice", ref save, "Please provide credentials", "Credentials for service"), "PromptForCredentials failed");
+
+ }
+ catch ( Exception e )
+ {
+ Assert.Fail ("Unexpected exception of type {0} caught: {1}",
+ e.GetType (), e.Message);
+ return;
+ }
+ }
+
+ ///
+ /// Not working as Console window can't be seen during test
+ ///
+ [TestMethod]
+ public void TestPromptForCredentialsConsole()
+ {
+
+ try
+ {
+ bool save = false;
+ Assert.IsNotNull (CredentialManager.PromptForCredentialsConsole ("Some Webservice"), "PromptForCredentialsConsole failed");
+
+ }
+ catch ( Exception e )
+ {
+ Assert.Fail ("Unexpected exception of type {0} caught: {1}",
+ e.GetType (), e.Message);
+ return;
+ }
+ }
+ [TestMethod]
+ public void IntegrationTest()
+ {
+
+ try
+ {
+ bool save = true;
+ var cred = CredentialManager.PromptForCredentials ("Some Webservice", ref save, "Please provide credentials", "Credentials for service");
+ Assert.IsNotNull (cred, "PromptForCredentials failed");
+ if ( save )
+ {
+ var usr = cred.UserName;
+ var pwd = cred.Password;
+ var dmn = cred.Domain;
+ Debug.WriteLine ("Usr:{0}, Pwd{1}, Dmn{2}", usr, pwd, dmn);
+ Assert.IsTrue (CredentialManager.SaveCredentials ("TestSystem", cred), "SaveCredential failed");
+ cred = CredentialManager.GetCredentials ("TestSystem");
+ Assert.IsNotNull (cred, "GetCredential failed");
+ Assert.IsTrue (usr == cred.UserName && pwd == cred.Password && dmn == cred.Domain, "Saved and retreived data doesn't match");
+ }
+
+ }
+ catch ( Exception e )
+ {
+ Assert.Fail ("Unexpected exception of type {0} caught: {1} on {2}",
+ e.GetType (), e.Message, e.StackTrace);
+ return;
+ }
+ }
+
+
}
}