public Process Start(ProcessStartInfo psi, DisplayDetectData display) { string oldArgs = psi.Arguments; string oldFile = psi.FileName; string oldPath = psi.EnvironmentVariables["PATH"]; psi.Arguments = string.Concat(display.User, " -c \"mono '", psi.FileName, "' ", psi.Arguments.Replace("\\", "\\\\").Replace("\"", "\\\""), "\""); psi.FileName = "/usr/bin/su"; string id = new Random().Next().ToString(); psi.EnvironmentVariables["LATIPIUM_DAEMON_SPAWN_ID"] = id; psi.EnvironmentVariables["MONO_PATH"] = psi.EnvironmentVariables["PATH"] = oldPath.Replace(';', ':'); psi.UseShellExecute = false; Process proc = Process.Start(psi); psi.Arguments = oldArgs; psi.FileName = oldFile; psi.EnvironmentVariables.Remove("LATIPIUM_DAEMON_SPAWN_ID"); psi.EnvironmentVariables["PATH"] = oldPath; psi.EnvironmentVariables.Remove("MONO_PATH"); proc.EnableRaisingEvents = true; proc.Exited += (sender, e) => { foreach (Process p in Process.GetProcesses()) { if (p.StartInfo.EnvironmentVariables["LATIPIUM_DAEMON_SPAWN_ID"] == id) { p.Kill(); } } }; return(proc); }
public override StartSessionResponse Handle(object req, ApiClient client) { if (client == null) { client = Server.RegisterClient(); } DisplayDetectData display = PlatformFactory.Proxy.DetectDisplay(client.Id.ToString()); if (display.Detected) { client.Display = display; } client.Type = ClientType.Launcher; return(new StartSessionResponse() { Display = display, ClientId = client.Id }); }
public Process Start(ProcessStartInfo psi, DisplayDetectData display) { string oldArgs = psi.Arguments; string oldFile = psi.FileName; string oldDisplay = psi.EnvironmentVariables.ContainsKey("DISPLAY") ? psi.EnvironmentVariables["DISPLAY"] : null; string oldAuth = psi.EnvironmentVariables.ContainsKey("XAUTHORITY") ? psi.EnvironmentVariables["XAUTHORITY"] : null; string oldPath = psi.EnvironmentVariables["PATH"]; psi.Arguments = string.Concat("-c \"mono '", psi.FileName, "' ", psi.Arguments.Replace("\\", "\\\\").Replace("\"", "\\\""), "\" ", display.User); psi.FileName = "/bin/su"; psi.EnvironmentVariables["DISPLAY"] = display.Display; psi.EnvironmentVariables["XAUTHORITY"] = display.Authority; psi.EnvironmentVariables["MONO_PATH"] = psi.EnvironmentVariables["PATH"] = oldPath.Replace(';', ':'); psi.UseShellExecute = false; Process proc = Process.Start(psi); psi.Arguments = oldArgs; psi.FileName = oldFile; if (oldDisplay == null) { psi.EnvironmentVariables.Remove("DISPLAY"); } else { psi.EnvironmentVariables["DISPLAY"] = oldDisplay; } if (oldAuth == null) { psi.EnvironmentVariables.Remove("XAUTHORITY"); } else { psi.EnvironmentVariables["XAUTHORITY"] = oldAuth; } psi.EnvironmentVariables["PATH"] = oldPath; psi.EnvironmentVariables.Remove("MONO_PATH"); string pidStr; do { pidStr = File.ReadAllText(string.Format("/proc/{0}/task/{0}/children", proc.Id)).Trim(); } while (string.IsNullOrEmpty(pidStr)); int pid; if (int.TryParse(pidStr, out pid)) { proc.EnableRaisingEvents = true; Process realProc = Process.GetProcessById(pid); proc.Exited += (sender, e) => { if (!realProc.HasExited) { realProc.Kill(); } }; } else { Console.Error.WriteLine("Unable to find real process"); } return(proc); }
public DisplayDetectData DetectDisplay(string id) { setutxent(); IntPtr utxp; List <DisplayDetectData> displays = new List <DisplayDetectData>(); while ((utxp = getutxent()) != IntPtr.Zero) { utmpx utx = (utmpx)Marshal.PtrToStructure(utxp, typeof(utmpx)); if (utx.ut_type == USER_PROCESS && utx.ut_host[0] != 0) { string authority = GetAuthority(utx.ut_pid); if (authority != null) { displays.Add(new DisplayDetectData() { User = new string(utx.ut_user, 0, Array.IndexOf(utx.ut_user, '\0')), Display = new string(utx.ut_host, 0, Array.IndexOf(utx.ut_host, '\0')), Authority = authority }); } } } endutxent(); switch (displays.Count) { case 0: Console.Error.WriteLine("No displays found"); return(new DisplayDetectData()); case 1: DisplayDetectData data = displays[0]; data.Detected = true; return(data); default: List <VerificationState> verification; if (VerificationStates.ContainsKey(id)) { verification = VerificationStates[id]; } else { verification = VerificationStates[id] = new List <VerificationState>(); } if (verification.Any(s => !s.HasDenied)) { VerificationState confirmed = verification.FirstOrDefault(s => s.HasConfirmed); if (confirmed == null) { return(new DisplayDetectData() { Token = verification.First().Display.Token }); } else { VerificationStates.Remove(id); return(new DisplayDetectData() { Detected = true, User = confirmed.Display.User, Display = confirmed.Display.Display, Authority = confirmed.Display.Authority }); } } else { verification.Clear(); string token = new Random().Next(1000000).ToString().PadLeft(6, '0'); ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = Assembly.GetEntryAssembly().CodeBase; psi.Arguments = string.Concat("confirm ", token); foreach (DisplayDetectData display in displays) { VerificationState state = new VerificationState() { Display = display, SessionId = id, HasConfirmed = false, HasDenied = false }; display.Token = token; Process proc = Start(psi, display); proc.EnableRaisingEvents = true; proc.Exited += (sender, e) => { if (proc.ExitCode == 0) { state.HasConfirmed = true; foreach (VerificationState s in verification) { if (!s.Process.HasExited) { s.Process.Kill(); } } } else { state.HasDenied = true; } }; state.Process = proc; verification.Add(state); } return(new DisplayDetectData() { Token = token }); } } }
public Process Start(ProcessStartInfo psi, DisplayDetectData display) { if (IsService) { /* * Doesn't support: * psi.Domain * psi.ErrorDialog * psi.ErrorDialogParentHandle * psi.LoadUserProfile * psi.Password * psi.RedirectStandardError * psi.RedirectStandardInput * psi.RedirectStandardOutput * psi.StandardErrorEncoding * psi.StandardInputEncoding * psi.StandardOutputEncoding * psi.UserName * psi.UseShellExecute * psi.Verb * psi.Verbs */ IntPtr accessToken = AccessToken; if (accessToken != IntPtr.Zero) { try { STARTUPINFO startInfo = new STARTUPINFO() { cb = (uint)Marshal.SizeOf(typeof(STARTUPINFO)), lpDesktop = "winsta0\\default", dwFlags = STARTF_USESHOWWINDOW }; switch (psi.WindowStyle) { case ProcessWindowStyle.Hidden: startInfo.wShowWindow = SW_HIDE; break; case ProcessWindowStyle.Maximized: startInfo.wShowWindow = SW_MAXIMIZE; break; case ProcessWindowStyle.Minimized: startInfo.wShowWindow = SW_MINIMIZE; break; case ProcessWindowStyle.Normal: startInfo.wShowWindow = SW_SHOWNORMAL; break; default: startInfo.dwFlags ^= STARTF_USESHOWWINDOW; break; } PROCESS_INFORMATION procInfo; string monoExe = Type.GetType("Mono.Runtime") == null ? null : Environment.GetEnvironmentVariable("_"); IEnumerable <byte[]> envVars = psi.EnvironmentVariables.Cast <DictionaryEntry>().Select(e => Encoding.Unicode.GetBytes(string.Concat(e.Key.ToString(), "=", e.Value.ToString()))); int len = envVars.Select(e => e.Length + 2).Sum() + 2; IntPtr environ = Marshal.AllocHGlobal(len); try { IntPtr it = environ; foreach (byte[] var in envVars) { foreach (byte b in var) { Marshal.WriteByte(it, b); it = IntPtr.Add(it, 1); } Marshal.WriteInt16(it, 0); it = IntPtr.Add(it, 2); } Marshal.WriteInt16(it, 0); SECURITY_ATTRIBUTES procSec = new SECURITY_ATTRIBUTES(); SECURITY_ATTRIBUTES threadSec = new SECURITY_ATTRIBUTES(); procSec.nLength = Marshal.SizeOf(procSec); threadSec.nLength = Marshal.SizeOf(threadSec); if (CreateProcessAsUser(accessToken, null, string.Concat(monoExe == null ? string.Concat("\"", EscapeProcessParameter(psi.FileName), "\" ") : string.Concat("\"", EscapeProcessParameter(monoExe), "\" \"", EscapeProcessParameter(psi.FileName), "\" "), psi.Arguments), ref procSec, ref threadSec, false, CREATE_UNICODE_ENVIRONMENT | (psi.CreateNoWindow ? CREATE_NO_WINDOW : 0), environ, psi.WorkingDirectory, ref startInfo, out procInfo)) { CloseHandle(procInfo.hThread); try { Process proc = new Process(); proc.StartInfo = psi; Type Process = typeof(Process); MethodInfo SetProcessHandle = Process.GetMethod("SetProcessHandle", BindingFlags.NonPublic | BindingFlags.Instance); if (SetProcessHandle == null) { WindowsService.WriteLog("Unable to find System.Diagnostics.Process.SetProcessHandle(Microsoft.Win32.SafeHandles.SafeProcessHandle)"); } else { ConstructorInfo ctor = SetProcessHandle.GetParameters()[0].ParameterType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new [] { typeof(IntPtr) }, null); if (ctor == null) { WindowsService.WriteLog("Unable to find Microsoft.Win32.SafeHandles.SafeProcessHandle.SafeProcessHandle(IntPtr)"); } else { object procHandle = ctor.Invoke(new object[] { procInfo.hProcess }); SetProcessHandle.Invoke(proc, new [] { procHandle }); MethodInfo SetProcessId = Process.GetMethod("SetProcessId", BindingFlags.NonPublic | BindingFlags.Instance); if (SetProcessId == null) { WindowsService.WriteLog("Unable to find System.Diagnostics.Process.SetProcessId(int)"); } else { SetProcessId.Invoke(proc, new object[] { (int)procInfo.dwProcessId }); return(proc); } } } } catch (Exception ex) { WindowsService.WriteLog(ex); } CloseHandle(procInfo.hProcess); return(Process.GetProcessById((int)procInfo.dwProcessId)); } else { Error("CreateProcessAsUser"); return(null); } } finally { Marshal.FreeHGlobal(environ); } } finally { CloseHandle(accessToken); } } return(null); } else { return(Process.Start(psi)); } }