Beispiel #1
0
        public bool Detect(ProcessPrison prison)
        {
            string exe = GetExecutable(Path.Combine(this.path, "bin"), "detect");

            string outputPath = Path.Combine(this.cacheDir, "detect.yml");
            string script = string.Format("{0} {1} > {2} 2>&1", exe, this.appDir, outputPath);

            Logger.Debug("Running detect script: {0}", script);
            var runInfo = new ProcessPrisonRunInfo();
            runInfo.WorkingDirectory = Path.Combine(this.appDir);
            runInfo.FileName = null;
            runInfo.Arguments = script;
            Process process = prison.RunProcess(runInfo);
            process.WaitForExit(5000);
            if (!process.HasExited)
            {
                process.Kill();
            }
            if (File.Exists(outputPath))
            {
                this.detectOutput = File.ReadAllText(outputPath);
                Logger.Debug("Detect output: {0}", this.detectOutput);
                File.Delete(outputPath);
            }
            if (process.ExitCode == 0)
            {
                return true;
            }
            else
            {
                Logger.Warning("Detect process exited with {0}", process.ExitCode);
                return false;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Runs a process in the current object container.
        /// Reference for starting a windows porcess in suspended mode:
        /// http://www.codeproject.com/Articles/230005/Launch-a-process-suspended
        /// </summary>
        /// <param name="executablePath"></param>
        public void RunProcess(string executablePath)
        {
            var runInfo = new ProcessPrisonRunInfo()
            {
                FileName = executablePath
            };

            this.RunProcess(runInfo);
        }
Beispiel #3
0
        public Process RunProcess(ProcessPrisonRunInfo runInfo)
        {
            if (!this.Created)
            {
                throw new InvalidOperationException("ProcessPrison has to be created first.");
            }

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

            startupInfo.cb = Marshal.SizeOf(startupInfo.GetType());
            // startupInfo.dwFlags = 0x00000100;

            string env = BuildEnvironmentVariable(runInfo.EnvironmentVariables);

            var creationFlags = ProcessCreationFlags.ZERO_FLAG;

            creationFlags &=
                ~ProcessCreationFlags.CREATE_PRESERVE_CODE_AUTHZ_LEVEL;

            creationFlags |=
                ProcessCreationFlags.CREATE_SEPARATE_WOW_VDM |

                ProcessCreationFlags.CREATE_DEFAULT_ERROR_MODE |
                ProcessCreationFlags.CREATE_NEW_PROCESS_GROUP |
                ProcessCreationFlags.CREATE_NO_WINDOW |
                ProcessCreationFlags.CREATE_SUSPENDED |
                ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT;

            if (runInfo.Interactive)
            {
                creationFlags |= ProcessCreationFlags.CREATE_NEW_CONSOLE;
                // startupInfo.lpDesktop = @"winsta0\default"; // set additional ACLs for the user to have access to winsta0/default
            }
            else
            {
                creationFlags |= ProcessCreationFlags.CREATE_NO_WINDOW;
                // http://support.microsoft.com/kb/165194
                // startupInfo.lpDesktop = this.Id + "\\" + "default";
                // TODO: isolate the Windows Station and Destop
            }



            if (string.IsNullOrEmpty(this.WindowsUsername))
            {
                throw new InvalidOperationException("This should not be run without a user");
            }
            else
            {
                SECURITY_ATTRIBUTES secAttributes = new SECURITY_ATTRIBUTES();
                secAttributes.nLength = Marshal.SizeOf(secAttributes);

                IntPtr windowStation = CreateWindowStation(this.WindowsUsername, 0, WINDOWS_STATION_ACCESS_MASK.WINSTA_NONE, null);
                IntPtr desktop       = IntPtr.Zero;

                lock (windowStationLock)
                {
                    IntPtr currentWindowStation = GetProcessWindowStation();

                    try
                    {
                        bool setOk = SetProcessWindowStation(windowStation);

                        if (!setOk)
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        CreateDesktop(this.WindowsUsername, null, null, 0, ACCESS_MASK.DESKTOP_CREATEWINDOW, null);

                        startupInfo.lpDesktop = string.Format(@"{0}\{0}", this.WindowsUsername);

                        byte[] envBlock = CreateEnvironment(myenvvars);

                        // Create the process in suspended mode to fence it with a Windows Job Object
                        // before it executes.
                        // TODO: Use CreateProcessWithToken to prevent Windows for creating an unamed job object for the
                        // second created process.
                        // http://stackoverflow.com/questions/1287620/createprocesswithlogonw-and-assignprocesstojobobject
                        bool ret = CreateProcessWithLogon(
                            this.WindowsUsername,
                            this.WindowsDomain,
                            this.WindowsPassword,
                            LogonFlags.LOGON_NETCREDENTIALS_ONLY,
                            runInfo.FileName,
                            runInfo.Arguments,
                            creationFlags,
                            UnicodeEncoding.Unicode.GetString(envBlock),
                            runInfo.WorkingDirectory,
                            ref startupInfo,
                            out processInfo
                            );

                        if (!ret)
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                    }
                    finally
                    {
                        SetProcessWindowStation(currentWindowStation);
                    }
                }
            }

            var process = Process.GetProcessById(processInfo.dwProcessId);

            this.jobObject.AddProcess(process);

            uint ret2 = ResumeThread(processInfo.hThread);

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

            CloseHandle(processInfo.hProcess);
            CloseHandle(processInfo.hThread);

            return(process);
        }
Beispiel #4
0
        private void StartDropletInstance(DropletInstance instance, string sha1, string executableFile, string executableUri)
        {
            try
            {
                try
                {
                    instance.Lock.EnterWriteLock();

                    var prisonInfo = new ProcessPrisonCreateInfo();

                    prisonInfo.Id = instance.Properties.InstanceId;
                    prisonInfo.TotalPrivateMemoryLimitBytes = instance.Properties.MemoryQuotaBytes;

                    if (this.useDiskQuota)
                    {
                        prisonInfo.DiskQuotaBytes = instance.Properties.DiskQuotaBytes;
                        prisonInfo.DiskQuotaPath = instance.Properties.Directory;
                    }

                    if (this.uploadThrottleBitsps > 0)
                    {
                        prisonInfo.NetworkOutboundRateLimitBitsPerSecond = this.uploadThrottleBitsps;
                    }

                    prisonInfo.UrlPortAccess = instance.Properties.Port;

                    Logger.Info("Creating Process Prisson: {0}", prisonInfo.Id);

                    instance.Prison.Create(prisonInfo);

                    Logger.Info("Opening firewall port {0} for instance {1}", instance.Properties.Port, instance.Properties.LoggingId);

                    FirewallTools.OpenPort(instance.Properties.Port, instance.Properties.InstanceId);

                    instance.Properties.WindowsPassword = instance.Prison.WindowsPassword;
                    instance.Properties.WindowsUserName = instance.Prison.WindowsUsername;
                }
                finally
                {
                    instance.Lock.ExitWriteLock();
                }

                string tgzFile = Path.Combine(this.fileResources.StagedDir, sha1 + ".tgz");
                this.fileResources.PrepareAppDirectory(executableFile, executableUri, sha1, tgzFile, instance);
                Logger.Debug(Strings.Downloadcompleate);

                string starting = string.Format(CultureInfo.InvariantCulture, Strings.StartingUpInstanceOnPort, instance.Properties.LoggingId, instance.Properties.Port);

                Logger.Info(starting);

                Logger.Debug(Strings.Clients, this.monitoring.Clients);
                Logger.Debug(Strings.ReservedMemoryUsageMb, this.monitoring.MemoryReservedMbytes, this.monitoring.MaxMemoryMbytes);

                try
                {
                    instance.Lock.EnterWriteLock();

                    instance.Properties.EnvironmentVariables.Add(VcapWindowsUserVariable, instance.Properties.WindowsUserName);
                    instance.Properties.EnvironmentVariables.Add(VcapWindowsUserPasswordVariable, instance.Properties.WindowsPassword);

                    instance.Prison.SetUsersEnvironmentVariables(instance.Properties.EnvironmentVariables);

                }
                finally
                {
                    instance.Lock.ExitWriteLock();
                }

                DateTime start = DateTime.Now;

                string startSciprtPath = this.CreateStartScript(instance);

                var runInfo = new ProcessPrisonRunInfo();
                runInfo.WorkingDirectory = Path.Combine(instance.Properties.Directory, "app");
                runInfo.FileName = startSciprtPath;

                instance.Prison.RunProcess(runInfo);

                Logger.Debug(Strings.TookXTimeToLoadConfigureAndStartDebugMessage, (DateTime.Now - start).TotalSeconds);

                try
                {
                    instance.Lock.EnterWriteLock();

                    if (!instance.Properties.StopProcessed)
                    {
                        this.droplets.ScheduleSnapshotAppState();
                    }
                }
                finally
                {
                    instance.Lock.ExitWriteLock();
                }

                this.DetectAppReady(instance);
            }
            catch (Exception ex)
            {
                Logger.Warning(Strings.FailedStagingAppDir, instance.Properties.Directory, instance.Properties.LoggingId, ex.ToString());
                try
                {
                    instance.Lock.EnterWriteLock();

                    instance.Properties.State = DropletInstanceState.Crashed;
                    instance.Properties.ExitReason = DropletExitReason.Crashed;
                    instance.Properties.StateTimestamp = DateTime.Now;

                    this.StopDroplet(instance);
                }
                finally
                {
                    instance.Lock.ExitWriteLock();
                }
            }
        }
Beispiel #5
0
        public Process StartCompile(ProcessPrison prison)
        {
            string exe = GetExecutable(Path.Combine(path, "bin"), "compile");
            string args = string.Format("{0} {1} >> {2} 2>&1", this.appDir, this.cacheDir, this.logFile);
            Logger.Debug("Running compile script {0} {1}", exe, args);

            var runInfo = new ProcessPrisonRunInfo();
            runInfo.WorkingDirectory = Path.Combine(this.appDir);
            runInfo.FileName = null;
            runInfo.Arguments = string.Format("{0} {1}", exe, args);
            return prison.RunProcess(runInfo);
        }
Beispiel #6
0
        public ReleaseInfo GetReleaseInfo(ProcessPrison prison)
        {
            string exe = GetExecutable(Path.Combine(this.path, "bin"), "release");

            string outputPath = Path.Combine(this.cacheDir, "release.yml");
            string script = string.Format("{0} {1} > {2} 2>&1", exe, this.appDir, outputPath);

            var runInfo = new ProcessPrisonRunInfo();
            runInfo.WorkingDirectory = Path.Combine(this.appDir);
            runInfo.FileName = null;
            runInfo.Arguments = script;
            Process process = prison.RunProcess(runInfo);
            process.WaitForExit(5000);

            string output = File.ReadAllText(outputPath);
            File.Delete(outputPath);
            using (var reader = new StringReader(output))
            {
                Deserializer deserializer = new Deserializer();
                return (ReleaseInfo)deserializer.Deserialize(reader, typeof(ReleaseInfo));
            }
        }
        public Process RunProcess(ProcessPrisonRunInfo runInfo)
        {
            if (!this.Created)
            {
                throw new InvalidOperationException("ProcessPrison has to be created first.");
            }

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

            startupInfo.cb = Marshal.SizeOf(startupInfo.GetType());
            // startupInfo.dwFlags = 0x00000100;

            string env = BuildEnvironmentVariable(runInfo.EnvironmentVariables);

            var creationFlags = ProcessCreationFlags.ZERO_FLAG;

            creationFlags &=
                ~ProcessCreationFlags.CREATE_PRESERVE_CODE_AUTHZ_LEVEL;

            creationFlags |=
                ProcessCreationFlags.CREATE_SEPARATE_WOW_VDM |

                ProcessCreationFlags.CREATE_DEFAULT_ERROR_MODE |
                ProcessCreationFlags.CREATE_NEW_PROCESS_GROUP |
                ProcessCreationFlags.CREATE_NO_WINDOW |
                ProcessCreationFlags.CREATE_SUSPENDED |
                ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT;

            if (runInfo.Interactive)
            {
                creationFlags |= ProcessCreationFlags.CREATE_NEW_CONSOLE;
                // startupInfo.lpDesktop = @"winsta0\default"; // set additional ACLs for the user to have access to winsta0/default
            }
            else
            {
                creationFlags |= ProcessCreationFlags.CREATE_NO_WINDOW;
                // http://support.microsoft.com/kb/165194
                // startupInfo.lpDesktop = this.Id + "\\" + "default";
                // TODO: isolate the Windows Station and Destop
            }

            if (string.IsNullOrEmpty(this.WindowsUsername))
            {
                throw new InvalidOperationException("This should not be run without a user");
            }
            else
            {

                SECURITY_ATTRIBUTES secAttributes = new SECURITY_ATTRIBUTES();
                secAttributes.nLength = Marshal.SizeOf(secAttributes);

                IntPtr windowStation = CreateWindowStation(this.WindowsUsername, 0, WINDOWS_STATION_ACCESS_MASK.WINSTA_NONE, null);
                IntPtr desktop = IntPtr.Zero;

                lock (windowStationLock)
                {
                    IntPtr currentWindowStation = GetProcessWindowStation();

                    try
                    {
                        bool setOk = SetProcessWindowStation(windowStation);

                        if (!setOk)
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        CreateDesktop(this.WindowsUsername, null, null, 0, ACCESS_MASK.DESKTOP_CREATEWINDOW, null);

                        startupInfo.lpDesktop = string.Format(@"{0}\{0}", this.WindowsUsername);

                        byte[] envBlock = CreateEnvironment(myenvvars);

                        // Create the process in suspended mode to fence it with a Windows Job Object
                        // before it executes.
                        // TODO: Use CreateProcessWithToken to prevent Windows for creating an unamed job object for the
                        // second created process.
                        // http://stackoverflow.com/questions/1287620/createprocesswithlogonw-and-assignprocesstojobobject
                        bool ret = CreateProcessWithLogon(
                            this.WindowsUsername,
                            this.WindowsDomain,
                            this.WindowsPassword,
                            LogonFlags.LOGON_NETCREDENTIALS_ONLY,
                            runInfo.FileName,
                            runInfo.Arguments,
                            creationFlags,
                            UnicodeEncoding.Unicode.GetString(envBlock),
                            runInfo.WorkingDirectory,
                            ref startupInfo,
                            out processInfo
                            );

                        if (!ret)
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }
                    }
                    finally
                    {
                        SetProcessWindowStation(currentWindowStation);
                    }
                }
            }

            var process = Process.GetProcessById(processInfo.dwProcessId);

            this.jobObject.AddProcess(process);

            uint ret2 = ResumeThread(processInfo.hThread);
            if (ret2 != 1)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }

            CloseHandle(processInfo.hProcess);
            CloseHandle(processInfo.hThread);

            return process;
        }
 /// <summary>
 /// Runs a process in the current object container.
 /// Reference for starting a windows porcess in suspended mode:
 /// http://www.codeproject.com/Articles/230005/Launch-a-process-suspended
 /// </summary>
 /// <param name="executablePath"></param>
 public void RunProcess(string executablePath)
 {
     var runInfo = new ProcessPrisonRunInfo() { FileName = executablePath };
     this.RunProcess(runInfo);
 }
Beispiel #9
0
        static void Main(string[] args)
        {
            Console.WriteLine("--- PrisonProcess REPL ---\n");
            Console.WriteLine("Use the following keys:");
            Console.WriteLine("\tc: Create a new cmd prison");
            Console.WriteLine("\tn: Create a new notepad prison");
            Console.WriteLine("\td: Destroy all prissons");
            Console.WriteLine("\tq: Quit");

            List<ProcessPrison> prisonss = new List<ProcessPrison>();

            DiskQuotaManager.StartQuotaInitialization();
            while (!DiskQuotaManager.IsQuotaInitialized())
            {
                Thread.Sleep(100);
            }

            var usersDesc = WindowsUsersAndGroups.GetUsersDescription();
            foreach (var desc in usersDesc.Values)
            {
                try
                {
                    var id = ProcessPrison.GetIdFromUserDescription(desc);

                    var ppci = new ProcessPrisonCreateInfo();
                    ppci.Id = id;
                    ppci.TotalPrivateMemoryLimitBytes = 128 * 1024 * 1024;
                    ppci.DiskQuotaBytes = 128 * 1024 * 1024;
                    ppci.DiskQuotaPath = @"C:\Users\Public";
                    // Cannot impersonate the user to create new processes or access the user's env.
                    ppci.WindowsPassword = "******";

                    var pp = new ProcessPrison();
                    pp.Attach(ppci);

                    prisonss.Add(pp);
                }
                catch(ArgumentException)
                {
                }
            }

            while (true)
            {
                var key = Console.ReadKey();
                if (key.Key == ConsoleKey.Q && key.Modifiers == ConsoleModifiers.Shift) break;

                switch (key.Key)
                {
                    case ConsoleKey.C:
                        {
                            var ppci = new ProcessPrisonCreateInfo();
                            ppci.TotalPrivateMemoryLimitBytes = 128 * 1000 * 1000;
                            ppci.DiskQuotaBytes = 128 * 1024 * 1024;
                            ppci.DiskQuotaPath = @"C:\Users\Public";
                            ppci.NetworkOutboundRateLimitBitsPerSecond = 80 * 1000;

                            var pp = new ProcessPrison();
                            pp.Create(ppci);
                            pp.SetUsersEnvironmentVariable("prison", pp.Id);

                            var ri = new ProcessPrisonRunInfo();
                            ri.Interactive = true;
                            ri.FileName = @"C:\Windows\System32\cmd.exe";
                            ri.Arguments = String.Format(" /k  title {1} & echo Wedcome to prisson {0}. & echo Running under user {1} & echo Private virtual memory limit: {2} B", pp.Id, pp.WindowsUsername, ppci.TotalPrivateMemoryLimitBytes);
                            ri.Arguments += " & echo. & echo Cmd bomb for memory test: & echo 'set loop=cmd /k ^%loop^%' & echo 'cmd /k %loop%'";
                            ri.Arguments += " & echo. & echo Ruby file server for network test: & echo 'rackup -b 'run Rack::Directory.new(\"\")''";

                            pp.RunProcess(ri);

                            prisonss.Add(pp);
                        }
                        break;
                    case ConsoleKey.N:
                        {
                            var ppci = new ProcessPrisonCreateInfo();
                            ppci.TotalPrivateMemoryLimitBytes = 128 * 1024 * 1024;
                            ppci.DiskQuotaBytes = 128 * 1024 * 1024;
                            ppci.DiskQuotaPath = @"C:\Users\Public";

                            var pp = new ProcessPrison();
                            pp.Create(ppci);
                            pp.SetUsersEnvironmentVariable("prison", pp.Id);

                            var ri = new ProcessPrisonRunInfo();
                            ri.Interactive = true;
                            ri.FileName = @"C:\Windows\System32\notepad.exe";

                            pp.RunProcess(ri);

                            prisonss.Add(pp);
                        }
                        break;
                    case ConsoleKey.D:
                        foreach (var prison in prisonss)
                        {
                            prison.Destroy();
                        }
                        prisonss.Clear();
                        break;
                    case ConsoleKey.Q:
                        return;
                }

            }

            var createInfo = new ProcessPrisonCreateInfo();

            var p = new ProcessPrison();

            p.Create(createInfo);
            var envs = p.GetUsersEnvironmentVariables();

            var runInfo = new ProcessPrisonRunInfo();
            runInfo.Interactive = false;
            runInfo.FileName = @"C:\Windows\System32\cmd.exe";
            runInfo.FileName = @"C:\Windows\System32\PING.EXE";
            // runInfo.Arguments = @"/c echo %PATH% & ping 10.0.0.10" ;
            runInfo.Arguments = @" /k rackup -b ""run lambda {|env| [200, {'Content-Type'=>'text/html'}, 'Hello World']}"" -P 2345";

            runInfo.Arguments = " 10.0.0.10 -t";
            runInfo.WorkingDirectory = @"C:\Users\Public";
            runInfo.FileName = @"C:\Windows\System32\mspaint.exe";
            runInfo.Arguments = "";

            p.RunProcess(runInfo);

            //p.RunProcess(@"C:\Windows\System32\mspaint.exe");

            Console.ReadKey();

            p.Destroy();
        }