public DeviceSocket(ConfigService configService, Uninstaller uninstaller, CommandExecutor commandExecutor, ScriptRunner scriptRunner, AppLauncher appLauncher, ChatClientService chatService) { ConfigService = configService; Uninstaller = uninstaller; CommandExecutor = commandExecutor; ScriptRunner = scriptRunner; AppLauncher = appLauncher; ChatService = chatService; }
public AgentSocket(ConfigService configService, Uninstaller uninstaller, CommandExecutor commandExecutor, ScriptRunner scriptRunner, ChatHostService chatService, IAppLauncher appLauncher, IUpdater updater) { ConfigService = configService; Uninstaller = uninstaller; CommandExecutor = commandExecutor; ScriptRunner = scriptRunner; AppLauncher = appLauncher; ChatService = chatService; Updater = updater; }
public AgentSocket(ConfigService configService, Uninstaller uninstaller, ScriptExecutor scriptExecutor, ChatClientService chatService, IAppLauncher appLauncher, IUpdater updater, IDeviceInformationService deviceInfoService) { _configService = configService; _uninstaller = uninstaller; _scriptExecutor = scriptExecutor; _appLauncher = appLauncher; _chatService = chatService; _updater = updater; _deviceInfoService = deviceInfoService; }
private void RegisterMessageHandlers() { // TODO: Remove possibility for circular dependencies in the future // by emitting these events so other services can listen for them. HubConnection.On("Chat", async(string senderName, string message, string orgName, bool disconnected, string senderConnectionID) => { try { if (!IsServerVerified) { Logger.Write("Chat attempted before server was verified.", EventType.Warning); return; } await ChatService.SendMessage(senderName, message, orgName, disconnected, senderConnectionID, HubConnection); } catch (Exception ex) { Logger.Write(ex); } }); HubConnection.On("DownloadFile", async(string filePath, string senderConnectionID) => { try { if (!IsServerVerified) { Logger.Write("File download attempted before server was verified.", EventType.Warning); return; } filePath = filePath.Replace("\"", ""); if (!File.Exists(filePath)) { await HubConnection.SendAsync("DisplayMessage", "File not found on remote device.", "File not found.", senderConnectionID); return; } using var wc = new WebClient(); var lastProgressPercent = 0; wc.UploadProgressChanged += async(sender, args) => { if (args.ProgressPercentage > lastProgressPercent) { lastProgressPercent = args.ProgressPercentage; await HubConnection.SendAsync("DownloadFileProgress", lastProgressPercent, senderConnectionID); } }; try { var response = await wc.UploadFileTaskAsync($"{ConnectionInfo.Host}/API/FileSharing/", filePath); var fileIDs = JsonSerializer.Deserialize <string[]>(Encoding.UTF8.GetString(response)); await HubConnection.SendAsync("DownloadFile", fileIDs[0], senderConnectionID); } catch (Exception ex) { Logger.Write(ex); await HubConnection.SendAsync("DisplayMessage", "Error occurred while uploading file from remote computer.", "Upload error.", senderConnectionID); } } catch (Exception ex) { Logger.Write(ex); } }); HubConnection.On("ChangeWindowsSession", async(string serviceID, string viewerID, int targetSessionID) => { try { if (!IsServerVerified) { Logger.Write("Session change attempted before server was verified.", EventType.Warning); return; } await AppLauncher.RestartScreenCaster(new List <string>() { viewerID }, serviceID, viewerID, HubConnection, targetSessionID); } catch (Exception ex) { Logger.Write(ex); } }); HubConnection.On("ExecuteCommand", (async(string mode, string command, string commandID, string senderConnectionID) => { try { if (!IsServerVerified) { Logger.Write($"Command attempted before server was verified. Mode: {mode}. Command: {command}. Sender: {senderConnectionID}", EventType.Warning); return; } await CommandExecutor.ExecuteCommand(mode, command, commandID, senderConnectionID, HubConnection); } catch (Exception ex) { Logger.Write(ex); } })); HubConnection.On("ExecuteCommandFromApi", (async(string mode, string requestID, string command, string commandID, string senderUserName) => { try { if (!IsServerVerified) { Logger.Write($"Command attempted before server was verified. Mode: {mode}. Command: {command}. Sender: {senderUserName}", EventType.Warning); return; } await CommandExecutor.ExecuteCommandFromApi(mode, requestID, command, commandID, senderUserName, HubConnection); } catch (Exception ex) { Logger.Write(ex); } })); HubConnection.On("UploadFiles", async(string transferID, List <string> fileIDs, string requesterID) => { try { if (!IsServerVerified) { Logger.Write("File upload attempted before server was verified.", EventType.Warning); return; } Logger.Write($"File upload started by {requesterID}."); var sharedFilePath = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "RemotelySharedFiles")).FullName; foreach (var fileID in fileIDs) { var url = $"{ConnectionInfo.Host}/API/FileSharing/{fileID}"; var wr = WebRequest.CreateHttp(url); using var response = await wr.GetResponseAsync(); var cd = response.Headers["Content-Disposition"]; var filename = cd .Split(";") .FirstOrDefault(x => x.Trim() .StartsWith("filename")) .Split("=")[1]; var legalChars = filename.ToCharArray().Where(x => !Path.GetInvalidFileNameChars().Any(y => x == y)); filename = new string(legalChars.ToArray()); using var rs = response.GetResponseStream(); using var fs = new FileStream(Path.Combine(sharedFilePath, filename), FileMode.Create); rs.CopyTo(fs); } await HubConnection.SendAsync("TransferCompleted", transferID, requesterID); } catch (Exception ex) { Logger.Write(ex); } }); HubConnection.On("DeployScript", async(string mode, string fileID, string commandResultID, string requesterID) => { try { if (!IsServerVerified) { Logger.Write($"Script deploy attempted before server was verified. Mode: {mode}. File ID: {fileID}. Sender: {requesterID}", EventType.Warning); return; } await ScriptRunner.RunScript(mode, fileID, commandResultID, requesterID, HubConnection); } catch (Exception ex) { Logger.Write(ex); } }); HubConnection.On("ReinstallAgent", async() => { try { await Updater.InstallLatestVersion(); } catch (Exception ex) { Logger.Write(ex); } }); HubConnection.On("UninstallAgent", () => { try { Uninstaller.UninstallAgent(); } catch (Exception ex) { Logger.Write(ex); } }); HubConnection.On("RemoteControl", async(string requesterID, string serviceID) => { try { if (!IsServerVerified) { Logger.Write("Remote control attempted before server was verified.", EventType.Warning); return; } await AppLauncher.LaunchRemoteControl(-1, requesterID, serviceID, HubConnection); } catch (Exception ex) { Logger.Write(ex); } }); HubConnection.On("RestartScreenCaster", async(List <string> viewerIDs, string serviceID, string requesterID) => { try { if (!IsServerVerified) { Logger.Write("Remote control attempted before server was verified.", EventType.Warning); return; } await AppLauncher.RestartScreenCaster(viewerIDs, serviceID, requesterID, HubConnection); } catch (Exception ex) { Logger.Write(ex); } }); HubConnection.On("CtrlAltDel", () => { if (!IsServerVerified) { Logger.Write("CtrlAltDel attempted before server was verified.", EventType.Warning); return; } User32.SendSAS(false); }); HubConnection.On("TriggerHeartbeat", async() => { await SendHeartbeat(); }); HubConnection.On("ServerVerificationToken", (string verificationToken) => { if (verificationToken == ConnectionInfo.ServerVerificationToken) { IsServerVerified = true; } else { Logger.Write($"Server sent an incorrect verification token. Token Sent: {verificationToken}.", EventType.Warning); return; } }); }
private static async Task ExecuteCommand(string mode, string command, string commandID, string senderConnectionID) { if (!IsServerVerified) { Logger.Write($"Command attempted before server was verified. Mode: {mode}. Command: {command}. Sender: {senderConnectionID}"); Uninstaller.UninstallAgent(); return; } try { switch (mode.ToLower()) { case "pscore": { var psCoreResult = PSCore.GetCurrent(senderConnectionID).WriteInput(command, commandID); var serializedResult = JsonConvert.SerializeObject(psCoreResult); if (Encoding.UTF8.GetBytes(serializedResult).Length > 400000) { SendResultsViaAjax("PSCore", psCoreResult); await HubConnection.InvokeAsync("PSCoreResultViaAjax", commandID); } else { await HubConnection.InvokeAsync("PSCoreResult", psCoreResult); } break; } case "winps": if (OSUtils.IsWindows) { var result = WindowsPS.GetCurrent(senderConnectionID).WriteInput(command, commandID); var serializedResult = JsonConvert.SerializeObject(result); if (Encoding.UTF8.GetBytes(serializedResult).Length > 400000) { SendResultsViaAjax("WinPS", result); await HubConnection.InvokeAsync("WinPSResultViaAjax", commandID); } else { await HubConnection.InvokeAsync("CommandResult", result); } } break; case "cmd": if (OSUtils.IsWindows) { var result = CMD.GetCurrent(senderConnectionID).WriteInput(command, commandID); var serializedResult = JsonConvert.SerializeObject(result); if (Encoding.UTF8.GetBytes(serializedResult).Length > 400000) { SendResultsViaAjax("CMD", result); await HubConnection.InvokeAsync("CMDResultViaAjax", commandID); } else { await HubConnection.InvokeAsync("CommandResult", result); } } break; case "bash": if (OSUtils.IsLinux) { var result = Bash.GetCurrent(senderConnectionID).WriteInput(command, commandID); var serializedResult = JsonConvert.SerializeObject(result); if (Encoding.UTF8.GetBytes(serializedResult).Length > 400000) { SendResultsViaAjax("Bash", result); } else { await HubConnection.InvokeAsync("CommandResult", result); } } break; default: break; } } catch (Exception ex) { Logger.Write(ex); await HubConnection.InvokeAsync("DisplayConsoleMessage", $"There was an error executing the command. It has been logged on the client device.", senderConnectionID); } }
private static void RegisterMessageHandlers(HubConnection hubConnection) { hubConnection.On("ExecuteCommand", (async(string mode, string command, string commandID, string senderConnectionID) => { await ExecuteCommand(mode, command, commandID, senderConnectionID); })); hubConnection.On("TransferFiles", async(string transferID, List <string> fileIDs, string requesterID) => { Logger.Write($"File transfer started by {requesterID}."); var connectionInfo = Utilities.GetConnectionInfo(); var sharedFilePath = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "RemotelySharedFiles")).FullName; foreach (var fileID in fileIDs) { var url = $"{connectionInfo.Host}/API/FileSharing/{fileID}"; var wr = WebRequest.CreateHttp(url); var response = await wr.GetResponseAsync(); var cd = response.Headers["Content-Disposition"]; var filename = cd .Split(";") .FirstOrDefault(x => x.Trim() .StartsWith("filename")) .Split("=")[1]; var legalChars = filename.ToCharArray().Where(x => !Path.GetInvalidFileNameChars().Any(y => x == y)); filename = new string(legalChars.ToArray()); using (var rs = response.GetResponseStream()) { using (var fs = new FileStream(Path.Combine(sharedFilePath, filename), FileMode.Create)) { rs.CopyTo(fs); } } } await HubConnection.InvokeAsync("TransferCompleted", transferID, requesterID); }); hubConnection.On("DeployScript", async(string mode, string fileID, string commandContextID, string requesterID) => { var connectionInfo = Utilities.GetConnectionInfo(); var sharedFilePath = Directory.CreateDirectory(Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Remotely", "SharedFiles" )).FullName; var webClient = new WebClient(); var url = $"{connectionInfo.Host}/API/FileSharing/{fileID}"; var wr = WebRequest.CreateHttp(url); var response = await wr.GetResponseAsync(); var cd = response.Headers["Content-Disposition"]; var filename = cd.Split(";").FirstOrDefault(x => x.Trim().StartsWith("filename")).Split("=")[1]; using (var rs = response.GetResponseStream()) { using (var sr = new StreamReader(rs)) { var result = await sr.ReadToEndAsync(); await ExecuteCommand(mode, result, commandContextID, requesterID); } } }); hubConnection.On("UninstallClient", () => { Uninstaller.UninstallAgent(); }); hubConnection.On("RemoteControl", async(string requesterID, string serviceID) => { if (!IsServerVerified) { Logger.Write("Remote control attempted before server was verified."); Uninstaller.UninstallAgent(); return; } try { var rcBinaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ScreenCast", OSUtils.ScreenCastExecutableFileName); if (!File.Exists(rcBinaryPath)) { await hubConnection.InvokeAsync("DisplayConsoleMessage", "Remote control executable not found on target device.", requesterID); return; } // Start ScreenCast. await hubConnection.InvokeAsync("DisplayConsoleMessage", $"Starting remote control...", requesterID); if (OSUtils.IsWindows) { if (Program.IsDebug) { Process.Start(rcBinaryPath, $"-mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -desktop default"); } else { var result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -desktop default", "default", true, out _); if (!result) { await hubConnection.InvokeAsync("DisplayConsoleMessage", "Remote control failed to start on target device.", requesterID); } } } else if (OSUtils.IsLinux) { var users = OSUtils.StartProcessWithResults("users", ""); var username = users?.Split()?.FirstOrDefault()?.Trim(); var homeDir = OSUtils.StartProcessWithResults("sudo", $"-u {username} env | grep HOME")?.Split('=')?.Last(); var psi = new ProcessStartInfo() { FileName = "sudo", Arguments = $"-u {username} {rcBinaryPath} -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -desktop default & disown" }; psi.Environment.Add("DISPLAY", ":0"); psi.Environment.Add("XAUTHORITY", $"{homeDir}/.Xauthority"); var casterProc = Process.Start(psi); casterProc.WaitForExit(); } } catch (Exception ex) { Logger.Write(ex); await hubConnection.InvokeAsync("DisplayConsoleMessage", "Remote control failed to start on target device.", requesterID); throw; } }); hubConnection.On("RestartScreenCaster", async(List <string> viewerIDs, string serviceID, string requesterID) => { if (!IsServerVerified) { Logger.Write("Remote control attempted before server was verified."); Uninstaller.UninstallAgent(); return; } try { var rcBinaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ScreenCast", OSUtils.ScreenCastExecutableFileName); // Start ScreenCast. if (OSUtils.IsWindows) { Logger.Write("Restarting screen caster."); if (Program.IsDebug) { var proc = Process.Start(rcBinaryPath, $"-mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)}"); var stopwatch = Stopwatch.StartNew(); while (stopwatch.Elapsed.TotalSeconds < 10) { await Task.Delay(250); if (Process.GetProcessesByName(Path.GetFileNameWithoutExtension(rcBinaryPath))?.Where(x => x.Id == proc.Id)?.Count() > 0 != true) { Logger.Write("Restarting screen caster after failed relaunch."); } } } else { var result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)}", "default", true, out var procInfo); if (result) { // This relaunch might have been prompted by a user logging out, which would close // the screencaster process. In that scenario, the relaunched process can get closed again // while the Windows sign-out process is still occurring. We'll wait a bit to make sure the // relaunched process is still running. If not, launch again. var stopwatch = Stopwatch.StartNew(); while (stopwatch.Elapsed.TotalSeconds < 10) { await Task.Delay(250); if (Process.GetProcessesByName(Path.GetFileNameWithoutExtension(rcBinaryPath))?.Where(x => x.Id == procInfo.dwProcessId)?.Count() > 0 != true) { Logger.Write("Restarting screen caster after failed relaunch."); result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)}", "default", true, out procInfo); } } } if (!result) { Logger.Write("Failed to relaunch screen caster."); await hubConnection.InvokeAsync("SendConnectionFailedToViewers", viewerIDs); await hubConnection.InvokeAsync("DisplayConsoleMessage", "Remote control failed to start on target device.", requesterID); } } } else if (OSUtils.IsLinux) { var users = OSUtils.StartProcessWithResults("users", ""); var username = users?.Split()?.FirstOrDefault()?.Trim(); var homeDir = OSUtils.StartProcessWithResults("sudo", $"-u {username} env | grep HOME")?.Split('=')?.Last(); var psi = new ProcessStartInfo() { FileName = "sudo", Arguments = $"-u {username} {rcBinaryPath} -mode Unattended -requester {requesterID} -serviceid {serviceID} -deviceid {ConnectionInfo.DeviceID} -host {Utilities.GetConnectionInfo().Host} -relaunch true -desktop default -viewers {String.Join(",", viewerIDs)} & disown" }; psi.Environment.Add("DISPLAY", ":0"); psi.Environment.Add("XAUTHORITY", $"{homeDir}/.Xauthority"); var casterProc = Process.Start(psi); casterProc.WaitForExit(); } } catch (Exception ex) { await hubConnection.InvokeAsync("SendConnectionFailedToViewers", viewerIDs); Logger.Write(ex); throw; } }); hubConnection.On("CtrlAltDel", () => { User32.SendSAS(false); }); hubConnection.On("ServerVerificationToken", (string verificationToken) => { if (verificationToken == Utilities.GetConnectionInfo().ServerVerificationToken) { IsServerVerified = true; if (!Program.IsDebug) { Updater.CheckForCoreUpdates(); } } else { Logger.Write($"Server sent an incorrect verification token. Token Sent: {verificationToken}."); Uninstaller.UninstallAgent(); return; } }); }
private void RegisterMessageHandlers() { HubConnection.On("Chat", async(string message, string senderConnectionID) => { await ChatService.SendMessage(message, senderConnectionID, HubConnection); }); HubConnection.On("ExecuteCommand", (async(string mode, string command, string commandID, string senderConnectionID) => { if (!IsServerVerified) { Logger.Write($"Command attempted before server was verified. Mode: {mode}. Command: {command}. Sender: {senderConnectionID}"); Uninstaller.UninstallAgent(); return; } await CommandExecutor.ExecuteCommand(mode, command, commandID, senderConnectionID, HubConnection); })); HubConnection.On("TransferFiles", async(string transferID, List <string> fileIDs, string requesterID) => { Logger.Write($"File transfer started by {requesterID}."); var sharedFilePath = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "RemotelySharedFiles")).FullName; foreach (var fileID in fileIDs) { var url = $"{ConnectionInfo.Host}/API/FileSharing/{fileID}"; var wr = WebRequest.CreateHttp(url); var response = await wr.GetResponseAsync(); var cd = response.Headers["Content-Disposition"]; var filename = cd .Split(";") .FirstOrDefault(x => x.Trim() .StartsWith("filename")) .Split("=")[1]; var legalChars = filename.ToCharArray().Where(x => !Path.GetInvalidFileNameChars().Any(y => x == y)); filename = new string(legalChars.ToArray()); using (var rs = response.GetResponseStream()) { using (var fs = new FileStream(Path.Combine(sharedFilePath, filename), FileMode.Create)) { rs.CopyTo(fs); } } } await this.HubConnection.InvokeAsync("TransferCompleted", transferID, requesterID); }); HubConnection.On("DeployScript", async(string mode, string fileID, string commandContextID, string requesterID) => { if (!IsServerVerified) { Logger.Write($"Script deploy attempted before server was verified. Mode: {mode}. File ID: {fileID}. Sender: {requesterID}"); Uninstaller.UninstallAgent(); return; } await ScriptRunner.RunScript(mode, fileID, commandContextID, requesterID, HubConnection); }); HubConnection.On("UninstallClient", () => { Uninstaller.UninstallAgent(); }); HubConnection.On("RemoteControl", async(string requesterID, string serviceID) => { if (!IsServerVerified) { Logger.Write("Remote control attempted before server was verified."); Uninstaller.UninstallAgent(); return; } await AppLauncher.LaunchRemoteControl(requesterID, serviceID, HubConnection); }); HubConnection.On("RestartScreenCaster", async(List <string> viewerIDs, string serviceID, string requesterID) => { if (!IsServerVerified) { Logger.Write("Remote control attempted before server was verified."); Uninstaller.UninstallAgent(); return; } await AppLauncher.RestartScreenCaster(viewerIDs, serviceID, requesterID, HubConnection); }); HubConnection.On("CtrlAltDel", () => { User32.SendSAS(false); }); HubConnection.On("ServerVerificationToken", (string verificationToken) => { if (verificationToken == ConnectionInfo.ServerVerificationToken) { IsServerVerified = true; if (!Program.IsDebug) { _ = Task.Run(Updater.CheckForUpdates); } } else { Logger.Write($"Server sent an incorrect verification token. Token Sent: {verificationToken}."); Uninstaller.UninstallAgent(); return; } }); }