mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-07-08 11:30:42 +00:00
RDP rework
This commit is contained in:
@@ -54,7 +54,7 @@ public class CustomRdpClient implements ExternalApplicationType, ExternalRdpClie
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing(RdpLaunchConfig config) {
|
||||
public boolean supportsPasswordPassing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public class DevolutionsRdpClient implements ExternalApplicationType.WindowsType
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing(RdpLaunchConfig config) {
|
||||
public boolean supportsPasswordPassing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public interface ExternalRdpClient extends PrefsValue {
|
||||
|
||||
void launch(RdpLaunchConfig configuration) throws Exception;
|
||||
|
||||
boolean supportsPasswordPassing(RdpLaunchConfig config);
|
||||
boolean supportsPasswordPassing();
|
||||
|
||||
String getWebsite();
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@ import lombok.Builder;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@JsonTypeName("freeRdp")
|
||||
@Value
|
||||
@Jacksonized
|
||||
@@ -33,7 +31,15 @@ public class FreeRdpClient implements ExternalRdpClient {
|
||||
var v3 = CommandSupport.isInLocalPath("xfreerdp3");
|
||||
if (!v3) {
|
||||
var v2 = CommandSupport.isInLocalPath("xfreerdp");
|
||||
if (!v2 && OsType.ofLocal() == OsType.LINUX) {
|
||||
|
||||
// macOS uses xfreerdp3 by default
|
||||
if (OsType.ofLocal() == OsType.MACOS && v2) {
|
||||
exec = CommandBuilder.of().add("xfreerdp");
|
||||
v3 = true;
|
||||
} else if (v2) {
|
||||
exec = CommandBuilder.of().add("xfreerdp");
|
||||
v3 = false;
|
||||
} else if (OsType.ofLocal() == OsType.LINUX) {
|
||||
var flatpak = FlatpakCache.getApp("com.freerdp.FreeRDP");
|
||||
if (flatpak.isPresent()) {
|
||||
exec = FlatpakCache.getRunCommand("com.freerdp.FreeRDP");
|
||||
@@ -42,10 +48,7 @@ public class FreeRdpClient implements ExternalRdpClient {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
CommandSupport.isInPathOrThrow(LocalShell.getShell(), "xfreerdp");
|
||||
exec = CommandBuilder.of().add("xfreerdp");
|
||||
// macOS uses xfreerdp3 by default
|
||||
v3 = true;
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
exec = CommandBuilder.of().add("xfreerdp3");
|
||||
@@ -55,13 +58,16 @@ public class FreeRdpClient implements ExternalRdpClient {
|
||||
|
||||
private Executable getWaylandCommandBase() throws Exception {
|
||||
CommandBuilder exec;
|
||||
var v3 = CommandSupport.isInLocalPath("wlfreerdp3");
|
||||
var v3 = CommandSupport.isInLocalPath("sdl-freerdp3") || CommandSupport.isInLocalPath("wlfreerdp3");
|
||||
if (!v3) {
|
||||
var v2 = CommandSupport.isInLocalPath("wlfreerdp");
|
||||
if (!v2 && OsType.ofLocal() == OsType.LINUX) {
|
||||
if (v2) {
|
||||
exec = CommandBuilder.of().add("wlfreerdp");
|
||||
v3 = false;
|
||||
} else if (OsType.ofLocal() == OsType.LINUX) {
|
||||
var flatpak = FlatpakCache.getApp("com.freerdp.FreeRDP");
|
||||
if (flatpak.isPresent()) {
|
||||
exec = FlatpakCache.getRunCommand("com.freerdp.FreeRDP", "sdl-freerdp");
|
||||
exec = FlatpakCache.getRunCommand("com.freerdp.FreeRDP", "sdl-freerdp3");
|
||||
v3 = true;
|
||||
} else {
|
||||
return null;
|
||||
@@ -71,7 +77,7 @@ public class FreeRdpClient implements ExternalRdpClient {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
exec = CommandBuilder.of().add("wlfreerdp3");
|
||||
exec = CommandSupport.isInLocalPath("sdl-freerdp3") ? CommandBuilder.of().add("sdl-freerdp3") : CommandBuilder.of().add("wlfreerdp3");
|
||||
}
|
||||
return new Executable(exec, v3);
|
||||
}
|
||||
@@ -85,7 +91,7 @@ public class FreeRdpClient implements ExternalRdpClient {
|
||||
}
|
||||
|
||||
if (exec == null) {
|
||||
throw ErrorEventFactory.expected(new IllegalStateException("Unable to find a FreeRDP v2 or v3 installation"));
|
||||
throw ErrorEventFactory.expected(new IllegalStateException("Unable to find a FreeRDP executable for v2 or v3 in the PATH or as a flatpak"));
|
||||
}
|
||||
|
||||
var file = writeRdpConfigFile(configuration.getTitle(), configuration.getConfig());
|
||||
@@ -100,6 +106,16 @@ public class FreeRdpClient implements ExternalRdpClient {
|
||||
.add("-themes")
|
||||
.add("/size:100%");
|
||||
|
||||
b.add(argument("/v", configuration.getHost()));
|
||||
|
||||
if (configuration.getUsername() != null) {
|
||||
b.add(argument("/u", configuration.getUsernameWithoutDomain()));
|
||||
}
|
||||
|
||||
if (configuration.getDomain().isPresent()) {
|
||||
b.add(argument("/d", configuration.getDomain().get()));
|
||||
}
|
||||
|
||||
if (configuration.getPassword() != null) {
|
||||
b.add(argument("/p", configuration.getPassword().getSecretValue()));
|
||||
}
|
||||
@@ -110,7 +126,10 @@ public class FreeRdpClient implements ExternalRdpClient {
|
||||
// Horrible quoting rules: https://github.com/FreeRDP/FreeRDP/issues/11396
|
||||
String s = "g:" + gateway.getHost();
|
||||
if (gateway.getUsername() != null) {
|
||||
s += "," + gatewayArgument("u", gateway.getUsername());
|
||||
s += "," + gatewayArgument("u", gateway.getUsernameWithoutDomain());
|
||||
}
|
||||
if (gateway.getDomain().isPresent()) {
|
||||
s += "," + gatewayArgument("d", gateway.getDomain().get());
|
||||
}
|
||||
if (gateway.getPassword() != null) {
|
||||
s += "," + gatewayArgument("p", gateway.getPassword().getSecretValue());
|
||||
@@ -146,7 +165,7 @@ public class FreeRdpClient implements ExternalRdpClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing(RdpLaunchConfig config) {
|
||||
public boolean supportsPasswordPassing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class KrdcRdpClient implements ExternalApplicationType.LinuxApplication,
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing(RdpLaunchConfig config) {
|
||||
public boolean supportsPasswordPassing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
package io.xpipe.app.rdp;
|
||||
|
||||
import com.sun.jna.LastErrorException;
|
||||
import com.sun.jna.Memory;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import io.xpipe.app.comp.base.ModalButton;
|
||||
import io.xpipe.app.comp.base.ModalOverlay;
|
||||
import io.xpipe.app.core.AppCache;
|
||||
import io.xpipe.app.core.AppDisplayScale;
|
||||
import io.xpipe.app.core.window.AppDialog;
|
||||
import io.xpipe.app.platform.ClipboardHelper;
|
||||
import io.xpipe.app.platform.OptionsBuilder;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.prefs.ExternalApplicationType;
|
||||
import io.xpipe.app.process.CommandBuilder;
|
||||
import io.xpipe.app.process.LocalShell;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.util.*;
|
||||
@@ -27,10 +21,7 @@ import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import lombok.Builder;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -231,7 +222,7 @@ public class MstscRdpClient implements ExternalApplicationType.PathApplication,
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing(RdpLaunchConfig config) {
|
||||
public boolean supportsPasswordPassing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.xpipe.app.util.SecretValue;
|
||||
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Value
|
||||
@@ -15,4 +16,18 @@ public class RdpLaunchConfigGateway {
|
||||
String username;
|
||||
SecretValue password;
|
||||
boolean reused;
|
||||
|
||||
public Optional<String> getDomain() {
|
||||
var domain = username.contains("\\") ? username.split("\\\\")[0] : null;
|
||||
return Optional.ofNullable(domain);
|
||||
}
|
||||
|
||||
public String getUsernameWithoutDomain() {
|
||||
if (username.contains("\\")) {
|
||||
return username.split("\\\\")[1];
|
||||
} else {
|
||||
return username;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@ import lombok.Builder;
|
||||
import lombok.Value;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@JsonTypeName("remmina")
|
||||
@Value
|
||||
@Jacksonized
|
||||
@@ -34,7 +32,7 @@ public class RemminaRdpClient implements ExternalApplicationType.LinuxApplicatio
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing(RdpLaunchConfig config) {
|
||||
public boolean supportsPasswordPassing() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class RemoteDesktopAppRdpClient implements ExternalApplicationType.MacApp
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing(RdpLaunchConfig config) {
|
||||
public boolean supportsPasswordPassing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public class WindowsAppRdpClient implements ExternalApplicationType.MacApplicati
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPasswordPassing(RdpLaunchConfig config) {
|
||||
public boolean supportsPasswordPassing() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import io.xpipe.app.vnc.VncLaunchConfig;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Optional;
|
||||
@@ -60,23 +61,17 @@ public class RemminaHelper {
|
||||
var name = OsFileSystem.ofLocal().makeFileSystemCompatible(configuration.getTitle());
|
||||
var file = AppLocalTemp.getLocalTempDataDirectory("remmina").resolve("xpipe-" + name + ".remmina");
|
||||
|
||||
var gateway = "";
|
||||
var gateway = new ArrayList<String>();
|
||||
if (configuration.getGateway() != null) {
|
||||
gateway += "gateway_server=" + configuration.getGateway().getHost();
|
||||
gateway.add("gateway_server=" + configuration.getGateway().getHost());
|
||||
if (configuration.getGateway().getUsername() != null) {
|
||||
var gatewayUser = configuration.getGateway().getUsername();
|
||||
var gatewayDomain = gatewayUser.contains("\\") ? gatewayUser.split("\\\\")[0] : null;
|
||||
if (gatewayDomain != null) {
|
||||
gatewayUser = gatewayUser.split("\\\\")[1];
|
||||
}
|
||||
|
||||
gateway += "gateway_username=" + gatewayUser;
|
||||
if (gatewayDomain != null) {
|
||||
gateway += "gateway_domain=" + gatewayDomain;
|
||||
gateway.add("gateway_username=" + configuration.getGateway().getUsernameWithoutDomain());
|
||||
if (configuration.getGateway().getDomain().isPresent()) {
|
||||
gateway.add("gateway_domain=" + configuration.getGateway().getDomain().get());
|
||||
}
|
||||
}
|
||||
if (configuration.getGateway().getPassword() != null) {
|
||||
gateway += "gateway_password=" + RemminaHelper.encryptPassword(configuration.getGateway().getPassword());
|
||||
gateway.add("gateway_password=" + RemminaHelper.encryptPassword(configuration.getGateway().getPassword()).orElse(""));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +97,7 @@ public class RemminaHelper {
|
||||
w,
|
||||
h,
|
||||
maximize,
|
||||
!gateway.isEmpty() ? "\n" + gateway : "");
|
||||
!gateway.isEmpty() ? "\n" + String.join("\n", gateway) : "");
|
||||
Files.createDirectories(file.getParent());
|
||||
Files.writeString(file, string);
|
||||
return file;
|
||||
|
||||
Reference in New Issue
Block a user