Exemple #1
0
        public Process InitializeProcess(string filename, string arguments, bool interactive, Dictionary <string, string> extraEnvironmentVariables)
        {
            // C with Win32 API example to start a process under a different user: http://msdn.microsoft.com/en-us/library/aa379608%28VS.85%29.aspx

            if (!this.isLocked)
            {
                throw new InvalidOperationException("This prison has to be locked before you can use it.");
            }


            this.InitializeLogonToken();
            this.LoadUserProfileIfNotLoaded();

            var envs = GetDefaultEnvironmentVarialbes();

            // environmentVariables from the method parameters have precedence over the default envs
            if (extraEnvironmentVariables != null)
            {
                foreach (var env in extraEnvironmentVariables)
                {
                    envs[env.Key] = env.Value;
                }
            }

            string envBlock = extraEnvironmentVariables == null ? null : Prison.BuildEnvironmentVariable(envs);

            Logger.Debug("Starting process '{0}' with arguments '{1}' as user '{2}' in working dir '{3}'", filename, arguments, this.user.Username, this.prisonRules.PrisonHomePath);

            if (filename == string.Empty)
            {
                filename = null;
            }

            if (CellEnabled(RuleType.WindowStation))
            {
                new WindowStation().Apply(this);
            }

            Native.PROCESS_INFORMATION processInfo = NativeCreateProcessAsUser(interactive, filename, arguments, envBlock);

            var workerProcessPid = processInfo.dwProcessId;
            var workerProcess    = Process.GetProcessById(workerProcessPid);

            // AccessTokenHandle
            // workerProcess.RemovePrivilege(ProcessPrivileges.Privilege.ChangeNotify);
            // ProcessExtensions.RemovePrivilege(new AccessTokenHandle() , Privilege.ChangeNotify);

            // Tag the process with the Job Object before resuming the process.
            this.jobObject.AddProcess(workerProcess);

            // Add process in the second job object
            this.AddProcessToGuardJobObject(workerProcess);

            // This would allow the process to query the ExitCode. ref: http://msdn.microsoft.com/en-us/magazine/cc163900.aspx
            workerProcess.EnableRaisingEvents = true;

            return(workerProcess);
        }
Exemple #2
0
        public Process Execute(string filename, string arguments, bool interactive, Dictionary <string, string> extraEnvironmentVariables)
        {
            // C with Win32 API example to start a process under a different user: http://msdn.microsoft.com/en-us/library/aa379608%28VS.85%29.aspx

            if (!this.isLocked)
            {
                throw new InvalidOperationException("This prison has to be locked before you can use it.");
            }

            var startupInfo = new Native.STARTUPINFO();
            var processInfo = new Native.PROCESS_INFORMATION();

            startupInfo = new Native.STARTUPINFO();

            if (CellEnabled(RuleType.WindowStation))
            {
                new WindowStation().Apply(this);
                startupInfo.lpDesktop = this.desktopName;
            }


            Native.ProcessCreationFlags creationFlags = Native.ProcessCreationFlags.ZERO_FLAG;

            // Exclude flags
            creationFlags &=
                ~Native.ProcessCreationFlags.CREATE_PRESERVE_CODE_AUTHZ_LEVEL &
                ~Native.ProcessCreationFlags.CREATE_BREAKAWAY_FROM_JOB;

            // Include flags
            creationFlags |=
                Native.ProcessCreationFlags.CREATE_DEFAULT_ERROR_MODE |
                Native.ProcessCreationFlags.CREATE_NEW_PROCESS_GROUP |
                Native.ProcessCreationFlags.CREATE_SUSPENDED |
                Native.ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT;

            // TODO: extra steps for interactive to work:
            // http://blogs.msdn.com/b/winsdk/archive/2013/05/01/how-to-launch-a-process-interactively-from-a-windows-service.aspx
            if (interactive)
            {
                creationFlags        |= Native.ProcessCreationFlags.CREATE_NEW_CONSOLE;
                startupInfo.lpDesktop = "";
            }
            else
            {
                //     creationFlags |= Native.ProcessCreationFlags.CREATE_NO_WINDOW;

                // startupInfo.dwFlags |= 0x00000100; // STARTF_USESTDHANDLES
                startupInfo.hStdInput  = Native.GetStdHandle(Native.STD_INPUT_HANDLE);
                startupInfo.hStdOutput = Native.GetStdHandle(Native.STD_OUTPUT_HANDLE);
                startupInfo.hStdError  = Native.GetStdHandle(Native.STD_ERROR_HANDLE);
            }


            this.InitializeLogonToken();
            this.LoadUserProfileIfNotLoaded();

            var envs = GetDefaultEnvironmentVarialbes();

            // environmentVariables from the method parameters have precedence over the default envs
            if (extraEnvironmentVariables != null)
            {
                foreach (var env in extraEnvironmentVariables)
                {
                    envs[env.Key] = env.Value;
                }
            }

            string envBlock = extraEnvironmentVariables == null ? null : Prison.BuildEnvironmentVariable(envs);

            Native.SECURITY_ATTRIBUTES processAttributes = new Native.SECURITY_ATTRIBUTES();
            Native.SECURITY_ATTRIBUTES threadAttributes  = new Native.SECURITY_ATTRIBUTES();
            processAttributes.nLength = Marshal.SizeOf(processAttributes);
            threadAttributes.nLength  = Marshal.SizeOf(threadAttributes);

            Logger.Debug("Starting process '{0}' with arguments '{1}' as user '{2}' in working dir '{3}'", filename, arguments, this.user.Username, this.prisonRules.PrisonHomePath);

            if (filename == string.Empty)
            {
                filename = null;
            }

            var createProcessSuc = Native.CreateProcessAsUser(
                hToken: logonToken.DangerousGetHandle(),
                lpApplicationName: filename,
                lpCommandLine: arguments,
                lpProcessAttributes: ref processAttributes,
                lpThreadAttributes: ref threadAttributes,
                bInheritHandles: false,
                dwCreationFlags: creationFlags,
                lpEnvironment: envBlock,
                lpCurrentDirectory: this.prisonRules.PrisonHomePath,
                lpStartupInfo: ref startupInfo,
                lpProcessInformation: out processInfo);

            if (createProcessSuc == false)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            var workerProcessPid = processInfo.dwProcessId;
            var workerProcess    = Process.GetProcessById(workerProcessPid);


            // AccessTokenHandle
            // workerProcess.RemovePrivilege(ProcessPrivileges.Privilege.ChangeNotify);
            // ProcessExtensions.RemovePrivilege(new AccessTokenHandle() , Privilege.ChangeNotify);

            // Tag the process with the Job Object before resuming the process.
            this.jobObject.AddProcess(workerProcess);

            // Add process in the second job object
            this.AddProcessToGuardJobObject(workerProcess);

            // This would allow the process to query the ExitCode. ref: http://msdn.microsoft.com/en-us/magazine/cc163900.aspx
            workerProcess.EnableRaisingEvents = true;

            // Now that the process is tagged with the Job Object so we can resume the thread.
            IntPtr threadHandler = Native.OpenThread(Native.ThreadAccess.SUSPEND_RESUME, false, processInfo.dwThreadId);

            uint resumeResult = Native.ResumeThread(threadHandler);

            Native.CloseHandle(threadHandler);

            if (resumeResult != 1)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            return(workerProcess);
        }
Exemple #3
0
        private Native.PROCESS_INFORMATION NativeCreateProcessAsUser(bool interactive, string filename, string arguments, string envBlock)
        {
            var startupInfo = new Native.STARTUPINFO();
            var processInfo = new Native.PROCESS_INFORMATION();

            startupInfo = new Native.STARTUPINFO();

            if (CellEnabled(RuleType.WindowStation))
            {
                startupInfo.lpDesktop = this.desktopName;
            }

            Native.ProcessCreationFlags creationFlags = Native.ProcessCreationFlags.ZERO_FLAG;

            // Exclude flags
            creationFlags &=
                ~Native.ProcessCreationFlags.CREATE_PRESERVE_CODE_AUTHZ_LEVEL &
                ~Native.ProcessCreationFlags.CREATE_BREAKAWAY_FROM_JOB;

            // Include flags
            creationFlags |=
                Native.ProcessCreationFlags.CREATE_DEFAULT_ERROR_MODE |
                Native.ProcessCreationFlags.CREATE_NEW_PROCESS_GROUP |
                Native.ProcessCreationFlags.CREATE_SUSPENDED |
                Native.ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT;

            // TODO: extra steps for interactive to work:
            // http://blogs.msdn.com/b/winsdk/archive/2013/05/01/how-to-launch-a-process-interactively-from-a-windows-service.aspx
            if (interactive)
            {
                creationFlags |= Native.ProcessCreationFlags.CREATE_NEW_CONSOLE;
                startupInfo.lpDesktop = "";
            }
            else
            {
                //     creationFlags |= Native.ProcessCreationFlags.CREATE_NO_WINDOW;

                // startupInfo.dwFlags |= 0x00000100; // STARTF_USESTDHANDLES
                startupInfo.hStdInput = Native.GetStdHandle(Native.STD_INPUT_HANDLE);
                startupInfo.hStdOutput = Native.GetStdHandle(Native.STD_OUTPUT_HANDLE);
                startupInfo.hStdError = Native.GetStdHandle(Native.STD_ERROR_HANDLE);
            }

            Native.SECURITY_ATTRIBUTES processAttributes = new Native.SECURITY_ATTRIBUTES();
            Native.SECURITY_ATTRIBUTES threadAttributes = new Native.SECURITY_ATTRIBUTES();
            processAttributes.nLength = Marshal.SizeOf(processAttributes);
            threadAttributes.nLength = Marshal.SizeOf(threadAttributes);

            var createProcessSuc = Native.CreateProcessAsUser(
                hToken: logonToken.DangerousGetHandle(),
                lpApplicationName: filename,
                lpCommandLine: arguments,
                lpProcessAttributes: ref processAttributes,
                lpThreadAttributes: ref threadAttributes,
                bInheritHandles: false,
                dwCreationFlags: creationFlags,
                lpEnvironment: envBlock,
                lpCurrentDirectory: this.prisonRules.PrisonHomePath,
                lpStartupInfo: ref startupInfo,
                lpProcessInformation: out processInfo);

            if (createProcessSuc == false)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            return processInfo;
        }
Exemple #4
0
        private Native.PROCESS_INFORMATION NativeCreateProcessAsUser(bool interactive, string filename, string arguments, string envBlock)
        {
            var startupInfo = new Native.STARTUPINFO();
            var processInfo = new Native.PROCESS_INFORMATION();

            startupInfo = new Native.STARTUPINFO();

            if (CellEnabled(RuleType.WindowStation))
            {
                startupInfo.lpDesktop = this.desktopName;
            }

            Native.ProcessCreationFlags creationFlags = Native.ProcessCreationFlags.ZERO_FLAG;

            // Exclude flags
            creationFlags &=
                ~Native.ProcessCreationFlags.CREATE_PRESERVE_CODE_AUTHZ_LEVEL &
                ~Native.ProcessCreationFlags.CREATE_BREAKAWAY_FROM_JOB;

            // Include flags
            creationFlags |=
                Native.ProcessCreationFlags.CREATE_DEFAULT_ERROR_MODE |
                Native.ProcessCreationFlags.CREATE_NEW_PROCESS_GROUP |
                Native.ProcessCreationFlags.CREATE_SUSPENDED |
                Native.ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT;

            // TODO: extra steps for interactive to work:
            // http://blogs.msdn.com/b/winsdk/archive/2013/05/01/how-to-launch-a-process-interactively-from-a-windows-service.aspx
            if (interactive)
            {
                creationFlags        |= Native.ProcessCreationFlags.CREATE_NEW_CONSOLE;
                startupInfo.lpDesktop = "";
            }
            else
            {
                //     creationFlags |= Native.ProcessCreationFlags.CREATE_NO_WINDOW;

                // startupInfo.dwFlags |= 0x00000100; // STARTF_USESTDHANDLES
                startupInfo.hStdInput  = Native.GetStdHandle(Native.STD_INPUT_HANDLE);
                startupInfo.hStdOutput = Native.GetStdHandle(Native.STD_OUTPUT_HANDLE);
                startupInfo.hStdError  = Native.GetStdHandle(Native.STD_ERROR_HANDLE);
            }

            Native.SECURITY_ATTRIBUTES processAttributes = new Native.SECURITY_ATTRIBUTES();
            Native.SECURITY_ATTRIBUTES threadAttributes  = new Native.SECURITY_ATTRIBUTES();
            processAttributes.nLength = Marshal.SizeOf(processAttributes);
            threadAttributes.nLength  = Marshal.SizeOf(threadAttributes);

            var createProcessSuc = Native.CreateProcessAsUser(
                hToken: logonToken.DangerousGetHandle(),
                lpApplicationName: filename,
                lpCommandLine: arguments,
                lpProcessAttributes: ref processAttributes,
                lpThreadAttributes: ref threadAttributes,
                bInheritHandles: false,
                dwCreationFlags: creationFlags,
                lpEnvironment: envBlock,
                lpCurrentDirectory: this.prisonRules.PrisonHomePath,
                lpStartupInfo: ref startupInfo,
                lpProcessInformation: out processInfo);

            if (createProcessSuc == false)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            return(processInfo);
        }