Esempio n. 1
0
        internal static int ExecWaitWithCapture(SafeUserTokenHandle userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine)
        {
            int retValue = 0;

            // Undo any current impersonation, call ExecWaitWithCaptureUnimpersonated, and reimpersonate
#if !FEATURE_PAL
            // the extra try-catch is here to mitigate exception filter injection attacks.
            try {
                WindowsImpersonationContext impersonation = RevertImpersonation();
                try {
#endif

            // Execute the process
            retValue = ExecWaitWithCaptureUnimpersonated(userToken, cmd, currentDir, tempFiles, ref outputName, ref errorName, trueCmdLine);
#if !FEATURE_PAL
        }
        finally {
            ReImpersonate(impersonation);
        }
    }
    catch {
        throw;
    }
#endif
            return(retValue);
        }
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        internal static int ExecWaitWithCapture(SafeUserTokenHandle userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine)
        {
            int retValue = 0;

            // Undo any current impersonation, call ExecWaitWithCaptureUnimpersonated, and reimpersonate

            // Execute the process
            retValue = ExecWaitWithCaptureUnimpersonated(userToken, cmd, currentDir, tempFiles, ref outputName, ref errorName, trueCmdLine);
            return(retValue);
        }
        internal static int ExecWaitWithCapture(SafeUserTokenHandle userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine)
        {
            int num = 0;

            try
            {
                WindowsImpersonationContext impersonation = RevertImpersonation();
                try
                {
                    num = ExecWaitWithCaptureUnimpersonated(userToken, cmd, currentDir, tempFiles, ref outputName, ref errorName, trueCmdLine);
                }
                finally
                {
                    ReImpersonate(impersonation);
                }
            }
            catch
            {
                throw;
            }
            return(num);
        }
        private static unsafe int ExecWaitWithCaptureUnimpersonated(SafeUserTokenHandle userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine)
        {
            IntSecurity.UnmanagedCode.Demand();

            FileStream output;
            FileStream error;

            int retValue = 0;

            if (outputName == null || outputName.Length == 0)
            {
                outputName = tempFiles.AddExtension("out");
            }

            if (errorName == null || errorName.Length == 0)
            {
                errorName = tempFiles.AddExtension("err");
            }

            // Create the files
            output = CreateInheritedFile(outputName);
            error  = CreateInheritedFile(errorName);

            bool success = false;

            SafeNativeMethods.PROCESS_INFORMATION pi = new SafeNativeMethods.PROCESS_INFORMATION();
            SafeProcessHandle   procSH       = new SafeProcessHandle();
            SafeThreadHandle    threadSH     = new SafeThreadHandle();
            SafeUserTokenHandle primaryToken = null;

            try {
                // Output the command line...
                StreamWriter sw = new StreamWriter(output, Encoding.UTF8);
                sw.Write(currentDir);
                sw.Write("> ");
                // 'true' command line is used in case the command line points to
                // a response file
                sw.WriteLine(trueCmdLine != null ? trueCmdLine : cmd);
                sw.WriteLine();
                sw.WriteLine();
                sw.Flush();

                NativeMethods.STARTUPINFO si = new NativeMethods.STARTUPINFO();

                si.cb         = Marshal.SizeOf(si);
                si.dwFlags    = NativeMethods.STARTF_USESTDHANDLES;
                si.hStdOutput = output.SafeFileHandle;
                si.hStdError  = error.SafeFileHandle;
                si.hStdInput  = new SafeFileHandle(UnsafeNativeMethods.GetStdHandle(NativeMethods.STD_INPUT_HANDLE), false);

                //
                // Prepare the environment
                //
#if PLATFORM_UNIX
                StringDictionary environment = new CaseSensitiveStringDictionary();
#else
                StringDictionary environment = new StringDictionary();
#endif // PLATFORM_UNIX



                // Add the current environment

                foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables())
                {
                    environment.Add((string)entry.Key, (string)entry.Value);
                }



                // Add the flag to indicate restricted security in the process
                environment["_ClrRestrictSecAttributes"] = "1";

                #if DEBUG
                environment["OANOCACHE"] = "1";
                #endif

                // set up the environment block parameter
                byte[] environmentBytes = EnvironmentBlock.ToByteArray(environment, false);
                fixed(byte *environmentBytesPtr = environmentBytes)
                {
                    IntPtr environmentPtr = new IntPtr((void *)environmentBytesPtr);

                    if (userToken == null || userToken.IsInvalid)
                    {
                        RuntimeHelpers.PrepareConstrainedRegions();
                        try {} finally {
                            success = NativeMethods.CreateProcess(
                                null,                              // String lpApplicationName,
                                new StringBuilder(cmd),            // String lpCommandLine,
                                null,                              // SECURITY_ATTRIBUTES lpProcessAttributes,
                                null,                              // SECURITY_ATTRIBUTES lpThreadAttributes,
                                true,                              // bool bInheritHandles,
                                0,                                 // int dwCreationFlags,
                                environmentPtr,                    // int lpEnvironment,
                                currentDir,                        // String lpCurrentDirectory,
                                si,                                // STARTUPINFO lpStartupInfo,
                                pi);                               // PROCESS_INFORMATION lpProcessInformation);
                            if (pi.hProcess != (IntPtr)0 && pi.hProcess != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
                            {
                                procSH.InitialSetHandle(pi.hProcess);
                            }
                            if (pi.hThread != (IntPtr)0 && pi.hThread != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
                            {
                                threadSH.InitialSetHandle(pi.hThread);
                            }
                        }
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
            }
            finally {
                // Close the file handles
                if (!success && (primaryToken != null && !primaryToken.IsInvalid))
                {
                    primaryToken.Close();
                    primaryToken = null;
                }

                output.Close();
                error.Close();
            }

            if (success)
            {
                try {
                    int ret = NativeMethods.WaitForSingleObject(procSH, ProcessTimeOut);

                    // Check for timeout
                    if (ret == NativeMethods.WAIT_TIMEOUT)
                    {
                        throw new ExternalException(SR.GetString(SR.ExecTimeout, cmd), NativeMethods.WAIT_TIMEOUT);
                    }

                    if (ret != NativeMethods.WAIT_OBJECT_0)
                    {
                        throw new ExternalException(SR.GetString(SR.ExecBadreturn, cmd), Marshal.GetLastWin32Error());
                    }

                    // Check the process's exit code
                    int status = NativeMethods.STILL_ACTIVE;
                    if (!NativeMethods.GetExitCodeProcess(procSH, out status))
                    {
                        throw new ExternalException(SR.GetString(SR.ExecCantGetRetCode, cmd), Marshal.GetLastWin32Error());
                    }

                    retValue = status;
                }
                finally {
                    procSH.Close();
                    threadSH.Close();
                    if (primaryToken != null && !primaryToken.IsInvalid)
                    {
                        primaryToken.Close();
                    }
                }
            }
            else
            {
                throw new ExternalException(SR.GetString(SR.ExecCantExec, cmd), Marshal.GetLastWin32Error());
            }

            return(retValue);
        }
        private static unsafe int ExecWaitWithCaptureUnimpersonated(SafeUserTokenHandle userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine)
        {
            IntSecurity.UnmanagedCode.Demand();
            if ((outputName == null) || (outputName.Length == 0))
            {
                outputName = tempFiles.AddExtension("out");
            }
            if ((errorName == null) || (errorName.Length == 0))
            {
                errorName = tempFiles.AddExtension("err");
            }
            FileStream stream  = CreateInheritedFile(outputName);
            FileStream stream2 = CreateInheritedFile(errorName);
            bool       flag    = false;

            Microsoft.Win32.SafeNativeMethods.PROCESS_INFORMATION lpProcessInformation = new Microsoft.Win32.SafeNativeMethods.PROCESS_INFORMATION();
            Microsoft.Win32.SafeHandles.SafeProcessHandle         processHandle        = new Microsoft.Win32.SafeHandles.SafeProcessHandle();
            Microsoft.Win32.SafeHandles.SafeThreadHandle          handle2 = new Microsoft.Win32.SafeHandles.SafeThreadHandle();
            SafeUserTokenHandle hNewToken = null;

            try
            {
                Microsoft.Win32.NativeMethods.STARTUPINFO startupinfo;
                StreamWriter writer = new StreamWriter(stream, Encoding.UTF8);
                writer.Write(currentDir);
                writer.Write("> ");
                writer.WriteLine((trueCmdLine != null) ? trueCmdLine : cmd);
                writer.WriteLine();
                writer.WriteLine();
                writer.Flush();
                startupinfo = new Microsoft.Win32.NativeMethods.STARTUPINFO {
                    cb          = Marshal.SizeOf(startupinfo),
                    dwFlags     = 0x101,
                    wShowWindow = 0,
                    hStdOutput  = stream.SafeFileHandle,
                    hStdError   = stream2.SafeFileHandle,
                    hStdInput   = new SafeFileHandle(Microsoft.Win32.UnsafeNativeMethods.GetStdHandle(-10), false)
                };
                StringDictionary sd = new StringDictionary();
                foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables())
                {
                    sd[(string)entry.Key] = (string)entry.Value;
                }
                sd["_ClrRestrictSecAttributes"] = "1";
                byte[] buffer = EnvironmentBlock.ToByteArray(sd, false);
                try
                {
                    fixed(byte *numRef = buffer)
                    {
                        IntPtr lpEnvironment = new IntPtr((void *)numRef);

                        if ((userToken == null) || userToken.IsInvalid)
                        {
                            RuntimeHelpers.PrepareConstrainedRegions();
                            try
                            {
                                goto Label_0325;
                            }
                            finally
                            {
                                flag = Microsoft.Win32.NativeMethods.CreateProcess(null, new StringBuilder(cmd), null, null, true, 0, lpEnvironment, currentDir, startupinfo, lpProcessInformation);
                                if ((lpProcessInformation.hProcess != IntPtr.Zero) && (lpProcessInformation.hProcess != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE))
                                {
                                    processHandle.InitialSetHandle(lpProcessInformation.hProcess);
                                }
                                if ((lpProcessInformation.hThread != IntPtr.Zero) && (lpProcessInformation.hThread != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE))
                                {
                                    handle2.InitialSetHandle(lpProcessInformation.hThread);
                                }
                            }
                        }
                        flag = SafeUserTokenHandle.DuplicateTokenEx(userToken, 0xf01ff, null, 2, 1, out hNewToken);
                        if (flag)
                        {
                            RuntimeHelpers.PrepareConstrainedRegions();
                            try
                            {
                            }
                            finally
                            {
                                flag = Microsoft.Win32.NativeMethods.CreateProcessAsUser(hNewToken, null, cmd, null, null, true, 0, new HandleRef(null, lpEnvironment), currentDir, startupinfo, lpProcessInformation);
                                if ((lpProcessInformation.hProcess != IntPtr.Zero) && (lpProcessInformation.hProcess != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE))
                                {
                                    processHandle.InitialSetHandle(lpProcessInformation.hProcess);
                                }
                                if ((lpProcessInformation.hThread != IntPtr.Zero) && (lpProcessInformation.hThread != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE))
                                {
                                    handle2.InitialSetHandle(lpProcessInformation.hThread);
                                }
                            }
                        }
                    }
                }
                finally
                {
                    numRef = null;
                }
            }
            finally
            {
                if ((!flag && (hNewToken != null)) && !hNewToken.IsInvalid)
                {
                    hNewToken.Close();
                    hNewToken = null;
                }
                stream.Close();
                stream2.Close();
            }
Label_0325:
            if (flag)
            {
                try
                {
                    bool flag2;
                    ProcessWaitHandle handle4 = null;
                    try
                    {
                        handle4 = new ProcessWaitHandle(processHandle);
                        flag2   = handle4.WaitOne(0x927c0, false);
                    }
                    finally
                    {
                        if (handle4 != null)
                        {
                            handle4.Close();
                        }
                    }
                    if (!flag2)
                    {
                        throw new ExternalException(SR.GetString("ExecTimeout", new object[] { cmd }), 0x102);
                    }
                    int exitCode = 0x103;
                    if (!Microsoft.Win32.NativeMethods.GetExitCodeProcess(processHandle, out exitCode))
                    {
                        throw new ExternalException(SR.GetString("ExecCantGetRetCode", new object[] { cmd }), Marshal.GetLastWin32Error());
                    }
                    return(exitCode);
                }
                finally
                {
                    processHandle.Close();
                    handle2.Close();
                    if ((hNewToken != null) && !hNewToken.IsInvalid)
                    {
                        hNewToken.Close();
                    }
                }
            }
            int error = Marshal.GetLastWin32Error();

            if (error == 8)
            {
                throw new OutOfMemoryException();
            }
            Win32Exception    inner      = new Win32Exception(error);
            ExternalException exception2 = new ExternalException(SR.GetString("ExecCantExec", new object[] { cmd }), inner);

            throw exception2;
        }