mirror of
https://github.com/immense/Remotely.git
synced 2025-10-26 11:27:15 +00:00
Bug - Proto forwarded header not being seen by ASP.NET Core. (#554)
* Set permissions on log file so non-elevated process can write to it. * Replace more instances of static Logger with ILogger<T>. * Add default Docker host to known proxies. * Update Immense.RemoteControl * Update Immense.RemoteControl
This commit is contained in:
parent
9cc964f52f
commit
56ee561ca2
@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Remotely.Agent.Interfaces;
|
||||
using Remotely.Shared.Models;
|
||||
using Remotely.Shared.Services;
|
||||
@ -20,11 +21,16 @@ namespace Remotely.Agent.Services
|
||||
private readonly string _rcBinaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Desktop", EnvironmentHelper.DesktopExecutableFileName);
|
||||
private readonly IProcessInvoker _processInvoker;
|
||||
private readonly ConnectionInfo _connectionInfo;
|
||||
private readonly ILogger<AppLauncherLinux> _logger;
|
||||
|
||||
public AppLauncherLinux(ConfigService configService, IProcessInvoker processInvoker)
|
||||
public AppLauncherLinux(
|
||||
ConfigService configService,
|
||||
IProcessInvoker processInvoker,
|
||||
ILogger<AppLauncherLinux> logger)
|
||||
{
|
||||
_processInvoker = processInvoker;
|
||||
_connectionInfo = configService.GetConnectionInfo();
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
@ -52,7 +58,7 @@ namespace Remotely.Agent.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while getting current X11 user.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +70,12 @@ namespace Remotely.Agent.Services
|
||||
|
||||
psi.Environment.Add("DISPLAY", display);
|
||||
psi.Environment.Add("XAUTHORITY", xauthority);
|
||||
Logger.Write($"Attempting to launch screen caster with username {username}, xauthority {xauthority}, display {display}, and args {args}.");
|
||||
_logger.LogInformation(
|
||||
"Attempting to launch screen caster with username {username}, xauthority {xauthority}, display {display}, and args {args}.",
|
||||
username,
|
||||
xauthority,
|
||||
display,
|
||||
args);
|
||||
return Process.Start(psi).Id;
|
||||
}
|
||||
|
||||
@ -123,7 +134,7 @@ namespace Remotely.Agent.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while starting chat.");
|
||||
await hubConnection.SendAsync("DisplayMessage", "Chat service failed to start on target device.", "Failed to start chat service.", "bg-danger", userConnectionId);
|
||||
}
|
||||
return -1;
|
||||
@ -159,7 +170,7 @@ namespace Remotely.Agent.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while launching remote control.");
|
||||
await hubConnection.SendAsync("DisplayMessage", "Remote control failed to start on target device.", "Failed to start remote control.", "bg-danger", userConnectionId);
|
||||
}
|
||||
}
|
||||
@ -182,7 +193,7 @@ namespace Remotely.Agent.Services
|
||||
catch (Exception ex)
|
||||
{
|
||||
await hubConnection.SendAsync("SendConnectionFailedToViewers", viewerIDs);
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while restarting screen caster.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Remotely.Agent.Interfaces;
|
||||
using Remotely.Shared.Models;
|
||||
using Remotely.Shared.Utilities;
|
||||
@ -18,11 +19,13 @@ namespace Remotely.Agent.Services
|
||||
public class AppLauncherWin : IAppLauncher
|
||||
{
|
||||
private readonly ConnectionInfo _connectionInfo;
|
||||
private readonly ILogger<AppLauncherWin> _logger;
|
||||
private readonly string _rcBinaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Desktop", EnvironmentHelper.DesktopExecutableFileName);
|
||||
|
||||
public AppLauncherWin(ConfigService configService)
|
||||
public AppLauncherWin(ConfigService configService, ILogger<AppLauncherWin> logger)
|
||||
{
|
||||
_connectionInfo = configService.GetConnectionInfo();
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<int> LaunchChatService(string pipeName, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection)
|
||||
@ -78,7 +81,7 @@ namespace Remotely.Agent.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while launching chat.");
|
||||
await hubConnection.SendAsync("DisplayMessage",
|
||||
"Chat service failed to start on target device.",
|
||||
"Failed to start chat service.",
|
||||
@ -148,7 +151,7 @@ namespace Remotely.Agent.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while launching remote control.");
|
||||
await hubConnection.SendAsync("DisplayMessage",
|
||||
"Remote control failed to start on target device.",
|
||||
"Failed to start remote control.",
|
||||
@ -161,7 +164,7 @@ namespace Remotely.Agent.Services
|
||||
try
|
||||
{
|
||||
// Start Desktop app.
|
||||
Logger.Write("Restarting screen caster.");
|
||||
_logger.LogInformation("Restarting screen caster.");
|
||||
if (WindowsIdentity.GetCurrent().IsSystem)
|
||||
{
|
||||
// Give a little time for session changing, etc.
|
||||
@ -186,7 +189,7 @@ namespace Remotely.Agent.Services
|
||||
|
||||
if (!result)
|
||||
{
|
||||
Logger.Write("Failed to relaunch screen caster.");
|
||||
_logger.LogWarning("Failed to relaunch screen caster.");
|
||||
await hubConnection.SendAsync("SendConnectionFailedToViewers", viewerIDs);
|
||||
await hubConnection.SendAsync("DisplayMessage",
|
||||
"Remote control failed to start on target device.",
|
||||
@ -212,7 +215,7 @@ namespace Remotely.Agent.Services
|
||||
catch (Exception ex)
|
||||
{
|
||||
await hubConnection.SendAsync("SendConnectionFailedToViewers", viewerIDs);
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while restarting screen caster.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Remotely.Agent.Interfaces;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Remotely.Agent.Interfaces;
|
||||
using Remotely.Shared.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -22,15 +23,21 @@ namespace Remotely.Agent.Services
|
||||
private readonly ConfigService _configService;
|
||||
private readonly IUpdateDownloader _updateDownloader;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly ILogger<UpdaterLinux> _logger;
|
||||
private readonly SemaphoreSlim _installLatestVersionLock = new(1, 1);
|
||||
private readonly System.Timers.Timer _updateTimer = new(TimeSpan.FromHours(6).TotalMilliseconds);
|
||||
private DateTimeOffset _lastUpdateFailure;
|
||||
|
||||
public UpdaterLinux(ConfigService configService, IUpdateDownloader updateDownloader, IHttpClientFactory httpClientFactory)
|
||||
public UpdaterLinux(
|
||||
ConfigService configService,
|
||||
IUpdateDownloader updateDownloader,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
ILogger<UpdaterLinux> logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_updateDownloader = updateDownloader;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
@ -62,7 +69,7 @@ namespace Remotely.Agent.Services
|
||||
|
||||
if (_lastUpdateFailure.AddDays(1) > DateTimeOffset.Now)
|
||||
{
|
||||
Logger.Write("Skipping update check due to previous failure. Restart the service to try again, or manually install the update.");
|
||||
_logger.LogInformation("Skipping update check due to previous failure. Restart the service to try again, or manually install the update.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -89,23 +96,23 @@ namespace Remotely.Agent.Services
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.NotModified)
|
||||
{
|
||||
Logger.Write("Service Updater: Version is current.");
|
||||
_logger.LogInformation("Service Updater: Version is current.");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Write("Service Updater: Update found.");
|
||||
_logger.LogInformation("Service Updater: Update found.");
|
||||
|
||||
await InstallLatestVersion();
|
||||
|
||||
}
|
||||
catch (WebException ex) when ((ex.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotModified)
|
||||
{
|
||||
Logger.Write("Service Updater: Version is current.");
|
||||
_logger.LogInformation("Service Updater: Version is current.");
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while checking for updates.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -122,7 +129,7 @@ namespace Remotely.Agent.Services
|
||||
var connectionInfo = _configService.GetConnectionInfo();
|
||||
var serverUrl = connectionInfo.Host;
|
||||
|
||||
Logger.Write("Service Updater: Downloading install package.");
|
||||
_logger.LogInformation("Service Updater: Downloading install package.");
|
||||
|
||||
var downloadId = Guid.NewGuid().ToString();
|
||||
var zipPath = Path.Combine(Path.GetTempPath(), "RemotelyUpdate.zip");
|
||||
@ -155,7 +162,7 @@ namespace Remotely.Agent.Services
|
||||
using var httpClient = _httpClientFactory.CreateClient();
|
||||
using var response = httpClient.GetAsync($"{serverUrl}/api/AgentUpdate/ClearDownload/{downloadId}");
|
||||
|
||||
Logger.Write("Launching installer to perform update.");
|
||||
_logger.LogInformation("Launching installer to perform update.");
|
||||
|
||||
Process.Start("sudo", $"chmod +x {installerPath}").WaitForExit();
|
||||
|
||||
@ -163,12 +170,12 @@ namespace Remotely.Agent.Services
|
||||
}
|
||||
catch (WebException ex) when (ex.Status == WebExceptionStatus.Timeout)
|
||||
{
|
||||
Logger.Write("Timed out while waiting to download update.", Shared.Enums.EventType.Warning);
|
||||
_logger.LogWarning("Timed out while waiting to download update.");
|
||||
_lastUpdateFailure = DateTimeOffset.Now;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while installing latest version.");
|
||||
_lastUpdateFailure = DateTimeOffset.Now;
|
||||
}
|
||||
finally
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Remotely.Agent.Interfaces;
|
||||
using Remotely.Shared.Utilities;
|
||||
using System;
|
||||
@ -23,15 +24,21 @@ namespace Remotely.Agent.Services
|
||||
private readonly ConfigService _configService;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly IUpdateDownloader _updateDownloader;
|
||||
private readonly ILogger<UpdaterMac> _logger;
|
||||
private readonly SemaphoreSlim _installLatestVersionLock = new(1, 1);
|
||||
private DateTimeOffset _lastUpdateFailure;
|
||||
private readonly System.Timers.Timer _updateTimer = new(TimeSpan.FromHours(6).TotalMilliseconds);
|
||||
|
||||
public UpdaterMac(ConfigService configService, IUpdateDownloader updateDownloader, IHttpClientFactory httpClientFactory)
|
||||
public UpdaterMac(
|
||||
ConfigService configService,
|
||||
IUpdateDownloader updateDownloader,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
ILogger<UpdaterMac> logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_updateDownloader = updateDownloader;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +70,7 @@ namespace Remotely.Agent.Services
|
||||
|
||||
if (_lastUpdateFailure.AddDays(1) > DateTimeOffset.Now)
|
||||
{
|
||||
Logger.Write("Skipping update check due to previous failure. Restart the service to try again, or manually install the update.");
|
||||
_logger.LogInformation("Skipping update check due to previous failure. Restart the service to try again, or manually install the update.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -90,23 +97,23 @@ namespace Remotely.Agent.Services
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.NotModified)
|
||||
{
|
||||
Logger.Write("Service Updater: Version is current.");
|
||||
_logger.LogInformation("Service Updater: Version is current.");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Write("Service Updater: Update found.");
|
||||
_logger.LogInformation("Service Updater: Update found.");
|
||||
|
||||
await InstallLatestVersion();
|
||||
|
||||
}
|
||||
catch (WebException ex) when ((ex.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotModified)
|
||||
{
|
||||
Logger.Write("Service Updater: Version is current.");
|
||||
_logger.LogInformation("Service Updater: Version is current.");
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while checking for updates.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -123,7 +130,7 @@ namespace Remotely.Agent.Services
|
||||
var connectionInfo = _configService.GetConnectionInfo();
|
||||
var serverUrl = connectionInfo.Host;
|
||||
|
||||
Logger.Write("Service Updater: Downloading install package.");
|
||||
_logger.LogInformation("Service Updater: Downloading install package.");
|
||||
|
||||
var downloadId = Guid.NewGuid().ToString();
|
||||
var zipPath = Path.Combine(Path.GetTempPath(), "RemotelyUpdate.zip");
|
||||
@ -141,7 +148,7 @@ namespace Remotely.Agent.Services
|
||||
using var httpClient = _httpClientFactory.CreateClient();
|
||||
using var response = httpClient.GetAsync($"{serverUrl}/api/AgentUpdate/ClearDownload/{downloadId}");
|
||||
|
||||
Logger.Write("Launching installer to perform update.");
|
||||
_logger.LogInformation("Launching installer to perform update.");
|
||||
|
||||
Process.Start("sudo", $"chmod +x {installerPath}").WaitForExit();
|
||||
|
||||
@ -149,12 +156,12 @@ namespace Remotely.Agent.Services
|
||||
}
|
||||
catch (WebException ex) when (ex.Status == WebExceptionStatus.Timeout)
|
||||
{
|
||||
Logger.Write("Timed out while waiting to download update.", Shared.Enums.EventType.Warning);
|
||||
_logger.LogWarning("Timed out while waiting to download update.");
|
||||
_lastUpdateFailure = DateTimeOffset.Now;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while installing latest version.");
|
||||
_lastUpdateFailure = DateTimeOffset.Now;
|
||||
}
|
||||
finally
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Remotely.Agent.Interfaces;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Remotely.Agent.Interfaces;
|
||||
using Remotely.Shared.Utilities;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
@ -17,16 +18,22 @@ namespace Remotely.Agent.Services
|
||||
private readonly ConfigService _configService;
|
||||
private readonly IUpdateDownloader _updateDownloader;
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly ILogger<UpdaterWin> _logger;
|
||||
private readonly SemaphoreSlim _installLatestVersionLock = new(1, 1);
|
||||
private readonly System.Timers.Timer _updateTimer = new(TimeSpan.FromHours(6).TotalMilliseconds);
|
||||
private DateTimeOffset _lastUpdateFailure;
|
||||
|
||||
|
||||
public UpdaterWin(ConfigService configService, IUpdateDownloader updateDownloader, IHttpClientFactory httpClientFactory)
|
||||
public UpdaterWin(
|
||||
ConfigService configService,
|
||||
IUpdateDownloader updateDownloader,
|
||||
IHttpClientFactory httpClientFactory,
|
||||
ILogger<UpdaterWin> logger)
|
||||
{
|
||||
_configService = configService;
|
||||
_updateDownloader = updateDownloader;
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task BeginChecking()
|
||||
@ -58,7 +65,7 @@ namespace Remotely.Agent.Services
|
||||
|
||||
if (_lastUpdateFailure.AddDays(1) > DateTimeOffset.Now)
|
||||
{
|
||||
Logger.Write("Skipping update check due to previous failure. Updating will be tried again after 24 hours have passed.");
|
||||
_logger.LogInformation("Skipping update check due to previous failure. Updating will be tried again after 24 hours have passed.");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -85,24 +92,24 @@ namespace Remotely.Agent.Services
|
||||
using var response = await httpClient.SendAsync(request);
|
||||
if (response.StatusCode == HttpStatusCode.NotModified)
|
||||
{
|
||||
Logger.Write("Service Updater: Version is current.");
|
||||
_logger.LogInformation("Service Updater: Version is current.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Logger.Write("Service Updater: Update found.");
|
||||
_logger.LogInformation("Service Updater: Update found.");
|
||||
|
||||
await InstallLatestVersion();
|
||||
|
||||
}
|
||||
catch (WebException ex) when ((ex.Response as HttpWebResponse).StatusCode == HttpStatusCode.NotModified)
|
||||
{
|
||||
Logger.Write("Service Updater: Version is current.");
|
||||
_logger.LogInformation("Service Updater: Version is current.");
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while checking for updates.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -119,7 +126,7 @@ namespace Remotely.Agent.Services
|
||||
var connectionInfo = _configService.GetConnectionInfo();
|
||||
var serverUrl = connectionInfo.Host;
|
||||
|
||||
Logger.Write("Service Updater: Downloading install package.");
|
||||
_logger.LogInformation("Service Updater: Downloading install package.");
|
||||
|
||||
var downloadId = Guid.NewGuid().ToString();
|
||||
var zipPath = Path.Combine(Path.GetTempPath(), "RemotelyUpdate.zip");
|
||||
@ -143,18 +150,18 @@ namespace Remotely.Agent.Services
|
||||
proc.Kill();
|
||||
}
|
||||
|
||||
Logger.Write("Launching installer to perform update.");
|
||||
_logger.LogInformation("Launching installer to perform update.");
|
||||
|
||||
Process.Start(installerPath, $"-install -quiet -path {zipPath} -serverurl {serverUrl} -organizationid {connectionInfo.OrganizationID}");
|
||||
}
|
||||
catch (WebException ex) when (ex.Status == WebExceptionStatus.Timeout)
|
||||
{
|
||||
Logger.Write("Timed out while waiting to download update.", Shared.Enums.EventType.Warning);
|
||||
_logger.LogWarning("Timed out while waiting to download update.");
|
||||
_lastUpdateFailure = DateTimeOffset.Now;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex);
|
||||
_logger.LogError(ex, "Error while installing latest version.");
|
||||
_lastUpdateFailure = DateTimeOffset.Now;
|
||||
}
|
||||
finally
|
||||
|
||||
10
README.md
10
README.md
@ -26,8 +26,14 @@ mkdir -p /var/www/remotely
|
||||
docker run -d --name remotely --restart unless-stopped -p 5000:5000 -v /var/www/remotely:/remotely-data immybot/remotely:latest
|
||||
```
|
||||
|
||||
## HTTPS Configuration
|
||||
When using HTTPS with a reverse proxy (e.g. Caddy or Nginx), be sure to set `RedirectToHttps` to `true` (which is the default) in `appsettings.json`. This is needed for the server to set the correct scheme when embedding the server URL in the clients. The scheme is supposed to be updated by the ForwardedHeaders feature, but it doesn't appear to be working in some scenarios.
|
||||
## Important: HTTPS and Reverse Proxies
|
||||
When using a reverse proxy, Remotely uses forwarded headers to determine the scheme (http/https) and host (server URL) to embed in the installers and remote control files when they are downloaded. To avoid injection attacks, ASP.NET Core defaults to only accepting forwarded headers from loopback addresses.
|
||||
|
||||
Remotely will also add the default Docker host IP (172.17.0.1).
|
||||
|
||||
**If you are using a non-default configuration, you must add the reverse proxy address to the `KnownProxies` array in appsettings.json.**
|
||||
|
||||
Remotely will not work if it receives forwarded requests from addresses that aren't in that list.
|
||||
|
||||
## After Installation
|
||||
- Data for Remotely will be saved in `/var/www/remotely/` within two files: appsettings.json and Remotely.db.
|
||||
|
||||
@ -72,8 +72,8 @@ EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docker", "Docker", "{963B5555-30AE-428E-9686-59C4B6FEC052}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.docker\Dockerfile = .docker\Dockerfile
|
||||
.docker\Dockerfile-old = .docker\Dockerfile-old
|
||||
.docker\Dockerfile-rootless = .docker\Dockerfile-rootless
|
||||
.docker\Dockerfile.old = .docker\Dockerfile.old
|
||||
.docker\Dockerfile.rootless = .docker\Dockerfile.rootless
|
||||
.docker\DockerMain.sh = .docker\DockerMain.sh
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
||||
@ -3,6 +3,8 @@ using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Remotely.Server.Auth;
|
||||
using Remotely.Server.Services;
|
||||
using Remotely.Shared;
|
||||
@ -23,22 +25,18 @@ namespace Remotely.Server.API
|
||||
[ApiController]
|
||||
public class ClientDownloadsController : ControllerBase
|
||||
{
|
||||
private readonly IApplicationConfig _appConfig;
|
||||
private readonly IEmbeddedServerDataSearcher _embeddedDataSearcher;
|
||||
private readonly SemaphoreSlim _fileLock = new(1,1);
|
||||
private readonly IWebHostEnvironment _hostEnv;
|
||||
|
||||
public ClientDownloadsController(
|
||||
IWebHostEnvironment hostEnv,
|
||||
IApplicationConfig appConfig,
|
||||
IEmbeddedServerDataSearcher embeddedDataSearcher)
|
||||
{
|
||||
_hostEnv = hostEnv;
|
||||
_appConfig = appConfig;
|
||||
_embeddedDataSearcher = embeddedDataSearcher;
|
||||
}
|
||||
|
||||
private string EffectiveScheme => _appConfig.RedirectToHttps ? "https" : Request.Scheme;
|
||||
|
||||
[HttpGet("desktop/{platformID}")]
|
||||
public async Task<IActionResult> GetDesktop(string platformID)
|
||||
{
|
||||
@ -132,7 +130,7 @@ namespace Remotely.Server.API
|
||||
var hostIndex = fileContents.IndexOf("HostName=");
|
||||
var orgIndex = fileContents.IndexOf("Organization=");
|
||||
|
||||
fileContents[hostIndex] = $"HostName=\"{EffectiveScheme}://{Request.Host}\"";
|
||||
fileContents[hostIndex] = $"HostName=\"{Request.Scheme}://{Request.Host}\"";
|
||||
fileContents[orgIndex] = $"Organization=\"{organizationId}\"";
|
||||
var fileBytes = Encoding.UTF8.GetBytes(string.Join("\n", fileContents));
|
||||
return File(fileBytes, "application/octet-stream", fileName);
|
||||
@ -140,7 +138,7 @@ namespace Remotely.Server.API
|
||||
|
||||
private async Task<IActionResult> GetDesktopFile(string filePath, string organizationId = null)
|
||||
{
|
||||
var serverUrl = $"{EffectiveScheme}://{Request.Host}";
|
||||
var serverUrl = $"{Request.Scheme}://{Request.Host}";
|
||||
var embeddedData = new EmbeddedServerData(new Uri(serverUrl), organizationId);
|
||||
var result = await _embeddedDataSearcher.GetRewrittenStream(filePath, embeddedData);
|
||||
|
||||
@ -163,7 +161,7 @@ namespace Remotely.Server.API
|
||||
case "WindowsInstaller":
|
||||
{
|
||||
var filePath = Path.Combine(_hostEnv.WebRootPath, "Content", "Remotely_Installer.exe");
|
||||
var serverUrl = $"{EffectiveScheme}://{Request.Host}";
|
||||
var serverUrl = $"{Request.Scheme}://{Request.Host}";
|
||||
var embeddedData = new EmbeddedServerData(new Uri(serverUrl), organizationId);
|
||||
var result = await _embeddedDataSearcher.GetRewrittenStream(filePath, embeddedData);
|
||||
|
||||
|
||||
@ -131,6 +131,9 @@ services.Configure<ForwardedHeadersOptions>(options =>
|
||||
options.ForwardedHeaders = ForwardedHeaders.All;
|
||||
options.ForwardLimit = null;
|
||||
|
||||
// Default Docker host. We want to allow forwarded headers from this address.
|
||||
options.KnownProxies.Add(IPAddress.Parse("172.17.0.1"));
|
||||
|
||||
if (knownProxies?.Any() == true)
|
||||
{
|
||||
foreach (var proxy in knownProxies)
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Remotely.Shared.Extensions;
|
||||
using Remotely.Shared.Utilities;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -19,6 +21,7 @@ namespace Remotely.Shared.Services
|
||||
private readonly string _applicationName;
|
||||
private readonly string _categoryName;
|
||||
private readonly System.Timers.Timer _sinkTimer = new(5000) { AutoReset = false };
|
||||
|
||||
public FileLogger(string applicationName, string categoryName)
|
||||
{
|
||||
_applicationName = applicationName?.SanitizeFileName() ?? string.Empty;
|
||||
@ -74,22 +77,12 @@ namespace Remotely.Shared.Services
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
switch (logLevel)
|
||||
return logLevel switch
|
||||
{
|
||||
#if DEBUG
|
||||
case LogLevel.Trace:
|
||||
case LogLevel.Debug:
|
||||
return true;
|
||||
#endif
|
||||
case LogLevel.Information:
|
||||
case LogLevel.Warning:
|
||||
case LogLevel.Error:
|
||||
case LogLevel.Critical:
|
||||
return true;
|
||||
case LogLevel.None:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
LogLevel.Trace or LogLevel.Debug => EnvironmentHelper.IsDebug,
|
||||
LogLevel.Information or LogLevel.Warning or LogLevel.Error or LogLevel.Critical => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
@ -106,7 +99,7 @@ namespace Remotely.Shared.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error queueing log entry: {ex.Message}");
|
||||
Debug.WriteLine($"Error queueing log entry: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,10 +126,38 @@ namespace Remotely.Shared.Services
|
||||
|
||||
private void CheckLogFileExists()
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(LogPath)!);
|
||||
_ = Directory.CreateDirectory(Path.GetDirectoryName(LogPath)!);
|
||||
|
||||
if (!File.Exists(LogPath))
|
||||
{
|
||||
File.Create(LogPath).Close();
|
||||
|
||||
try
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
Process.Start("cmd", $"/c icacls \"{LogPath}\" /grant Users:M").WaitForExit(1_000);
|
||||
}
|
||||
else if (OperatingSystem.IsLinux())
|
||||
{
|
||||
Process.Start("sudo", $"chmod 775 {LogPath}").WaitForExit(1_000);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"Error modifying log file permissions: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(LogPath))
|
||||
{
|
||||
var fi = new FileInfo(LogPath);
|
||||
while (fi.Length > 1_000_000)
|
||||
{
|
||||
var content = File.ReadAllLines(LogPath);
|
||||
File.WriteAllLines(LogPath, content.Skip(10));
|
||||
fi = new FileInfo(LogPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,7 +216,7 @@ namespace Remotely.Shared.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error writing log entry: {ex.Message}");
|
||||
Debug.WriteLine($"Error writing log entry: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Remotely.Shared.Utilities;
|
||||
|
||||
namespace Remotely.Shared.Services
|
||||
@ -11,6 +12,13 @@ namespace Remotely.Shared.Services
|
||||
|
||||
public class ProcessInvoker : IProcessInvoker
|
||||
{
|
||||
private readonly ILogger<ProcessInvoker> _logger;
|
||||
|
||||
public ProcessInvoker(ILogger<ProcessInvoker> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public string InvokeProcessOutput(string command, string arguments)
|
||||
{
|
||||
try
|
||||
@ -30,7 +38,7 @@ namespace Remotely.Shared.Services
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Write(ex, "Failed to start process.");
|
||||
_logger.LogError(ex, "Failed to start process.");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Remotely.Shared.Enums;
|
||||
using Remotely.Shared.Services;
|
||||
using Remotely.Shared.Utilities;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
@ -154,7 +155,7 @@ namespace Remotely.Shared.Utilities
|
||||
File.Create(LogPath).Close();
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
Process.Start("sudo", $"chmod 777 {LogPath}").WaitForExit();
|
||||
Process.Start("sudo", $"chmod 775 {LogPath}").WaitForExit();
|
||||
}
|
||||
}
|
||||
if (File.Exists(LogPath))
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit b7d9377237fcb1d60060ad8d3470815920975df0
|
||||
Subproject commit a2b9a545671c05ad156404ca82879c9de0f0c0f8
|
||||
Loading…
Reference in New Issue
Block a user