mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
175 lines
6.2 KiB
C#
175 lines
6.2 KiB
C#
using Microsoft.AspNetCore.SignalR.Client;
|
|
using Remotely.Shared.Enums;
|
|
using Remotely.Shared.Models;
|
|
using Remotely.Shared.Utilities;
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Remotely.Agent.Services
|
|
{
|
|
public class ScriptExecutor
|
|
{
|
|
public ScriptExecutor(ConfigService configService)
|
|
{
|
|
ConfigService = configService;
|
|
}
|
|
|
|
private ConfigService ConfigService { get; }
|
|
|
|
public async Task RunCommandFromApi(ScriptingShell shell,
|
|
string requestID,
|
|
string command,
|
|
string senderUsername,
|
|
string authToken,
|
|
HubConnection hubConnection)
|
|
{
|
|
try
|
|
{
|
|
|
|
var result = ExecuteScriptContent(shell, requestID, command, TimeSpan.FromMinutes(AppConstants.ScriptRunExpirationMinutes));
|
|
|
|
result.InputType = ScriptInputType.Api;
|
|
result.SenderUserName = senderUsername;
|
|
|
|
await SendResultsToApi(result, authToken);
|
|
await hubConnection.SendAsync("ScriptResultViaApi", requestID);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
}
|
|
|
|
public async Task RunCommandFromTerminal(ScriptingShell shell,
|
|
string command,
|
|
string authToken,
|
|
string senderUsername,
|
|
string senderConnectionID,
|
|
ScriptInputType scriptInputType,
|
|
TimeSpan timeout,
|
|
HubConnection hubConnection)
|
|
{
|
|
try
|
|
{
|
|
var result = ExecuteScriptContent(shell, senderConnectionID, command, timeout);
|
|
|
|
result.InputType = scriptInputType;
|
|
result.SenderUserName = senderUsername;
|
|
|
|
var responseResult = await SendResultsToApi(result, authToken);
|
|
if (responseResult is null)
|
|
{
|
|
return;
|
|
}
|
|
await hubConnection.SendAsync("ScriptResult", responseResult.ID);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
await hubConnection.SendAsync("DisplayMessage",
|
|
"There was an error executing the command. It has been logged on the client device.",
|
|
"Error executing command.",
|
|
"bg-danger",
|
|
senderConnectionID);
|
|
}
|
|
}
|
|
|
|
public async Task RunScript(Guid savedScriptId,
|
|
int scriptRunId,
|
|
string initiator,
|
|
ScriptInputType scriptInputType,
|
|
string authToken)
|
|
{
|
|
try
|
|
{
|
|
Logger.Write($"Script run started. Script ID: {savedScriptId}. Script Run: {scriptRunId}. Initiator: {initiator}.");
|
|
|
|
var connectionInfo = ConfigService.GetConnectionInfo();
|
|
var url = $"{connectionInfo.Host}/API/SavedScripts/{savedScriptId}";
|
|
using var hc = new HttpClient();
|
|
hc.DefaultRequestHeaders.Add("Authorization", authToken);
|
|
var savedScript = await hc.GetFromJsonAsync<SavedScript>(url);
|
|
|
|
var result = ExecuteScriptContent(savedScript.Shell,
|
|
Guid.NewGuid().ToString(),
|
|
savedScript.Content,
|
|
TimeSpan.FromMinutes(AppConstants.ScriptRunExpirationMinutes));
|
|
|
|
result.SenderUserName = initiator;
|
|
result.ScriptRunId = scriptRunId;
|
|
result.InputType = scriptInputType;
|
|
result.SavedScriptId = savedScriptId;
|
|
|
|
var responseResult = await SendResultsToApi(result, authToken);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Write(ex);
|
|
}
|
|
}
|
|
|
|
// TODO: Async/await.
|
|
private ScriptResult ExecuteScriptContent(ScriptingShell shell,
|
|
string terminalSessionId,
|
|
string command,
|
|
TimeSpan timeout)
|
|
{
|
|
switch (shell)
|
|
{
|
|
case ScriptingShell.PSCore:
|
|
return PSCore.GetCurrent(terminalSessionId).WriteInput(command);
|
|
|
|
case ScriptingShell.WinPS:
|
|
if (EnvironmentHelper.IsWindows)
|
|
{
|
|
return ExternalScriptingShell
|
|
.GetCurrent(ScriptingShell.WinPS, terminalSessionId)
|
|
.WriteInput(command, timeout);
|
|
|
|
}
|
|
break;
|
|
|
|
case ScriptingShell.CMD:
|
|
if (EnvironmentHelper.IsWindows)
|
|
{
|
|
return ExternalScriptingShell
|
|
.GetCurrent(ScriptingShell.CMD, terminalSessionId)
|
|
.WriteInput(command, timeout);
|
|
}
|
|
break;
|
|
|
|
case ScriptingShell.Bash:
|
|
return ExternalScriptingShell
|
|
.GetCurrent(ScriptingShell.Bash, terminalSessionId)
|
|
.WriteInput(command, timeout);
|
|
default:
|
|
break;
|
|
}
|
|
return null;
|
|
}
|
|
private async Task<ScriptResult> SendResultsToApi(object result, string authToken)
|
|
{
|
|
var targetURL = ConfigService.GetConnectionInfo().Host + $"/API/ScriptResults";
|
|
|
|
using var httpClient = new HttpClient();
|
|
httpClient.DefaultRequestHeaders.Add("Authorization", authToken);
|
|
|
|
using var response = await httpClient.PostAsJsonAsync(targetURL, result);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
Logger.Write($"Failed to send script results. Status Code: {response.StatusCode}");
|
|
return default;
|
|
}
|
|
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
return JsonSerializer.Deserialize<ScriptResult>(content, JsonSerializerHelper.CaseInsensitiveOptions);
|
|
}
|
|
}
|
|
} |