Security.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. using Microsoft.Win32;
  2. using System;
  3. using System.Security.Principal;
  4. using System.Threading;
  5. using System.Windows.Forms;
  6. namespace PaintDotNet.SystemLayer
  7. {
  8. /// <summary>
  9. /// Security related static methods and properties.
  10. /// </summary>
  11. public static class Security
  12. {
  13. private static bool isAdmin = GetIsAdministrator();
  14. private static bool GetIsAdministrator()
  15. {
  16. AppDomain domain = Thread.GetDomain();
  17. domain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
  18. WindowsPrincipal principal = (WindowsPrincipal)Thread.CurrentPrincipal;
  19. return principal.IsInRole(WindowsBuiltInRole.Administrator);
  20. }
  21. /// <summary>
  22. /// Gets a flag indicating whether the user has administrator-level privileges.
  23. /// </summary>
  24. /// <remarks>
  25. /// This is used to control access to actions that require the user to be an administrator.
  26. /// An example is checking for and installing updates, actions which are not normally able
  27. /// to be performed by normal or "limited" users. A user must also be an administrator in
  28. /// order to write to any Settings.SystemWide entries.
  29. /// </remarks>
  30. public static bool IsAdministrator
  31. {
  32. get
  33. {
  34. return isAdmin;
  35. }
  36. }
  37. /// <summary>
  38. /// Gets a flag indicating whether the current user is able to elevate to obtain
  39. /// administrator-level privileges.
  40. /// </summary>
  41. /// <remarks>
  42. /// This flag has no meaning if IsAdministrator returns true.
  43. /// This flag indicates whether a new process may be spawned which has administrator
  44. /// privilege. It does not indicate the ability to elevate the current process to
  45. /// administrator privilege. For Windows this indicates that the user is running
  46. /// Vista and has UAC enabled. This property should be used instead of checking
  47. /// the OS version anytime this check must be performed.
  48. /// Note to implementors: This may be written to simply return false.
  49. /// </remarks>
  50. public static bool CanElevateToAdministrator
  51. {
  52. get
  53. {
  54. if (OS.IsVistaOrLater && !Security.IsAdministrator)
  55. {
  56. return IsUacEnabled;
  57. }
  58. else
  59. {
  60. return false;
  61. }
  62. }
  63. }
  64. private static bool IsUacEnabled
  65. {
  66. get
  67. {
  68. bool returnVal = false;
  69. const string keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
  70. const string valueName = "EnableLUA";
  71. try
  72. {
  73. if (Environment.OSVersion.Version >= OS.WindowsVista)
  74. {
  75. using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, false))
  76. {
  77. if (key != null)
  78. {
  79. RegistryValueKind valueKind = key.GetValueKind(valueName);
  80. if (valueKind == RegistryValueKind.DWord)
  81. {
  82. int value = unchecked((int)key.GetValue(valueName));
  83. returnVal = (value == 1);
  84. }
  85. }
  86. }
  87. }
  88. }
  89. catch (Exception ex)
  90. {
  91. Tracing.Ping(ex.ToString());
  92. returnVal = false;
  93. }
  94. return returnVal;
  95. }
  96. }
  97. /// <summary>
  98. /// If IsAdministrator is true, this returns true if we can launch a process with limited privilege.
  99. /// </summary>
  100. /// <remarks>
  101. /// Here's the truth table for this:
  102. /// Windows XP + Admin User -> false
  103. /// Windows XP + Standard User -> true
  104. /// Windows Vista + Admin User + UAC Enabled -> true
  105. /// Windows Vista + Admin User + UAC Disabled -> false
  106. /// Windows Vista + Standard User -> true
  107. /// </remarks>
  108. public static bool CanLaunchNonAdminProcess
  109. {
  110. get
  111. {
  112. if (!Security.IsAdministrator)
  113. {
  114. return true;
  115. }
  116. else if (OS.IsVistaOrLater)
  117. {
  118. return Security.IsUacEnabled;
  119. }
  120. else
  121. {
  122. return false;
  123. }
  124. }
  125. }
  126. /// <summary>
  127. /// Verifies that a file has a valid digital signature.
  128. /// </summary>
  129. /// <param name="owner">The parent/owner window for any UI that may be shown.</param>
  130. /// <param name="fileName">The path to the file to be validate.</param>
  131. /// <param name="showNegativeUI">Whether or not to show a UI in the case that the signature can not be found or validated.</param>
  132. /// <param name="showPositiveUI">Whether or not to show a UI in the case that the signature is successfully found and validated.</param>
  133. /// <returns>true if the file has a digital signature that validates up to a trusted root, or false otherwise</returns>
  134. public static bool VerifySignedFile(IWin32Window owner, string fileName, bool showNegativeUI, bool showPositiveUI)
  135. {
  136. unsafe
  137. {
  138. fixed (char* szFileName = fileName)
  139. {
  140. Guid pgActionID = NativeConstants.WINTRUST_ACTION_GENERIC_VERIFY_V2;
  141. NativeStructs.WINTRUST_FILE_INFO fileInfo = new NativeStructs.WINTRUST_FILE_INFO();
  142. fileInfo.cbStruct = (uint)sizeof(NativeStructs.WINTRUST_FILE_INFO);
  143. fileInfo.pcwszFilePath = szFileName;
  144. NativeStructs.WINTRUST_DATA wintrustData = new NativeStructs.WINTRUST_DATA();
  145. wintrustData.cbStruct = (uint)sizeof(NativeStructs.WINTRUST_DATA);
  146. if (!showNegativeUI && !showPositiveUI)
  147. {
  148. wintrustData.dwUIChoice = NativeConstants.WTD_UI_NONE;
  149. }
  150. else if (!showNegativeUI && showPositiveUI)
  151. {
  152. wintrustData.dwUIChoice = NativeConstants.WTD_UI_NOBAD;
  153. }
  154. else if (showNegativeUI && !showPositiveUI)
  155. {
  156. wintrustData.dwUIChoice = NativeConstants.WTD_UI_NOGOOD;
  157. }
  158. else // if (showNegativeUI && showPositiveUI)
  159. {
  160. wintrustData.dwUIChoice = NativeConstants.WTD_UI_ALL;
  161. }
  162. wintrustData.fdwRevocationChecks = NativeConstants.WTD_REVOKE_WHOLECHAIN;
  163. wintrustData.dwUnionChoice = NativeConstants.WTD_CHOICE_FILE;
  164. wintrustData.pInfo = (void*)&fileInfo;
  165. IntPtr handle;
  166. if (owner == null)
  167. {
  168. handle = IntPtr.Zero;
  169. }
  170. else
  171. {
  172. handle = owner.Handle;
  173. }
  174. int result = NativeMethods.WinVerifyTrust(handle, ref pgActionID, ref wintrustData);
  175. GC.KeepAlive(owner);
  176. return result >= 0;
  177. }
  178. }
  179. }
  180. }
  181. }