public DesktopSecurity(Desktop desktop, AccessControlSections includeSections) : base(false /* isContainer */, ResourceType.WindowObject, desktop, includeSections) { this.desktop = desktop; }
/// <summary> /// Creates a new desktop with minimal rights. /// </summary> /// <param name="tracer">A tracer instance.</param> /// <returns>The desktop instance.</returns> public static Desktop Create(ITracer tracer, string mandatoryLevelSacl) { using (var disposalEscrow = new DisposalEscrow()) using (Desktop currentDesktop = Desktop.GetCurrent()) { try { string name = "sbox" + DateTime.UtcNow.Ticks; tracer.Trace(nameof(Desktop), "Creating desktop '{0}'", name); SECURITY_ATTRIBUTES securityAttributes = null; if (mandatoryLevelSacl != null) { tracer.Trace(nameof(Desktop), "Generating security attributes for '{0}'", mandatoryLevelSacl); // If a security descriptor (in SDDL form) was provided convert it to binary form and then marshal // it into native memory to that we can pass it in to the native method. var rawSecurityDescriptor = new RawSecurityDescriptor(mandatoryLevelSacl); var binaryForm = new byte[rawSecurityDescriptor.BinaryLength]; rawSecurityDescriptor.GetBinaryForm(binaryForm, 0 /* offset */); var nativeBinaryForm = disposalEscrow.Add(new SafeHGlobalBuffer(binaryForm.Length)); Marshal.Copy(binaryForm, 0 /* startIndex */, nativeBinaryForm.DangerousGetHandle(), binaryForm.Length); securityAttributes = new SECURITY_ATTRIBUTES { lpSecurityDescriptor = nativeBinaryForm.DangerousGetHandle() }; } // Since we're creating the desktop we'll ask for all rights so that we have the ability to modify security as // required. Since the created desktop will be referenced by name when creating the process this will not impact // the security of the desktop. IntPtr unsafeDesktopHandle = Methods.CreateDesktop( name, device: null, deviceMode: null, flags: 0, accessMask: DESKTOP_RIGHTS.GENERIC_ALL, attributes: securityAttributes); if (unsafeDesktopHandle == IntPtr.Zero) { throw new SandboxException( $"Unable to create new desktop", new Win32Exception()); } tracer.Trace(nameof(Desktop), "Desktop successfully created"); return(new Desktop(unsafeDesktopHandle, ownsHandle: true) { Name = name, }); } finally { // Since CreateDesktop automatically switches to the new desktop we need to make sure that we switch back // to the original one. currentDesktop.MakeCurrent(); } } }