diff --git a/Agent/Program.cs b/Agent/Program.cs
index af954741b..82b8800b2 100644
--- a/Agent/Program.cs
+++ b/Agent/Program.cs
@@ -123,6 +123,7 @@ private static void RegisterServices(IServiceCollection services)
services.AddSingleton();
services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
}
else
{
diff --git a/Agent/Services/MacOS/AppLauncherMac.cs b/Agent/Services/MacOS/AppLauncherMac.cs
index 238ba8615..e5d1a9284 100644
--- a/Agent/Services/MacOS/AppLauncherMac.cs
+++ b/Agent/Services/MacOS/AppLauncherMac.cs
@@ -10,17 +10,17 @@ public class AppLauncherMac : IAppLauncher
public async Task LaunchChatService(string pipeName, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection)
{
- await hubConnection.SendAsync("DisplayMessage", "Feature under development.", "Feature is under development.", "bg-warning", userConnectionId);
+ await hubConnection.SendAsync("DisplayMessage", "Feature under development.", "Currently unsupported", "bg-warning", userConnectionId);
return 0;
}
public async Task LaunchRemoteControl(int targetSessionId, string sessionId, string accessKey, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection)
{
- await hubConnection.SendAsync("DisplayMessage", "Feature under development.", "Feature is under development.", "bg-warning", userConnectionId);
+ await hubConnection.SendAsync("DisplayMessage", "Feature under development.", "Currently unsupported", "bg-warning", userConnectionId);
}
public async Task RestartScreenCaster(string[] viewerIds, string sessionId, string accessKey, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection, int targetSessionID = -1)
{
- await hubConnection.SendAsync("DisplayMessage", "Feature under development.", "Feature is under development.", "bg-warning", userConnectionId);
+ await hubConnection.SendAsync("DisplayMessage", "Feature under development.", "Currently unsupported", "bg-warning", userConnectionId);
}
}
diff --git a/Agent/Services/Windows/UpdaterWin.cs b/Agent/Services/Windows/UpdaterWin.cs
index cef171519..3d76bec47 100644
--- a/Agent/Services/Windows/UpdaterWin.cs
+++ b/Agent/Services/Windows/UpdaterWin.cs
@@ -130,25 +130,23 @@ public async Task InstallLatestVersion()
var zipPath = Path.Combine(Path.GetTempPath(), "RemotelyUpdate.zip");
- var installerPath = Path.Combine(Path.GetTempPath(), "Remotely_Installer.exe");
+ var installerPath = Path.Combine(Path.GetTempPath(), "Install-Remotely.ps1");
var platform = Environment.Is64BitOperatingSystem ? "x64" : "x86";
await _updateDownloader.DownloadFile(
- $"{serverUrl}/Content/Remotely_Installer.exe",
+ $"{serverUrl}/Content/Install-Remotely.ps1",
installerPath);
await _updateDownloader.DownloadFile(
$"{serverUrl}/api/AgentUpdate/DownloadPackage/win-{platform}",
zipPath);
- foreach (var proc in Process.GetProcessesByName("Remotely_Installer"))
- {
- proc.Kill();
- }
-
_logger.LogInformation("Launching installer to perform update.");
- Process.Start(installerPath, $"-install -quiet -path {zipPath} -serverurl {serverUrl} -organizationid {connectionInfo.OrganizationID}");
+ Process.Start(
+ "powershell.exe",
+ $"-ExecutionPolicy Bypass -File \"{installerPath}\" -Path \"{zipPath}\" " +
+ $"-OrganizationId {connectionInfo.OrganizationID} -ServerUrl {connectionInfo.Host}");
}
catch (WebException ex) when (ex.Status == WebExceptionStatus.Timeout)
{
diff --git a/Server/API/ClientDownloadsController.cs b/Server/API/ClientDownloadsController.cs
index 1967a4854..65d1a2e35 100644
--- a/Server/API/ClientDownloadsController.cs
+++ b/Server/API/ClientDownloadsController.cs
@@ -200,8 +200,8 @@ private async Task GetInstallFile(string organizationId, string p
return NotFound();
}
- fileContents[hostIndex] = $"$HostName = \"{effectiveScheme}://{Request.Host}\"";
- fileContents[orgIndex] = $"$Organization = \"{organizationId}\"";
+ fileContents[hostIndex] = $"[string]$HostName = \"{effectiveScheme}://{Request.Host}\"";
+ fileContents[orgIndex] = $"[string]$Organization = \"{organizationId}\"";
var fileBytes = Encoding.UTF8.GetBytes(string.Join("\n", fileContents));
return File(fileBytes, "application/octet-stream", "Install-Remotely.ps1");
diff --git a/Server/Components/Pages/Downloads.razor b/Server/Components/Pages/Downloads.razor
index 9463481df..7b9678efb 100644
--- a/Server/Components/Pages/Downloads.razor
+++ b/Server/Components/Pages/Downloads.razor
@@ -146,13 +146,6 @@
macOS x64 Files Only
- @*macOS arm64 (11.01)
-
- macOS arm64 Bash Installer
-
- macOS arm64 Files Only
-
*@
-
Example Install:
@@ -169,6 +162,31 @@
sudo [path]/Install-MacOS-x64.sh --uninstall
+
+
+
macOS arm64
+
+ macOS arm64 Bash Installer
+
+ macOS arm64 Files Only
+
+
+
+
Example Install:
+
+
sudo [path]/Install-MacOS-arm64.sh
+
+
+
Example Local Install:
+
+
sudo [path]/Install-MacOS-arm64.sh --path [path]/Remotely-MacOS-arm64.zip
+
+
+
Example Uninstall:
+
+
sudo [path]/Install-MacOS-arm64.sh --uninstall
+
+
}
diff --git a/Server/Options/ApplicationOptions.cs b/Server/Options/ApplicationOptions.cs
index 1a11cc3b8..ed5d39a3f 100644
--- a/Server/Options/ApplicationOptions.cs
+++ b/Server/Options/ApplicationOptions.cs
@@ -4,4 +4,5 @@ public class ApplicationOptions
{
public const string SectionKey = "ApplicationOptions";
public string DbProvider { get; set; } = "SQLite";
+ public string? DockerGatewayIp { get; set; }
}
diff --git a/Server/Program.cs b/Server/Program.cs
index da91809d4..b75498453 100644
--- a/Server/Program.cs
+++ b/Server/Program.cs
@@ -36,6 +36,10 @@
services.Configure(
configuration.GetSection(ApplicationOptions.SectionKey));
+var appOptions = configuration
+ .GetSection(ApplicationOptions.SectionKey)
+ .Get();
+
services
.AddRazorComponents()
.AddInteractiveServerComponents();
@@ -47,7 +51,7 @@
services.AddScoped();
services.AddScoped();
-var dbProvider = configuration["ApplicationOptions:DbProvider"]?.ToLower();
+var dbProvider = appOptions?.DbProvider?.ToLower();
switch (dbProvider)
{
@@ -168,7 +172,10 @@
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 (IPAddress.TryParse(appOptions?.DockerGatewayIp, out var dockerGatewayIp))
+ {
+ options.KnownProxies.Add(dockerGatewayIp);
+ }
if (settings.KnownProxies is { Count: >0 } knownProxies)
{
@@ -257,6 +264,8 @@
var app = builder.Build();
+app.UseForwardedHeaders();
+
app.UseRateLimiter();
if (settings.UseHttpLogging)
@@ -264,8 +273,6 @@
app.UseHttpLogging();
}
-app.UseForwardedHeaders();
-
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
diff --git a/Server/Server.csproj b/Server/Server.csproj
index 76f3c56b3..f5d1e7111 100644
--- a/Server/Server.csproj
+++ b/Server/Server.csproj
@@ -29,6 +29,7 @@
+
diff --git a/Server/appsettings.json b/Server/appsettings.json
index b752a55aa..d5a5d8632 100644
--- a/Server/appsettings.json
+++ b/Server/appsettings.json
@@ -20,6 +20,7 @@
}
},
"ApplicationOptions": {
- "DbProvider": "SQLite"
+ "DbProvider": "SQLite",
+ "DockerGatewayIp": "172.28.0.1"
}
}
diff --git a/Server/wwwroot/Content/Install-MacOS-arm64.sh b/Server/wwwroot/Content/Install-MacOS-arm64.sh
index a58534187..43547654c 100644
--- a/Server/wwwroot/Content/Install-MacOS-arm64.sh
+++ b/Server/wwwroot/Content/Install-MacOS-arm64.sh
@@ -16,7 +16,7 @@ ArgLength=${#Args[@]}
for (( i=0; i<${ArgLength}; i+=2 ));
do
if [ "${Args[$i]}" = "--uninstall" ]; then
- launchctl unload -w /Library/LaunchDaemons/remotely-agent.plist
+ sudo launchctl bootout system /Library/LaunchDaemons/remotely-agent.plist
rm -r -f $InstallDir/
rm -f /Library/LaunchDaemons/remotely-agent.plist
exit
@@ -41,9 +41,6 @@ Owner=$(ls -l /usr/local/bin/brew | awk '{print $3}')
su - $Owner -c "brew update"
-# Install .NET Runtime
-su - $Owner -c "brew install --cask dotnet"
-
# Install other dependencies
su - $Owner -c "brew install curl"
su - $Owner -c "brew install jq"
@@ -71,9 +68,10 @@ else
rm -f "$UpdatePackagePath"
fi
-unzip -o $InstallDir/Remotely-MacOS-arm64.zip
+unzip -o $InstallDir/Remotely-MacOS-arm64.zip -d $InstallDir
rm -f $InstallDir/Remotely-MacOS-arm64.zip
-
+chmod +x $InstallDir/Remotely_Agent
+chmod +x $InstallDir/Desktop/Remotely_Desktop
connectionInfo="{
\"DeviceID\":\"$GUID\",
@@ -95,8 +93,7 @@ plistFile="
com.translucency.remotely-agent
ProgramArguments
- /usr/local/bin/dotnet
- $InstallDir/Remotely_Agent.dll
+ $InstallDir/Remotely_Agent
KeepAlive
@@ -104,5 +101,6 @@ plistFile="
"
echo "$plistFile" > "/Library/LaunchDaemons/remotely-agent.plist"
-launchctl load -w /Library/LaunchDaemons/remotely-agent.plist
-launchctl kickstart -k system/com.translucency.remotely-agent
\ No newline at end of file
+
+sudo launchctl bootstrap system /Library/LaunchDaemons/remotely-agent.plist
+sudo launchctl kickstart -k system/com.translucency.remotely-agent
\ No newline at end of file
diff --git a/Server/wwwroot/Content/Install-MacOS-x64.sh b/Server/wwwroot/Content/Install-MacOS-x64.sh
index 74794cd9f..56c6c2ec9 100644
--- a/Server/wwwroot/Content/Install-MacOS-x64.sh
+++ b/Server/wwwroot/Content/Install-MacOS-x64.sh
@@ -16,7 +16,7 @@ ArgLength=${#Args[@]}
for (( i=0; i<${ArgLength}; i+=2 ));
do
if [ "${Args[$i]}" = "--uninstall" ]; then
- launchctl unload -w /Library/LaunchDaemons/remotely-agent.plist
+ sudo launchctl bootout system /Library/LaunchDaemons/remotely-agent.plist
rm -r -f $InstallDir/
rm -f /Library/LaunchDaemons/remotely-agent.plist
exit
@@ -41,9 +41,6 @@ Owner=$(ls -l /usr/local/bin/brew | awk '{print $3}')
su - $Owner -c "brew update"
-# Install .NET Runtime
-su - $Owner -c "brew install --cask dotnet"
-
# Install other dependencies
su - $Owner -c "brew install curl"
su - $Owner -c "brew install jq"
@@ -71,9 +68,10 @@ else
rm -f "$UpdatePackagePath"
fi
-unzip -o $InstallDir/Remotely-MacOS-x64.zip
+unzip -o $InstallDir/Remotely-MacOS-x64.zip -d $InstallDir
rm -f $InstallDir/Remotely-MacOS-x64.zip
-
+chmod +x $InstallDir/Remotely_Agent
+chmod +x $InstallDir/Desktop/Remotely_Desktop
connectionInfo="{
\"DeviceID\":\"$GUID\",
@@ -95,8 +93,7 @@ plistFile="
com.translucency.remotely-agent
ProgramArguments
- /usr/local/bin/dotnet
- $InstallDir/Remotely_Agent.dll
+ $InstallDir/Remotely_Agent
KeepAlive
@@ -104,5 +101,5 @@ plistFile="
"
echo "$plistFile" > "/Library/LaunchDaemons/remotely-agent.plist"
-launchctl load -w /Library/LaunchDaemons/remotely-agent.plist
-launchctl kickstart -k system/com.translucency.remotely-agent
\ No newline at end of file
+sudo launchctl bootstrap system /Library/LaunchDaemons/remotely-agent.plist
+sudo launchctl kickstart -k system/com.translucency.remotely-agent
\ No newline at end of file
diff --git a/Server/wwwroot/Content/Install-Remotely.ps1 b/Server/wwwroot/Content/Install-Remotely.ps1
index 078ea2641..150fe9c7a 100644
--- a/Server/wwwroot/Content/Install-Remotely.ps1
+++ b/Server/wwwroot/Content/Install-Remotely.ps1
@@ -12,13 +12,24 @@ param (
[string]$DeviceAlias,
[string]$DeviceGroup,
[string]$Path,
+ [string]$OrganizationId,
+ [string]$ServerUrl,
[switch]$Uninstall
)
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
$LogPath = "$env:TEMP\Remotely_Install.txt"
+
[string]$HostName = $null
+if ($ServerUrl) {
+ $HostName = $ServerUrl
+}
+
[string]$Organization = $null
+if ($OrganizationId) {
+ $Organization = $OrganizationId
+}
+
$ConnectionInfo = $null
if ([System.Environment]::Is64BitOperatingSystem){
@@ -47,17 +58,35 @@ function Is-Administrator() {
function Run-StartupChecks {
- if ($HostName -eq $null -or $Organization -eq $null) {
+ if (!$HostName -or !$Organization) {
Write-Log "Required parameters are missing. Please try downloading the installer again."
Do-Exit
}
- if ((Is-Administrator) -eq $false) {
+ if (!(Is-Administrator)) {
Write-Log -Message "Install script requires elevation. Attempting to self-elevate..."
Start-Sleep -Seconds 3
- $param = "-f `"$($MyInvocation.ScriptName)`""
- Start-Process -FilePath powershell.exe -ArgumentList "-DeviceAlias $DeviceAlias -DeviceGroup $DeviceGroup -Path $Path" -Verb RunAs
+ $Params = "-File `"$($MyInvocation.ScriptName)`"";
+ if ($OrganizationId) {
+ $Params += " -OrganizationId $OrganizationId"
+ }
+ if ($ServerUrl) {
+ $Params += " -ServerUrl $ServerUrl"
+ }
+ if ($DeviceAlias) {
+ $Params += " -DeviceAlias $DeviceAlias"
+ }
+ if ($DeviceGroup) {
+ $Params += " -DeviceGroup $DeviceGroup"
+ }
+ if ($Path) {
+ $Params += " -Path `"$Path`""
+ }
+ if ($Uninstall) {
+ $Params += " -Uninstall"
+ }
+ Start-Process -FilePath powershell.exe -ArgumentList $Params -Verb RunAs
exit
}
}
@@ -75,9 +104,15 @@ function Uninstall-Remotely {
}
function Install-Remotely {
+ $HeadResponse = Invoke-WebRequest -Uri "$HostName/Content/Remotely-Win-$Platform.zip" -Method Head -UseBasicParsing
+ $ETag = $HeadResponse.Headers["ETag"]
+ if (!$Etag) {
+ Write-Host "Failed to get ETag from server. Aborting install."
+ }
+
if ((Test-Path -Path "$InstallPath") -and (Test-Path -Path "$InstallPath\ConnectionInfo.json")) {
$ConnectionInfo = Get-Content -Path "$InstallPath\ConnectionInfo.json" | ConvertFrom-Json
- if ($ConnectionInfo -ne $null) {
+ if ($ConnectionInfo) {
$ConnectionInfo.Host = $HostName
$ConnectionInfo.OrganizationID = $Organization
$ConnectionInfo.ServerVerificationToken = ""
@@ -87,7 +122,7 @@ function Install-Remotely {
New-Item -ItemType Directory -Path "$InstallPath" -Force
}
- if ($ConnectionInfo -eq $null) {
+ if (!$ConnectionInfo) {
$ConnectionInfo = @{
DeviceID = (New-Guid).ToString();
Host = $HostName;
@@ -108,7 +143,7 @@ function Install-Remotely {
else {
$ProgressPreference = 'SilentlyContinue'
Write-Log "Downloading client..."
- Invoke-WebRequest -Uri "$HostName/Content/Remotely-Win-$Platform.zip" -OutFile "$env:TEMP\Remotely-Win-$Platform.zip"
+ Invoke-WebRequest -Uri "$HostName/Content/Remotely-Win-$Platform.zip" -OutFile "$env:TEMP\Remotely-Win-$Platform.zip" -UseBasicParsing
$ProgressPreference = 'Continue'
}
@@ -124,6 +159,8 @@ function Install-Remotely {
New-Item -ItemType File -Path "$InstallPath\ConnectionInfo.json" -Value (ConvertTo-Json -InputObject $ConnectionInfo) -Force
+ New-Item -ItemType File -Path "$InstallPath\etag.txt" -Value $ETag -Force
+
if ($DeviceAlias -or $DeviceGroup) {
$DeviceSetupOptions = @{
DeviceAlias = $DeviceAlias;
@@ -131,8 +168,9 @@ function Install-Remotely {
OrganizationID = $Organization;
DeviceID = $ConnectionInfo.DeviceID;
}
-
- Invoke-RestMethod -Method Post -ContentType "application/json" -Uri "$HostName/api/devices" -Body $DeviceSetupOptions -UseBasicParsing
+
+ $Body = $DeviceSetupOptions | ConvertTo-Json
+ Invoke-RestMethod -Method Post -ContentType "application/json" -Uri "$HostName/api/devices" -Body $Body
}
New-Service -Name "Remotely_Service" -BinaryPathName "$InstallPath\Remotely_Agent.exe" -DisplayName "Remotely Service" -StartupType Automatic -Description "Background service that maintains a connection to the Remotely server. The service is used for remote support and maintenance by this computer's administrators."
@@ -144,7 +182,6 @@ try {
Run-StartupChecks
Write-Log "Install/uninstall logs are being written to `"$LogPath`""
- Write-Log
if ($Uninstall) {
Write-Log "Uninstall started."
@@ -154,7 +191,6 @@ try {
}
else {
Write-Log "Install started."
- Write-Log
Install-Remotely
Write-Log "Install completed."
exit
diff --git a/Shared/Services/ElevationDetectorMac.cs b/Shared/Services/ElevationDetectorMac.cs
new file mode 100644
index 000000000..9408c5698
--- /dev/null
+++ b/Shared/Services/ElevationDetectorMac.cs
@@ -0,0 +1,14 @@
+using System.Runtime.InteropServices;
+
+namespace Remotely.Shared.Services;
+
+public class ElevationDetectorMac : IElevationDetector
+{
+ [DllImport("libc", SetLastError = true)]
+ private static extern uint geteuid();
+
+ public bool IsElevated()
+ {
+ return geteuid() == 0;
+ }
+}
diff --git a/Shared/Services/FileLoggerDefaults.cs b/Shared/Services/FileLoggerDefaults.cs
index f4d68d274..5cdbcf433 100644
--- a/Shared/Services/FileLoggerDefaults.cs
+++ b/Shared/Services/FileLoggerDefaults.cs
@@ -31,7 +31,7 @@ public static string LogsFolderPath
return logsPath;
}
- if (OperatingSystem.IsLinux())
+ if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
{
if (EnvironmentHelper.IsDebug)
{
diff --git a/docker-compose/docker-compose.yml b/docker-compose/docker-compose.yml
index 872c0771b..1eb4e5153 100644
--- a/docker-compose/docker-compose.yml
+++ b/docker-compose/docker-compose.yml
@@ -1,13 +1,25 @@
version: '3.4'
+networks:
+ remotely:
+ name: remotely-network
+ driver: bridge
+ ipam:
+ config:
+ - subnet: 172.28.0.0/16
+ gateway: 172.28.0.1
+
services:
remotely:
image: immybot/remotely:latest
+ container_name: remotely
volumes:
- /var/www/remotely:/app/AppData
restart: unless-stopped
ports:
- "5000:5000"
+ networks:
+ - remotely
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_HTTP_PORTS=5000
@@ -16,9 +28,14 @@ services:
# Values for DbProvider are SQLite, SQLServer, and PostgreSQL.
- Remotely_ApplicationOptions__DbProvider=SQLite
+ # The Docker gateway will be used in Forwarded Headers, which is necessary to
+ # to correctly determine request hostname and scheme within the app. If you change
+ # the network config, you must update this value as well.
+ - Remotely_ApplicationOptions__DockerGateway=172.28.0.1
# This path shouldn't be changed. It points to the Docker volume.
- Remotely_ConnectionStrings__SQLite=Data Source=/app/AppData/Remotely.db
# If using SQL Server, change the connection string to point to your SQL Server instance.
- Remotely_ConnectionStrings__SQLServer=Server=(localdb)\\mssqllocaldb;Database=Remotely-Server-53bc9b9d-9d6a-45d4-8429-2a2761773502;Trusted_Connection=True;MultipleActiveResultSets=true
# If using PostgreSQL, change the connection string to point to your PostgreSQL instance.
- - Remotely_ConnectionStrings__PostgreSQL=Server=Host=localhost;Database=Remotely;Username=postgres;
\ No newline at end of file
+ - Remotely_ConnectionStrings__PostgreSQL=Server=Host=localhost;Database=Remotely;Username=postgres;
+
\ No newline at end of file
diff --git a/submodules/Immense.RemoteControl b/submodules/Immense.RemoteControl
index 49384c61a..986742db0 160000
--- a/submodules/Immense.RemoteControl
+++ b/submodules/Immense.RemoteControl
@@ -1 +1 @@
-Subproject commit 49384c61a5b9f8bbd4fb42ae877e38e789904236
+Subproject commit 986742db0d9aa54ba35531b29519b2372e6423aa