From 5dacb65e1aca30e665d18241a87fc83b05e0f067 Mon Sep 17 00:00:00 2001 From: crschnick Date: Fri, 19 Apr 2024 01:34:49 +0000 Subject: [PATCH] Fixes --- .../app/comp/store/StoreEntryWrapper.java | 5 ++- .../main/java/io/xpipe/app/core/AppI18n.java | 4 +++ .../io/xpipe/app/storage/DataStoreEntry.java | 15 ++++---- .../io/xpipe/app/util/WindowsRegistry.java | 34 +++++++++++++++--- lang/proc/strings/translations_en.properties | 4 +++ lang/proc/texts/rdpFileAllowListCheck_en.md | 36 +++++++++++++++++++ lang/proc/texts/rdpFileAllowList_en.md | 26 ++++++++------ 7 files changed, 101 insertions(+), 23 deletions(-) create mode 100644 lang/proc/texts/rdpFileAllowListCheck_en.md diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java index 8887d55a..254d41a6 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryWrapper.java @@ -115,7 +115,10 @@ public class StoreEntryWrapper { expanded.setValue(entry.isExpanded()); persistentState.setValue(entry.getStorePersistentState()); // Use map copy to recognize update - cache.setValue(new HashMap<>(entry.getStoreCache())); + // This is a synchronized map, so we synchronize the access + synchronized (entry.getStoreCache()) { + cache.setValue(new HashMap<>(entry.getStoreCache())); + } color.setValue(entry.getColor()); busy.setValue(entry.isInRefresh()); diff --git a/app/src/main/java/io/xpipe/app/core/AppI18n.java b/app/src/main/java/io/xpipe/app/core/AppI18n.java index e6c1b66c..2d3f634b 100644 --- a/app/src/main/java/io/xpipe/app/core/AppI18n.java +++ b/app/src/main/java/io/xpipe/app/core/AppI18n.java @@ -90,6 +90,10 @@ public class AppI18n { private static String getCallerModuleName() { var callers = CallingClass.INSTANCE.getCallingClasses(); for (Class caller : callers) { + if (caller.isSynthetic()) { + continue; + } + if (caller.equals(CallingClass.class) || caller.equals(ModuleHelper.class) || caller.equals(ModalOverlayComp.class) diff --git a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java index acdc7263..a30e4020 100644 --- a/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java +++ b/app/src/main/java/io/xpipe/app/storage/DataStoreEntry.java @@ -1,18 +1,17 @@ package io.xpipe.app.storage; -import io.xpipe.app.ext.DataStoreProvider; -import io.xpipe.app.ext.DataStoreProviders; -import io.xpipe.app.issue.ErrorEvent; -import io.xpipe.app.util.FixedHierarchyStore; -import io.xpipe.core.store.*; -import io.xpipe.core.util.JacksonMapper; - import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; +import io.xpipe.app.ext.DataStoreProvider; +import io.xpipe.app.ext.DataStoreProviders; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.app.util.FixedHierarchyStore; +import io.xpipe.core.store.*; +import io.xpipe.core.util.JacksonMapper; import lombok.*; import lombok.experimental.NonFinal; import org.apache.commons.io.FileUtils; @@ -26,7 +25,7 @@ import java.util.stream.Collectors; @Value public class DataStoreEntry extends StorageElement { - Map storeCache = new LinkedHashMap<>(); + Map storeCache = Collections.synchronizedMap(new HashMap<>()); @NonFinal Validity validity; diff --git a/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java b/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java index 5afb1316..99601582 100644 --- a/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java +++ b/app/src/main/java/io/xpipe/app/util/WindowsRegistry.java @@ -1,11 +1,10 @@ package io.xpipe.app.util; -import io.xpipe.app.issue.ErrorEvent; -import io.xpipe.core.process.CommandBuilder; -import io.xpipe.core.process.ShellControl; - import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.WinReg; +import io.xpipe.app.issue.ErrorEvent; +import io.xpipe.core.process.CommandBuilder; +import io.xpipe.core.process.ShellControl; import java.util.Optional; @@ -47,6 +46,33 @@ public class WindowsRegistry { } } + public static boolean remoteKeyExists(ShellControl shellControl, int hkey, String key) throws Exception { + var command = CommandBuilder.of() + .add("reg", "query") + .addQuoted((hkey == HKEY_LOCAL_MACHINE ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER") + "\\" + key) + .add("/ve"); + try (var c = shellControl.command(command).start()) { + return c.discardAndCheckExit(); + } + } + + public static Optional findRemoteValuesRecursive(ShellControl shellControl, int hkey, String key, String valueName) throws Exception { + var command = CommandBuilder.of() + .add("reg", "query") + .addQuoted((hkey == HKEY_LOCAL_MACHINE ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER") + "\\" + key) + .add("/v") + .addQuoted(valueName) + .add("/s"); + try (var c = shellControl.command(command).start()) { + var output = c.readStdoutDiscardErr(); + if (c.getExitCode() != 0) { + return Optional.empty(); + } else { + return Optional.of(output); + } + } + } + public static Optional readRemoteString(ShellControl shellControl, int hkey, String key, String valueName) throws Exception { var command = CommandBuilder.of() diff --git a/lang/proc/strings/translations_en.properties b/lang/proc/strings/translations_en.properties index 89f5a77d..59badaae 100644 --- a/lang/proc/strings/translations_en.properties +++ b/lang/proc/strings/translations_en.properties @@ -303,4 +303,8 @@ rdpTunnel.displayName=RDP connection over SSH rdpTunnel.displayDescription=Connect via RDP over a tunneled SSH connection rdpEnableDesktopIntegration=Enable desktop integration rdpEnableDesktopIntegrationDescription=Run remote applications assuming that the RDP allow list permits that +rdpSetupAdminTitle=RDP setup required +rdpSetupAllowTitle=RDP remote application +rdpSetupAllowHeader=Starting remote applications directly is currently not allowed on this system. Do you want to enable it? +rdpSetupAllowContent=This will allow you to run your remote applications directly from XPipe by disabling the allow list for RDP remote applications. diff --git a/lang/proc/texts/rdpFileAllowListCheck_en.md b/lang/proc/texts/rdpFileAllowListCheck_en.md new file mode 100644 index 00000000..af1e7eec --- /dev/null +++ b/lang/proc/texts/rdpFileAllowListCheck_en.md @@ -0,0 +1,36 @@ +# RDP remote applications + +You can use RDP connections in XPipe to quickly launch remote applications and scripts without opening a full desktop. However, due to the nature of RDP, you have to edit the remote application allow list on your server for this to work. + +## RDP allow lists + +An RDP server uses the concept of allow lists to handle application launches. This essentially means that unless the allow list is disabled or specific applications have been explicitly added the allow list, launching any remote applications directly will fail. + +You can find the allow list settings in the registry of your server at `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList`. + +### Allowing all applications + +You can disable the allow list to allow all remote applications to be started directly from XPipe. For this, you can run the following command on your server in PowerShell: `Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList' -Name "fDisabledAllowList" -Value 1`. + +### Adding allowed applications + +Alternatively, you can also add individual remote applications to the list. This will then allow you to launch the listed applications directly from XPipe. + +Under the `Applications` key of `TSAppAllowList`, create a new key with some arbitrary name. The only requirement for the name is that it is unique within the children of the “Applications” key. This new key, must have these values in it: `Name`, `Path` and `CommandLineSetting`. You can do this in PowerShell with the following commands: + +``` +$appName="Notepad" +$appPath="C:\Windows\System32\notepad.exe" + +$regKey="HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList\Applications" +New-item -Path "$regKey\$appName" +New-ItemProperty -Path "$regKey\$appName" -Name "Name" -Value "$appName" -Force +New-ItemProperty -Path "$regKey\$appName" -Name "Path" -Value "$appPath" -Force +New-ItemProperty -Path "$regKey\$appName" -Name "CommandLineSetting" -Value "1" -PropertyType DWord -Force +``` + +If you want to allow XPipe to also run scripts and open terminal sessions, you have to add `C:\Windows\System32\cmd.exe` to the allow list as well. + +## Security considerations + +This does not make your server insecure in any way, as you can always run the same applications manually when launching an RDP connection. Allow lists are more intended to prevent clients from instantly running any application without user input. At the end of the day, it is up to you whether you trust XPipe to do this. You can launch this connection just fine out of the box, this is only useful if you want to use any of the advanced desktop integration features in XPipe. diff --git a/lang/proc/texts/rdpFileAllowList_en.md b/lang/proc/texts/rdpFileAllowList_en.md index 350371cf..62798637 100644 --- a/lang/proc/texts/rdpFileAllowList_en.md +++ b/lang/proc/texts/rdpFileAllowList_en.md @@ -1,32 +1,38 @@ -## RDP desktop integration +# RDP desktop integration You can use this RDP connection in XPipe to quickly launch applications and scripts. However, due to the nature of RDP, you have to edit the remote application allow list on your server for this to work. Furthermore, this option enables drive sharing to execute your scripts on your remote server. You can also choose not to do this and just use XPipe to launch your RDP client without using any advanced desktop integration features. -### RDP allow lists +## RDP allow lists An RDP server uses the concept of allow lists to handle application launches. This essentially means that unless the allow list is disabled or specific applications have been explicitly added the allow list, launching any remote applications directly will fail. You can find the allow list settings in the registry of your server at `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList`. -#### Disabling the allow list +### Allowing all applications -You can disable the allow list concept to allow all remote applications to be started directly from XPipe. For this, you can run the following command on your server: `Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList' -Name "fDisabledAllowList" -Value 1`. +You can disable the allow list to allow all remote applications to be started directly from XPipe. For this, you can run the following command on your server in PowerShell: `Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList' -Name "fDisabledAllowList" -Value 1`. -#### Adding allowed applications +### Adding allowed applications Alternatively, you can also add individual remote applications to the list. This will then allow you to launch the listed applications directly from XPipe. -Under the `Applications` key of `TSAppAllowList`, create a new key with some arbitrary name. The only requirement for the name is that it is unique within the children of the “Applications” key. This new key, must have two string values in it: `Name` and `Path`. `Name` is the name by which we will refer to the application later when configuring the client, and `Path` is the path to the application on the server. You can do this in PowerShell with the following commands: +Under the `Applications` key of `TSAppAllowList`, create a new key with some arbitrary name. The only requirement for the name is that it is unique within the children of the “Applications” key. This new key, must have these values in it: `Name`, `Path` and `CommandLineSetting`. You can do this in PowerShell with the following commands: ``` -Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList\Applications\' -Name "Name" -Value "" -Force -Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList\Applications\' -Name "Path" -Value "" -Force +$appName="Notepad" +$appPath="C:\Windows\System32\notepad.exe" + +$regKey="HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Terminal Server\TSAppAllowList\Applications" +New-item -Path "$regKey\$appName" +New-ItemProperty -Path "$regKey\$appName" -Name "Name" -Value "$appName" -Force +New-ItemProperty -Path "$regKey\$appName" -Name "Path" -Value "$appPath" -Force +New-ItemProperty -Path "$regKey\$appName" -Name "CommandLineSetting" -Value "1" -PropertyType DWord -Force ``` -If you want to allow XPipe to also run scripts and open terminal sessions, you have to add `cmd.exe` to the allow list as well. +If you want to allow XPipe to also run scripts and open terminal sessions, you have to add `C:\Windows\System32\cmd.exe` to the allow list as well. -### Security considerations +## Security considerations This does not make your server insecure in any way, as you can always run the same applications manually when launching an RDP connection. Allow lists are more intended to prevent clients from instantly running any application without user input. At the end of the day, it is up to you whether you trust XPipe to do this. You can launch this connection just fine out of the box, this is only useful if you want to use any of the advanced desktop integration features in XPipe.