using Microsoft.Win32;
using System;
using System.Security.Principal;
using System.Threading;
using System.Windows.Forms;
namespace PaintDotNet.SystemLayer
{
///
/// Security related static methods and properties.
///
public static class Security
{
private static bool isAdmin = GetIsAdministrator();
private static bool GetIsAdministrator()
{
AppDomain domain = Thread.GetDomain();
domain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsPrincipal principal = (WindowsPrincipal)Thread.CurrentPrincipal;
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
///
/// Gets a flag indicating whether the user has administrator-level privileges.
///
///
/// This is used to control access to actions that require the user to be an administrator.
/// An example is checking for and installing updates, actions which are not normally able
/// to be performed by normal or "limited" users. A user must also be an administrator in
/// order to write to any Settings.SystemWide entries.
///
public static bool IsAdministrator
{
get
{
return isAdmin;
}
}
///
/// Gets a flag indicating whether the current user is able to elevate to obtain
/// administrator-level privileges.
///
///
/// This flag has no meaning if IsAdministrator returns true.
/// This flag indicates whether a new process may be spawned which has administrator
/// privilege. It does not indicate the ability to elevate the current process to
/// administrator privilege. For Windows this indicates that the user is running
/// Vista and has UAC enabled. This property should be used instead of checking
/// the OS version anytime this check must be performed.
/// Note to implementors: This may be written to simply return false.
///
public static bool CanElevateToAdministrator
{
get
{
if (OS.IsVistaOrLater && !Security.IsAdministrator)
{
return IsUacEnabled;
}
else
{
return false;
}
}
}
private static bool IsUacEnabled
{
get
{
bool returnVal = false;
const string keyName = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
const string valueName = "EnableLUA";
try
{
if (Environment.OSVersion.Version >= OS.WindowsVista)
{
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, false))
{
if (key != null)
{
RegistryValueKind valueKind = key.GetValueKind(valueName);
if (valueKind == RegistryValueKind.DWord)
{
int value = unchecked((int)key.GetValue(valueName));
returnVal = (value == 1);
}
}
}
}
}
catch (Exception ex)
{
Tracing.Ping(ex.ToString());
returnVal = false;
}
return returnVal;
}
}
///
/// If IsAdministrator is true, this returns true if we can launch a process with limited privilege.
///
///
/// Here's the truth table for this:
/// Windows XP + Admin User -> false
/// Windows XP + Standard User -> true
/// Windows Vista + Admin User + UAC Enabled -> true
/// Windows Vista + Admin User + UAC Disabled -> false
/// Windows Vista + Standard User -> true
///
public static bool CanLaunchNonAdminProcess
{
get
{
if (!Security.IsAdministrator)
{
return true;
}
else if (OS.IsVistaOrLater)
{
return Security.IsUacEnabled;
}
else
{
return false;
}
}
}
///
/// Verifies that a file has a valid digital signature.
///
/// The parent/owner window for any UI that may be shown.
/// The path to the file to be validate.
/// Whether or not to show a UI in the case that the signature can not be found or validated.
/// Whether or not to show a UI in the case that the signature is successfully found and validated.
/// true if the file has a digital signature that validates up to a trusted root, or false otherwise
public static bool VerifySignedFile(IWin32Window owner, string fileName, bool showNegativeUI, bool showPositiveUI)
{
unsafe
{
fixed (char* szFileName = fileName)
{
Guid pgActionID = NativeConstants.WINTRUST_ACTION_GENERIC_VERIFY_V2;
NativeStructs.WINTRUST_FILE_INFO fileInfo = new NativeStructs.WINTRUST_FILE_INFO();
fileInfo.cbStruct = (uint)sizeof(NativeStructs.WINTRUST_FILE_INFO);
fileInfo.pcwszFilePath = szFileName;
NativeStructs.WINTRUST_DATA wintrustData = new NativeStructs.WINTRUST_DATA();
wintrustData.cbStruct = (uint)sizeof(NativeStructs.WINTRUST_DATA);
if (!showNegativeUI && !showPositiveUI)
{
wintrustData.dwUIChoice = NativeConstants.WTD_UI_NONE;
}
else if (!showNegativeUI && showPositiveUI)
{
wintrustData.dwUIChoice = NativeConstants.WTD_UI_NOBAD;
}
else if (showNegativeUI && !showPositiveUI)
{
wintrustData.dwUIChoice = NativeConstants.WTD_UI_NOGOOD;
}
else // if (showNegativeUI && showPositiveUI)
{
wintrustData.dwUIChoice = NativeConstants.WTD_UI_ALL;
}
wintrustData.fdwRevocationChecks = NativeConstants.WTD_REVOKE_WHOLECHAIN;
wintrustData.dwUnionChoice = NativeConstants.WTD_CHOICE_FILE;
wintrustData.pInfo = (void*)&fileInfo;
IntPtr handle;
if (owner == null)
{
handle = IntPtr.Zero;
}
else
{
handle = owner.Handle;
}
int result = NativeMethods.WinVerifyTrust(handle, ref pgActionID, ref wintrustData);
GC.KeepAlive(owner);
return result >= 0;
}
}
}
}
}