Advertisement
Guest User

Untitled

a guest
Jul 6th, 2016
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.09 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using Microsoft.Win32.SafeHandles;
  7.  
  8. public static class CredentialManager
  9. {
  10. public static Credential ReadCredential(string applicationName)
  11. {
  12. IntPtr nCredPtr;
  13. bool read = CredRead(applicationName, CredentialType.Generic, 0, out nCredPtr);
  14. if (read)
  15. {
  16. using (CriticalCredentialHandle critCred = new CriticalCredentialHandle(nCredPtr))
  17. {
  18. CREDENTIAL cred = critCred.GetCredential();
  19. return ReadCredential(cred);
  20. }
  21. }
  22.  
  23. return null;
  24. }
  25.  
  26. private static Credential ReadCredential(CREDENTIAL credential)
  27. {
  28. string applicationName = Marshal.PtrToStringUni(credential.TargetName);
  29. string userName = Marshal.PtrToStringUni(credential.UserName);
  30. string secret = null;
  31. if (credential.CredentialBlob != IntPtr.Zero)
  32. {
  33. secret = Marshal.PtrToStringUni(credential.CredentialBlob, (int)credential.CredentialBlobSize / 2);
  34. }
  35.  
  36. return new Credential(credential.Type, applicationName, userName, secret);
  37. }
  38.  
  39. public static void WriteCredential(string applicationName, string userName, string secret)
  40. {
  41. byte[] byteArray = secret == null ? null : Encoding.Unicode.GetBytes(secret);
  42. // XP and Vista: 512;
  43. // 7 and above: 5*512
  44. if (Environment.OSVersion.Version < new Version(6, 1) /* Windows 7 */)
  45. {
  46. if (byteArray != null && byteArray.Length > 512)
  47. throw new ArgumentOutOfRangeException("secret", "The secret message has exceeded 512 bytes.");
  48. }
  49. else
  50. {
  51. if (byteArray != null && byteArray.Length > 512 * 5)
  52. throw new ArgumentOutOfRangeException("secret", "The secret message has exceeded 2560 bytes.");
  53. }
  54.  
  55. CREDENTIAL credential = new CREDENTIAL();
  56. credential.AttributeCount = 0;
  57. credential.Attributes = IntPtr.Zero;
  58. credential.Comment = IntPtr.Zero;
  59. credential.TargetAlias = IntPtr.Zero;
  60. credential.Type = CredentialType.Generic;
  61. credential.Persist = (uint)CredentialPersistence.LocalMachine;
  62. credential.CredentialBlobSize = (uint)(byteArray == null ? 0 : byteArray.Length);
  63. credential.TargetName = Marshal.StringToCoTaskMemUni(applicationName);
  64. credential.CredentialBlob = Marshal.StringToCoTaskMemUni(secret);
  65. credential.UserName = Marshal.StringToCoTaskMemUni(userName ?? Environment.UserName);
  66.  
  67. bool written = CredWrite(ref credential, 0);
  68. Marshal.FreeCoTaskMem(credential.TargetName);
  69. Marshal.FreeCoTaskMem(credential.CredentialBlob);
  70. Marshal.FreeCoTaskMem(credential.UserName);
  71.  
  72. if (!written)
  73. {
  74. int lastError = Marshal.GetLastWin32Error();
  75. throw new Exception(string.Format("CredWrite failed with the error code {0}.", lastError));
  76. }
  77. }
  78.  
  79. public static IReadOnlyList<Credential> EnumerateCrendentials()
  80. {
  81. List<Credential> result = new List<Credential>();
  82.  
  83. int count;
  84. IntPtr pCredentials;
  85. bool ret = CredEnumerate(null, 0, out count, out pCredentials);
  86. if (ret)
  87. {
  88. for (int n = 0; n < count; n++)
  89. {
  90. IntPtr credential = Marshal.ReadIntPtr(pCredentials, n * Marshal.SizeOf(typeof(IntPtr)));
  91. result.Add(ReadCredential((CREDENTIAL)Marshal.PtrToStructure(credential, typeof(CREDENTIAL))));
  92. }
  93. }
  94. else
  95. {
  96. int lastError = Marshal.GetLastWin32Error();
  97. throw new Win32Exception(lastError);
  98. }
  99.  
  100. return result;
  101. }
  102.  
  103. [DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
  104. static extern bool CredRead(string target, CredentialType type, int reservedFlag, out IntPtr credentialPtr);
  105.  
  106. [DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
  107. static extern bool CredWrite([In] ref CREDENTIAL userCredential, [In] UInt32 flags);
  108.  
  109. [DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
  110. static extern bool CredEnumerate(string filter, int flag, out int count, out IntPtr pCredentials);
  111.  
  112. [DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
  113. static extern bool CredFree([In] IntPtr cred);
  114.  
  115. private enum CredentialPersistence : uint
  116. {
  117. Session = 1,
  118. LocalMachine,
  119. Enterprise
  120. }
  121.  
  122. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  123. private struct CREDENTIAL
  124. {
  125. public uint Flags;
  126. public CredentialType Type;
  127. public IntPtr TargetName;
  128. public IntPtr Comment;
  129. public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
  130. public uint CredentialBlobSize;
  131. public IntPtr CredentialBlob;
  132. public uint Persist;
  133. public uint AttributeCount;
  134. public IntPtr Attributes;
  135. public IntPtr TargetAlias;
  136. public IntPtr UserName;
  137. }
  138.  
  139. sealed class CriticalCredentialHandle : CriticalHandleZeroOrMinusOneIsInvalid
  140. {
  141. public CriticalCredentialHandle(IntPtr preexistingHandle)
  142. {
  143. SetHandle(preexistingHandle);
  144. }
  145.  
  146. public CREDENTIAL GetCredential()
  147. {
  148. if (!IsInvalid)
  149. {
  150. CREDENTIAL credential = (CREDENTIAL)Marshal.PtrToStructure(handle, typeof(CREDENTIAL));
  151. return credential;
  152. }
  153.  
  154. throw new InvalidOperationException("Invalid CriticalHandle!");
  155. }
  156.  
  157. protected override bool ReleaseHandle()
  158. {
  159. if (!IsInvalid)
  160. {
  161. CredFree(handle);
  162. SetHandleAsInvalid();
  163. return true;
  164. }
  165.  
  166. return false;
  167. }
  168. }
  169. }
  170.  
  171. public enum CredentialType
  172. {
  173. Generic = 1,
  174. DomainPassword,
  175. DomainCertificate,
  176. DomainVisiblePassword,
  177. GenericCertificate,
  178. DomainExtended,
  179. Maximum,
  180. MaximumEx = Maximum + 1000,
  181. }
  182.  
  183. public class Credential
  184. {
  185. private readonly string _applicationName;
  186. private readonly string _userName;
  187. private readonly string _password;
  188. private readonly CredentialType _credentialType;
  189.  
  190. public CredentialType CredentialType
  191. {
  192. get { return _credentialType; }
  193. }
  194.  
  195. public string ApplicationName
  196. {
  197. get { return _applicationName; }
  198. }
  199.  
  200. public string UserName
  201. {
  202. get { return _userName; }
  203. }
  204.  
  205. public string Password
  206. {
  207. get { return _password; }
  208. }
  209.  
  210. public Credential(CredentialType credentialType, string applicationName, string userName, string password)
  211. {
  212. _applicationName = applicationName;
  213. _userName = userName;
  214. _password = password;
  215. _credentialType = credentialType;
  216. }
  217.  
  218. public override string ToString()
  219. {
  220. return string.Format("CredentialType: {0}, ApplicationName: {1}, UserName: {2}, Password: {3}", CredentialType, ApplicationName, UserName, Password);
  221. }
  222. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement