Advertisement
Guest User

Untitled

a guest
Mar 5th, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.41 KB | None | 0 0
  1. using System;
  2. using System.Net;
  3. using System.Runtime.InteropServices;
  4. using System.Text;
  5.  
  6. namespace SMM.Helper
  7. {
  8. public static class CredentialsUI
  9. {
  10. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  11. private struct CREDUI_INFO
  12. {
  13. public int cbSize;
  14. public IntPtr hwndParent;
  15. public string pszMessageText;
  16. public string pszCaptionText;
  17. public IntPtr hbmBanner;
  18. }
  19.  
  20. [Flags]
  21. private enum PromptForWindowsCredentialsFlags
  22. {
  23. /// <summary>
  24. /// The caller is requesting that the credential provider return the user name and password in plain text.
  25. /// This value cannot be combined with SECURE_PROMPT.
  26. /// </summary>
  27. CREDUIWIN_GENERIC = 0x1,
  28. /// <summary>
  29. /// The Save check box is displayed in the dialog box.
  30. /// </summary>
  31. CREDUIWIN_CHECKBOX = 0x2,
  32. /// <summary>
  33. /// Only credential providers that support the authentication package specified by the authPackage parameter should be enumerated.
  34. /// This value cannot be combined with CREDUIWIN_IN_CRED_ONLY.
  35. /// </summary>
  36. CREDUIWIN_AUTHPACKAGE_ONLY = 0x10,
  37. /// <summary>
  38. /// Only the credentials specified by the InAuthBuffer parameter for the authentication package specified by the authPackage parameter should be enumerated.
  39. /// If this flag is set, and the InAuthBuffer parameter is NULL, the function fails.
  40. /// This value cannot be combined with CREDUIWIN_AUTHPACKAGE_ONLY.
  41. /// </summary>
  42. CREDUIWIN_IN_CRED_ONLY = 0x20,
  43. /// <summary>
  44. /// Credential providers should enumerate only administrators. This value is intended for User Account Control (UAC) purposes only. We recommend that external callers not set this flag.
  45. /// </summary>
  46. CREDUIWIN_ENUMERATE_ADMINS = 0x100,
  47. /// <summary>
  48. /// Only the incoming credentials for the authentication package specified by the authPackage parameter should be enumerated.
  49. /// </summary>
  50. CREDUIWIN_ENUMERATE_CURRENT_USER = 0x200,
  51. /// <summary>
  52. /// The credential dialog box should be displayed on the secure desktop. This value cannot be combined with CREDUIWIN_GENERIC.
  53. /// Windows Vista: This value is not supported until Windows Vista with SP1.
  54. /// </summary>
  55. CREDUIWIN_SECURE_PROMPT = 0x1000,
  56. /// <summary>
  57. /// The credential provider should align the credential BLOB pointed to by the refOutAuthBuffer parameter to a 32-bit boundary, even if the provider is running on a 64-bit system.
  58. /// </summary>
  59. CREDUIWIN_PACK_32_WOW = 0x10000000,
  60. }
  61.  
  62. [DllImport("ole32.dll")]
  63. private static extern void CoTaskMemFree(IntPtr ptr);
  64.  
  65. [DllImport("credui.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  66. private static extern Boolean CredPackAuthenticationBuffer(
  67. int dwFlags,
  68. string pszUserName,
  69. string pszPassword,
  70. IntPtr pPackedCredentials,
  71. ref int pcbPackedCredentials);
  72.  
  73. [DllImport("credui.dll", CharSet = CharSet.Unicode)]
  74. private static extern uint CredUIPromptForWindowsCredentials(ref CREDUI_INFO notUsedHere,
  75. int authError,
  76. ref uint authPackage,
  77. IntPtr InAuthBuffer,
  78. uint InAuthBufferSize,
  79. out IntPtr refOutAuthBuffer,
  80. out uint refOutAuthBufferSize,
  81. ref bool fSave,
  82. PromptForWindowsCredentialsFlags flags);
  83.  
  84. [DllImport("credui.dll", CharSet = CharSet.Auto)]
  85. private static extern bool CredUnPackAuthenticationBuffer(int dwFlags,
  86. IntPtr pAuthBuffer, uint cbAuthBuffer,
  87. StringBuilder pszUserName,
  88. ref int pcchMaxUserName,
  89. StringBuilder pszDomainName,
  90. ref int pcchMaxDomainame,
  91. StringBuilder pszPassword,
  92. ref int pcchMaxPassword);
  93.  
  94. public static NetworkCredential PromptForCreds(string PromptCaption = "Credentials needed", string PromptMessage = "Please enter your username and password")
  95. {
  96. bool save = false;
  97. int errorcode = 0;
  98. uint dialogReturn;
  99. uint authPackage = 0;
  100. IntPtr outCredBuffer = IntPtr.Zero;
  101. uint outCredSize;
  102.  
  103. try
  104. {
  105. CREDUI_INFO credui = new CREDUI_INFO();
  106. credui.cbSize = Marshal.SizeOf(credui);
  107. credui.pszCaptionText = PromptCaption;
  108. credui.pszMessageText = PromptMessage;
  109. IntPtr hwnd = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
  110. if (hwnd != IntPtr.Zero) credui.hwndParent = hwnd;
  111.  
  112. int maxUserName = 256;
  113. int maxDomain = 100;
  114. int maxPassword = 127; // Windows 10 max
  115. var usernameBuf = new StringBuilder(maxUserName);
  116. var domainBuf = new StringBuilder(maxDomain);
  117. var passwordBuf = new StringBuilder(maxPassword);
  118.  
  119. while (true) //Show the dialog again and again, until Cancel is clicked or the entered credentials are correct.
  120. {
  121. //Show the dialog
  122. dialogReturn = CredUIPromptForWindowsCredentials(ref credui,
  123. errorcode,
  124. ref authPackage,
  125. (IntPtr)0, //You can force that a specific username is shown in the dialog. Create it with 'CredPackAuthenticationBuffer()'. Then, the buffer goes here...
  126. 0, //...and the size goes here. You also have to add CREDUIWIN_IN_CRED_ONLY to the flags (last argument).
  127. out outCredBuffer,
  128. out outCredSize,
  129. ref save,
  130. 0); //Use the PromptForWindowsCredentialsFlags-Enum here. You can use multiple flags if you seperate them with | .
  131.  
  132. if (dialogReturn != 0) break; //Break, if Cancel was clicked or an error occurred
  133.  
  134.  
  135. /*Unpack your credentials (outCredBuffer, outCredSize) with 'CredUnPackAuthenticationBuffer()'
  136. For example, it returns a bool 'credentialsEnteredCorrect':*/
  137. NetworkCredential netCredential;
  138. if (CredUnPackAuthenticationBuffer(0, outCredBuffer, outCredSize, usernameBuf, ref maxUserName, domainBuf, ref maxDomain, passwordBuf, ref maxPassword))
  139. {
  140. //clear the memory allocated by CredUIPromptForWindowsCredentials
  141.  
  142. netCredential = new NetworkCredential()
  143. {
  144. UserName = usernameBuf.ToString(),
  145. Password = passwordBuf.ToString(),
  146. Domain = domainBuf.ToString()
  147. };
  148. return netCredential;
  149. }
  150. }
  151. }
  152. catch (Exception e)
  153. {
  154. throw e; // Caller needs to handle this, only here so we can release the buffer in finally
  155. }
  156. finally
  157. {
  158. if (outCredBuffer != IntPtr.Zero) CoTaskMemFree(outCredBuffer);
  159. }
  160. return null;
  161.  
  162. }
  163. }
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement