Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.47 KB | None | 0 0
  1. // Copyright (c) 2014, Joel Bennett
  2. // Licensed under MIT license
  3. using System;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using Microsoft.Win32.SafeHandles;
  7. using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
  8.  
  9. namespace CredentialManagement
  10. {
  11. using System.Management.Automation;
  12. using System.Security;
  13.  
  14. public enum CredentialType : uint
  15. {
  16. None = 0,
  17. Generic = 1,
  18. DomainPassword = 2,
  19. DomainCertificate = 3,
  20. DomainVisiblePassword = 4,
  21. GenericCertificate = 5,
  22. DomainExtended = 6,
  23. Maximum = 7,
  24. MaximumEx = 1007
  25. }
  26.  
  27. public enum PersistanceType : uint
  28. {
  29. Session = 1,
  30. LocalComputer = 2,
  31. Enterprise = 3
  32. }
  33.  
  34. public static class SecureStringHelper
  35. {
  36. // Methods
  37. public static SecureString CreateSecureString(string plainString)
  38. {
  39. var result = new SecureString();
  40. if (!string.IsNullOrEmpty(plainString))
  41. {
  42. foreach (var c in plainString.ToCharArray())
  43. {
  44. result.AppendChar(c);
  45. }
  46. }
  47. result.MakeReadOnly();
  48. return result;
  49. }
  50.  
  51. public static SecureString CreateSecureString(IntPtr ptrToString, int length = 0)
  52. {
  53. string password = length > 0
  54. ? Marshal.PtrToStringUni(ptrToString, length)
  55. : Marshal.PtrToStringUni(ptrToString);
  56. return CreateSecureString(password);
  57. }
  58.  
  59. public static string CreateString(SecureString secureString)
  60. {
  61. string str;
  62. IntPtr zero = IntPtr.Zero;
  63. if ((secureString == null) || (secureString.Length == 0))
  64. {
  65. return string.Empty;
  66. }
  67. try
  68. {
  69. zero = Marshal.SecureStringToBSTR(secureString);
  70. str = Marshal.PtrToStringBSTR(zero);
  71. }
  72. finally
  73. {
  74. if (zero != IntPtr.Zero)
  75. {
  76. Marshal.ZeroFreeBSTR(zero);
  77. }
  78. }
  79. return str;
  80. }
  81. }
  82.  
  83. public static class IntPtrExtensions
  84. {
  85. public static IntPtr Increment(this IntPtr ptr, int cbSize)
  86. {
  87. return new IntPtr(ptr.ToInt64() + cbSize);
  88. }
  89.  
  90. public static IntPtr Increment<T>(this IntPtr ptr)
  91. {
  92. return ptr.Increment(Marshal.SizeOf(typeof(T)));
  93. }
  94.  
  95. public static T ElementAt<T>(this IntPtr ptr, int index)
  96. {
  97. var offset = Marshal.SizeOf(typeof(T))*index;
  98. var offsetPtr = ptr.Increment(offset);
  99. return (T)Marshal.PtrToStructure(offsetPtr, typeof(T));
  100. }
  101. }
  102.  
  103. public static class Store
  104. {
  105.  
  106. public static PSObject Load(string target, CredentialType type = CredentialType.Generic, bool fix = true)
  107. {
  108. PSObject cred;
  109. if(fix) {
  110. target = FixTarget(target);
  111. }
  112. NativeMethods.CredRead(target, type, 0, out cred);
  113.  
  114. return cred;
  115. }
  116.  
  117. private static string FixTarget(string target)
  118. {
  119. if (!target.Contains("/"))
  120. {
  121. if (target.Contains("="))
  122. {
  123. target = "MicrosoftPowerShell/" + target;
  124. }
  125. else
  126. {
  127. target = "MicrosoftPowerShell/user=" + target;
  128. }
  129. }
  130. return target;
  131. }
  132.  
  133. public static PSObject[] Enumerate(string filter = "")
  134. {
  135. uint count = 0;
  136. int Flag = 0;
  137. IntPtr credentialArray = IntPtr.Zero;
  138. PSObject[] output = null;
  139.  
  140. if(string.IsNullOrEmpty(filter)) {
  141. filter = null;
  142. Flag = 1;
  143. }
  144.  
  145. NativeMethods.PSCredentialMarshaler helper = new NativeMethods.PSCredentialMarshaler();
  146.  
  147. if(NativeMethods.CredEnumerate(filter, Flag, out count, out credentialArray)) {
  148. IntPtr cred = IntPtr.Zero;
  149. output = new PSObject[count];
  150. for (int n = 0; n < count; n++)
  151. {
  152. cred = credentialArray.ElementAt<IntPtr>(n);
  153. output[n] = (PSObject)helper.MarshalNativeToManaged(cred);
  154. }
  155. helper.CleanUpNativeData(credentialArray);
  156. }
  157. return output;
  158. }
  159.  
  160. public static NativeMethods.CREDErrorCodes Save(PSObject credential)
  161. {
  162. var cred = credential.BaseObject as PSCredential;
  163. if (cred == null)
  164. {
  165. throw new ArgumentException("Credential object does not contain a PSCredential");
  166. }
  167.  
  168. if (!NativeMethods.CredWrite(credential, 0))
  169. {
  170. return (NativeMethods.CREDErrorCodes)Marshal.GetLastWin32Error();
  171. }
  172. else return NativeMethods.CREDErrorCodes.NO_ERROR;
  173. }
  174.  
  175. public static NativeMethods.CREDErrorCodes Delete(string target, CredentialType type = CredentialType.Generic)
  176. {
  177. if (!NativeMethods.CredDelete(FixTarget(target), type, 0))
  178. {
  179. return (NativeMethods.CREDErrorCodes)Marshal.GetLastWin32Error();
  180. }
  181. else return NativeMethods.CREDErrorCodes.NO_ERROR;
  182. }
  183. }
  184.  
  185.  
  186. public class NativeMethods
  187. {
  188. public enum CREDErrorCodes
  189. {
  190. NO_ERROR = 0,
  191. ERROR_NOT_FOUND = 1168,
  192. ERROR_NO_SUCH_LOGON_SESSION = 1312,
  193. ERROR_INVALID_PARAMETER = 87,
  194. ERROR_INVALID_FLAGS = 1004,
  195. ERROR_BAD_USERNAME = 2202,
  196. SCARD_E_NO_READERS_AVAILABLE = (int)(0x8010002E - 0x100000000),
  197. SCARD_E_NO_SMARTCARD = (int)(0x8010000C - 0x100000000),
  198. SCARD_W_REMOVED_CARD = (int)(0x80100069 - 0x100000000),
  199. SCARD_W_WRONG_CHV = (int)(0x8010006B - 0x100000000)
  200. }
  201.  
  202. [DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
  203. public static extern bool CredRead(string target, CredentialType type, int reservedFlag,
  204. [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PSCredentialMarshaler))]
  205. out PSObject credentialout);
  206.  
  207. [DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
  208. public static extern bool CredWrite([In]
  209. [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(PSCredentialMarshaler))]
  210. PSObject userCredential, [In] UInt32 flags);
  211.  
  212. [DllImport("advapi32.dll", EntryPoint = "CredDeleteW", CharSet = CharSet.Unicode, SetLastError = true)]
  213. public static extern bool CredDelete(string target, CredentialType type, int flags);
  214.  
  215. [DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
  216. public static extern bool CredFree([In] IntPtr cred);
  217.  
  218. [DllImport("advapi32.dll", EntryPoint = "CredEnumerateW", CharSet = CharSet.Unicode, SetLastError = true)]
  219. public static extern bool CredEnumerate(string filter, int flag, out uint count, out IntPtr pCredentials);
  220.  
  221. [DllImport("ole32.dll")]
  222. public static extern void CoTaskMemFree(IntPtr ptr);
  223.  
  224.  
  225. public class PSCredentialMarshaler : ICustomMarshaler
  226. {
  227. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  228. private class NATIVECREDENTIAL
  229. {
  230. public UInt32 Flags;
  231. public CredentialType Type = CredentialType.Generic;
  232. public string TargetName;
  233. public string Comment;
  234. public FILETIME LastWritten;
  235. public UInt32 CredentialBlobSize;
  236. public IntPtr CredentialBlob;
  237. public PersistanceType Persist = PersistanceType.Enterprise;
  238. public UInt32 AttributeCount;
  239. public IntPtr Attributes;
  240. public string TargetAlias;
  241. public string UserName;
  242. }
  243.  
  244. public void CleanUpManagedData(object ManagedObj)
  245. {
  246. // Nothing to do since all data can be garbage collected.
  247. }
  248.  
  249. public void CleanUpNativeData(IntPtr pNativeData)
  250. {
  251. if (pNativeData == IntPtr.Zero)
  252. {
  253. return;
  254. }
  255. CredFree(pNativeData);
  256. }
  257.  
  258. public int GetNativeDataSize()
  259. {
  260. return Marshal.SizeOf(typeof(NATIVECREDENTIAL));
  261. }
  262.  
  263. public IntPtr MarshalManagedToNative(object obj)
  264. {
  265. PSCredential credential;
  266. PSObject credo = obj as PSObject;
  267. if (credo != null)
  268. {
  269. credential = credo.BaseObject as PSCredential;
  270. }
  271. else
  272. {
  273. credential = obj as PSCredential;
  274. }
  275.  
  276. if (credential == null)
  277. {
  278. Console.WriteLine("Error: Can't convert!");
  279. return IntPtr.Zero;
  280. }
  281. var nCred = new NATIVECREDENTIAL()
  282. {
  283. UserName = credential.UserName,
  284. CredentialBlob = Marshal.SecureStringToCoTaskMemUnicode(credential.Password),
  285. CredentialBlobSize = (uint)credential.Password.Length * 2,
  286. TargetName = "MicrosoftPowerShell:user=" + credential.UserName,
  287. Type = CredentialType.Generic,
  288. Persist = PersistanceType.Enterprise
  289. };
  290.  
  291. if (credo != null)
  292. {
  293. foreach (var m in credo.Members)
  294. {
  295. switch (m.Name)
  296. {
  297. case "Target":
  298. if (m.Value != null)
  299. nCred.TargetName = m.Value.ToString();
  300. break;
  301. case "TargetAlias":
  302. if (m.Value != null)
  303. nCred.TargetAlias = m.Value.ToString();
  304. break;
  305. case "Type":
  306. if (m.Value != null)
  307. nCred.Type = (CredentialType)m.Value;
  308. break;
  309. case "Persistence":
  310. if (m.Value != null)
  311. nCred.Persist = (PersistanceType)m.Value;
  312. break;
  313. case "Description":
  314. if (m.Value != null)
  315. nCred.Comment = m.Value.ToString();
  316. break;
  317. case "LastWriteTime":
  318. // ignored
  319. break;
  320. }
  321. }
  322. }
  323. IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(nCred));
  324. Marshal.StructureToPtr(nCred, ptr, false);
  325. return ptr;
  326. }
  327.  
  328. public object MarshalNativeToManaged(IntPtr pNativeData)
  329. {
  330. if (pNativeData == IntPtr.Zero)
  331. {
  332. return null;
  333. }
  334.  
  335. var ncred = (NATIVECREDENTIAL)Marshal.PtrToStructure(pNativeData, typeof(NATIVECREDENTIAL));
  336.  
  337. var securePass = (ncred.CredentialBlob == IntPtr.Zero) ? new SecureString()
  338. : SecureStringHelper.CreateSecureString(ncred.CredentialBlob, (int)(ncred.CredentialBlobSize)/2);
  339.  
  340. var credEx = new PSObject(new PSCredential(ncred.UserName, securePass));
  341.  
  342. credEx.Members.Add(new PSNoteProperty("Target", ncred.TargetName));
  343. credEx.Members.Add(new PSNoteProperty("TargetAlias", ncred.TargetAlias));
  344. credEx.Members.Add(new PSNoteProperty("Type", (CredentialType)ncred.Type));
  345. credEx.Members.Add(new PSNoteProperty("Persistence", (PersistanceType)ncred.Persist));
  346. credEx.Members.Add(new PSNoteProperty("Description", ncred.Comment));
  347. credEx.Members.Add(new PSNoteProperty("LastWriteTime", DateTime.FromFileTime((((long)ncred.LastWritten.dwHighDateTime) << 32) + ncred.LastWritten.dwLowDateTime)));
  348.  
  349. return credEx;
  350. }
  351.  
  352. public static ICustomMarshaler GetInstance(string cookie)
  353. {
  354. return new PSCredentialMarshaler();
  355. }
  356. }
  357.  
  358. }
  359. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement