diff --git a/app/src/main/java/io/xpipe/app/cred/CustomAgentStrategy.java b/app/src/main/java/io/xpipe/app/cred/CustomAgentStrategy.java index 0669a6fb6..4b0940011 100644 --- a/app/src/main/java/io/xpipe/app/cred/CustomAgentStrategy.java +++ b/app/src/main/java/io/xpipe/app/cred/CustomAgentStrategy.java @@ -9,6 +9,7 @@ import io.xpipe.app.platform.Validator; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.process.CommandBuilder; import io.xpipe.app.process.ShellControl; +import io.xpipe.core.FilePath; import io.xpipe.core.KeyValue; import io.xpipe.core.OsType; @@ -31,7 +32,7 @@ import java.util.List; @Value @Jacksonized @Builder -public class CustomAgentStrategy implements SshIdentityStrategy { +public class CustomAgentStrategy implements SshIdentityAgentStrategy { @SuppressWarnings("unused") public static OptionsBuilder createOptions( @@ -104,9 +105,7 @@ public class CustomAgentStrategy implements SshIdentityStrategy { } @Override - public void buildCommand(CommandBuilder builder) {} - - private String getIdentityAgent(ShellControl sc) throws Exception { + public FilePath determinetAgentSocketLocation(ShellControl sc) throws Exception { if (!sc.isLocal() || sc.getOsType() == OsType.WINDOWS) { return null; } @@ -117,13 +116,16 @@ public class CustomAgentStrategy implements SshIdentityStrategy { agent = AppPrefs.get().defaultSshAgentSocket().getValue(); } if (agent != null) { - return agent.resolveTildeHome(sc.view().userHome()).toString(); + return agent.resolveTildeHome(sc.view().userHome()); } } return null; } + @Override + public void buildCommand(CommandBuilder builder) {} + @Override public List configOptions(ShellControl sc) throws Exception { var file = SshIdentityStrategy.getPublicKeyPath(sc, publicKey); @@ -133,7 +135,7 @@ public class CustomAgentStrategy implements SshIdentityStrategy { new KeyValue("IdentityFile", file.isPresent() ? file.get().toString() : "none"), new KeyValue("PKCS11Provider", "none"))); - var agent = getIdentityAgent(sc); + var agent = determinetAgentSocketLocation(sc); if (agent != null) { l.add(new KeyValue("IdentityAgent", "\"" + agent + "\"")); } diff --git a/app/src/main/java/io/xpipe/app/cred/GpgAgentStrategy.java b/app/src/main/java/io/xpipe/app/cred/GpgAgentStrategy.java index b3eb26510..59b797ede 100644 --- a/app/src/main/java/io/xpipe/app/cred/GpgAgentStrategy.java +++ b/app/src/main/java/io/xpipe/app/cred/GpgAgentStrategy.java @@ -7,6 +7,7 @@ import io.xpipe.app.process.CommandBuilder; import io.xpipe.app.process.LocalShell; import io.xpipe.app.process.ShellControl; import io.xpipe.app.util.LicenseProvider; +import io.xpipe.core.FilePath; import io.xpipe.core.KeyValue; import io.xpipe.core.OsType; @@ -27,7 +28,7 @@ import java.util.List; @Jacksonized @Builder @JsonTypeName("gpgAgent") -public class GpgAgentStrategy implements SshIdentityStrategy { +public class GpgAgentStrategy implements SshIdentityAgentStrategy { @SuppressWarnings("unused") public static OptionsBuilder createOptions(Property p, SshIdentityStrategyChoiceConfig config) { @@ -81,9 +82,7 @@ public class GpgAgentStrategy implements SshIdentityStrategy { } @Override - public void buildCommand(CommandBuilder builder) {} - - private String getIdentityAgent(ShellControl sc) throws Exception { + public FilePath determinetAgentSocketLocation(ShellControl sc) throws Exception { if (sc.getOsType() == OsType.WINDOWS) { return null; } @@ -93,9 +92,12 @@ public class GpgAgentStrategy implements SshIdentityStrategy { return null; } - return r; + return FilePath.of(r); } + @Override + public void buildCommand(CommandBuilder builder) {} + @Override public List configOptions(ShellControl sc) throws Exception { var file = SshIdentityStrategy.getPublicKeyPath(sc, publicKey); @@ -105,7 +107,7 @@ public class GpgAgentStrategy implements SshIdentityStrategy { new KeyValue("IdentityFile", file.isPresent() ? file.get().toString() : "none"), new KeyValue("PKCS11Provider", "none"))); - var agent = getIdentityAgent(sc); + var agent = determinetAgentSocketLocation(sc); if (agent != null) { l.add(new KeyValue("IdentityAgent", "\"" + agent + "\"")); } diff --git a/app/src/main/java/io/xpipe/app/cred/OpenSshAgentStrategy.java b/app/src/main/java/io/xpipe/app/cred/OpenSshAgentStrategy.java index 47b3e52ab..8ae6d2cdd 100644 --- a/app/src/main/java/io/xpipe/app/cred/OpenSshAgentStrategy.java +++ b/app/src/main/java/io/xpipe/app/cred/OpenSshAgentStrategy.java @@ -5,6 +5,7 @@ import io.xpipe.app.platform.OptionsBuilder; import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.process.CommandBuilder; import io.xpipe.app.process.ShellControl; +import io.xpipe.core.FilePath; import io.xpipe.core.KeyValue; import io.xpipe.core.OsType; @@ -24,7 +25,7 @@ import java.util.List; @Value @Jacksonized @Builder -public class OpenSshAgentStrategy implements SshIdentityStrategy { +public class OpenSshAgentStrategy implements SshIdentityAgentStrategy { @SuppressWarnings("unused") public static OptionsBuilder createOptions( @@ -63,9 +64,7 @@ public class OpenSshAgentStrategy implements SshIdentityStrategy { } @Override - public void buildCommand(CommandBuilder builder) {} - - private String getIdentityAgent(ShellControl sc) throws Exception { + public FilePath determinetAgentSocketLocation(ShellControl sc) throws Exception { if (sc.getOsType() == OsType.WINDOWS) { return null; } @@ -73,13 +72,16 @@ public class OpenSshAgentStrategy implements SshIdentityStrategy { if (AppPrefs.get() != null) { var socket = AppPrefs.get().defaultSshAgentSocket().getValue(); if (socket != null) { - return socket.resolveTildeHome(sc.view().userHome()).toString(); + return socket.resolveTildeHome(sc.view().userHome()); } } return null; } + @Override + public void buildCommand(CommandBuilder builder) {} + @Override public List configOptions(ShellControl sc) throws Exception { var file = SshIdentityStrategy.getPublicKeyPath(sc, publicKey); @@ -89,7 +91,7 @@ public class OpenSshAgentStrategy implements SshIdentityStrategy { new KeyValue("IdentityFile", file.isPresent() ? file.get().toString() : "none"), new KeyValue("PKCS11Provider", "none"))); - var agent = getIdentityAgent(sc); + var agent = determinetAgentSocketLocation(sc); if (agent != null) { l.add(new KeyValue("IdentityAgent", "\"" + agent + "\"")); } diff --git a/app/src/main/java/io/xpipe/app/cred/OtherExternalAgentStrategy.java b/app/src/main/java/io/xpipe/app/cred/OtherExternalAgentStrategy.java index a7fc56f6a..a8b3203bc 100644 --- a/app/src/main/java/io/xpipe/app/cred/OtherExternalAgentStrategy.java +++ b/app/src/main/java/io/xpipe/app/cred/OtherExternalAgentStrategy.java @@ -3,6 +3,7 @@ package io.xpipe.app.cred; import io.xpipe.app.platform.OptionsBuilder; import io.xpipe.app.process.CommandBuilder; import io.xpipe.app.process.ShellControl; +import io.xpipe.core.FilePath; import io.xpipe.core.KeyValue; import javafx.beans.property.Property; @@ -20,7 +21,7 @@ import java.util.List; @Value @Jacksonized @Builder -public class OtherExternalAgentStrategy implements SshIdentityStrategy { +public class OtherExternalAgentStrategy implements SshIdentityAgentStrategy { @SuppressWarnings("unused") public static OptionsBuilder createOptions( @@ -54,6 +55,11 @@ public class OtherExternalAgentStrategy implements SshIdentityStrategy { } } + @Override + public FilePath determinetAgentSocketLocation(ShellControl parent) throws Exception { + return null; + } + @Override public void buildCommand(CommandBuilder builder) {} diff --git a/app/src/main/java/io/xpipe/app/cred/PageantStrategy.java b/app/src/main/java/io/xpipe/app/cred/PageantStrategy.java index 8444630ab..5135e0e51 100644 --- a/app/src/main/java/io/xpipe/app/cred/PageantStrategy.java +++ b/app/src/main/java/io/xpipe/app/cred/PageantStrategy.java @@ -8,6 +8,7 @@ import io.xpipe.app.process.CommandBuilder; import io.xpipe.app.process.LocalShell; import io.xpipe.app.process.ShellControl; import io.xpipe.app.util.LocalExec; +import io.xpipe.core.FilePath; import io.xpipe.core.KeyValue; import io.xpipe.core.OsType; @@ -30,7 +31,7 @@ import java.util.List; @Value @Jacksonized @Builder -public class PageantStrategy implements SshIdentityStrategy { +public class PageantStrategy implements SshIdentityAgentStrategy { @SuppressWarnings("unused") public static OptionsBuilder createOptions(Property p, SshIdentityStrategyChoiceConfig config) { @@ -95,16 +96,17 @@ public class PageantStrategy implements SshIdentityStrategy { } @Override - public void buildCommand(CommandBuilder builder) {} - - private String getIdentityAgent(ShellControl sc) { + public FilePath determinetAgentSocketLocation(ShellControl sc) throws Exception { if (sc.isLocal() && sc.getOsType() == OsType.WINDOWS) { - return getPageantWindowsPipe(); + return FilePath.of(getPageantWindowsPipe()); } return null; } + @Override + public void buildCommand(CommandBuilder builder) {} + @Override public List configOptions(ShellControl sc) throws Exception { var file = SshIdentityStrategy.getPublicKeyPath(sc, publicKey); @@ -114,7 +116,7 @@ public class PageantStrategy implements SshIdentityStrategy { new KeyValue("IdentityFile", file.isPresent() ? file.get().toString() : "none"), new KeyValue("PKCS11Provider", "none"))); - var agent = getIdentityAgent(sc); + var agent = determinetAgentSocketLocation(sc); if (agent != null) { l.add(new KeyValue("IdentityAgent", "\"" + agent + "\"")); } diff --git a/app/src/main/java/io/xpipe/app/cred/PasswordManagerAgentStrategy.java b/app/src/main/java/io/xpipe/app/cred/PasswordManagerAgentStrategy.java index ffd054d01..2a20a5991 100644 --- a/app/src/main/java/io/xpipe/app/cred/PasswordManagerAgentStrategy.java +++ b/app/src/main/java/io/xpipe/app/cred/PasswordManagerAgentStrategy.java @@ -14,6 +14,7 @@ import io.xpipe.app.process.ShellControl; import io.xpipe.app.pwman.PasswordManagerKeyConfiguration; import io.xpipe.app.storage.DataStorage; import io.xpipe.app.util.Validators; +import io.xpipe.core.FilePath; import io.xpipe.core.KeyValue; import javafx.beans.binding.Bindings; import javafx.beans.property.Property; @@ -33,7 +34,7 @@ import java.util.List; @Value @Jacksonized @Builder -public class PasswordManagerAgentStrategy implements SshIdentityStrategy { +public class PasswordManagerAgentStrategy implements SshIdentityAgentStrategy { @SuppressWarnings("unused") public static OptionsBuilder createOptions( @@ -111,6 +112,11 @@ public class PasswordManagerAgentStrategy implements SshIdentityStrategy { } } + @Override + public FilePath determinetAgentSocketLocation(ShellControl parent) throws Exception { + return null; + } + @Override public void buildCommand(CommandBuilder builder) { var config = getConfig(); diff --git a/app/src/main/java/io/xpipe/app/cred/SshAgentKeyList.java b/app/src/main/java/io/xpipe/app/cred/SshAgentKeyList.java index 0a0c46b65..c7e79f244 100644 --- a/app/src/main/java/io/xpipe/app/cred/SshAgentKeyList.java +++ b/app/src/main/java/io/xpipe/app/cred/SshAgentKeyList.java @@ -30,7 +30,7 @@ public class SshAgentKeyList { } } - public static Entry findAgentIdentity(DataStoreEntryRef ref, SshIdentityStrategy strategy, String identifier) throws Exception { + public static Entry findAgentIdentity(DataStoreEntryRef ref, SshIdentityAgentStrategy strategy, String identifier) throws Exception { var list = listAgentIdentities(ref, strategy).stream().filter(entry -> { return entry.getName().equalsIgnoreCase(identifier) || entry.getPublicKey().equalsIgnoreCase(identifier); }).toList(); @@ -47,11 +47,12 @@ public class SshAgentKeyList { return list.getFirst(); } - public static List listAgentIdentities(DataStoreEntryRef ref, SshIdentityStrategy strategy) throws Exception { + public static List listAgentIdentities(DataStoreEntryRef ref, SshIdentityAgentStrategy strategy) throws Exception { var session = ref.getStore().getOrStartSession(); strategy.prepareParent(session); - var out = session.command(CommandBuilder.of().add("ssh-add", "-L")).readStdoutOrThrow(); + var socket = strategy.determinetAgentSocketLocation(session); + var out = session.command(CommandBuilder.of().add("ssh-add", "-L").fixedEnvironment("SSH_AUTH_SOCK", socket != null ? socket.toString() : null)).readStdoutOrThrow(); var pattern = Pattern.compile("([^ ]+) ([^ ]+) (.+)"); var lines = out.lines().toList(); var list = new ArrayList(); diff --git a/app/src/main/java/io/xpipe/app/cred/SshAgentKeyListComp.java b/app/src/main/java/io/xpipe/app/cred/SshAgentKeyListComp.java index 4f1d9b349..293cc1b6e 100644 --- a/app/src/main/java/io/xpipe/app/cred/SshAgentKeyListComp.java +++ b/app/src/main/java/io/xpipe/app/cred/SshAgentKeyListComp.java @@ -29,11 +29,11 @@ import java.util.List; public class SshAgentKeyListComp extends SimpleRegionBuilder { private final ObservableValue> ref; - private final ObservableValue sshIdentityStrategy; + private final ObservableValue sshIdentityStrategy; private final StringProperty value; private final boolean useKeyNames; - public SshAgentKeyListComp(ObservableValue> ref, ObservableValue sshIdentityStrategy, StringProperty value, + public SshAgentKeyListComp(ObservableValue> ref, ObservableValue sshIdentityStrategy, StringProperty value, boolean useKeyNames ) { this.ref = ref; diff --git a/app/src/main/java/io/xpipe/app/cred/SshAgentTestComp.java b/app/src/main/java/io/xpipe/app/cred/SshAgentTestComp.java index 6b7409006..ad97b8d28 100644 --- a/app/src/main/java/io/xpipe/app/cred/SshAgentTestComp.java +++ b/app/src/main/java/io/xpipe/app/cred/SshAgentTestComp.java @@ -26,9 +26,9 @@ import java.util.List; public class SshAgentTestComp extends SimpleRegionBuilder { - private final ObservableValue sshIdentityStrategy; + private final ObservableValue sshIdentityStrategy; - public SshAgentTestComp(ObservableValue sshIdentityStrategy) {this.sshIdentityStrategy = sshIdentityStrategy;} + public SshAgentTestComp(ObservableValue sshIdentityStrategy) {this.sshIdentityStrategy = sshIdentityStrategy;} @Override protected Region createSimple() { diff --git a/app/src/main/java/io/xpipe/app/cred/SshIdentityAgentStrategy.java b/app/src/main/java/io/xpipe/app/cred/SshIdentityAgentStrategy.java new file mode 100644 index 000000000..7aa992736 --- /dev/null +++ b/app/src/main/java/io/xpipe/app/cred/SshIdentityAgentStrategy.java @@ -0,0 +1,24 @@ +package io.xpipe.app.cred; + +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import io.xpipe.app.ext.ValidationException; +import io.xpipe.app.issue.ErrorEventFactory; +import io.xpipe.app.process.CommandBuilder; +import io.xpipe.app.process.OsFileSystem; +import io.xpipe.app.process.ShellControl; +import io.xpipe.app.secret.SecretNoneStrategy; +import io.xpipe.app.secret.SecretRetrievalStrategy; +import io.xpipe.core.FilePath; +import io.xpipe.core.KeyValue; +import io.xpipe.core.OsType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public interface SshIdentityAgentStrategy extends SshIdentityStrategy { + + void prepareParent(ShellControl parent) throws Exception; + + FilePath determinetAgentSocketLocation(ShellControl parent) throws Exception; +} diff --git a/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyConfiguration.java b/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyConfiguration.java index dccd45a46..3f2e80a3a 100644 --- a/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyConfiguration.java +++ b/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyConfiguration.java @@ -1,5 +1,6 @@ package io.xpipe.app.pwman; +import io.xpipe.app.cred.SshIdentityAgentStrategy; import io.xpipe.app.cred.SshIdentityStrategy; import java.nio.file.Path; @@ -24,7 +25,7 @@ public interface PasswordManagerKeyConfiguration { } @Override - public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) { + public SshIdentityAgentStrategy getSshIdentityStrategy(String publicKey, boolean forward) { return strategy.getSshIdentityStrategy(publicKey, forward); } @@ -58,7 +59,7 @@ public interface PasswordManagerKeyConfiguration { } @Override - public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) { + public SshIdentityAgentStrategy getSshIdentityStrategy(String publicKey, boolean forward) { return null; } @@ -80,7 +81,7 @@ public interface PasswordManagerKeyConfiguration { boolean supportsAgentKeyNames(); - SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward); + SshIdentityAgentStrategy getSshIdentityStrategy(String publicKey, boolean forward); Path getDefaultSocketLocation(); diff --git a/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyStrategy.java b/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyStrategy.java index 565d10acd..cd649aa57 100644 --- a/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyStrategy.java +++ b/app/src/main/java/io/xpipe/app/pwman/PasswordManagerKeyStrategy.java @@ -52,7 +52,7 @@ public interface PasswordManagerKeyStrategy { } @Override - public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) { + public SshIdentityAgentStrategy getSshIdentityStrategy(String publicKey, boolean forward) { return null; } } @@ -112,8 +112,8 @@ public interface PasswordManagerKeyStrategy { } @Override - public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) { - return new SshIdentityStrategy() { + public SshIdentityAgentStrategy getSshIdentityStrategy(String publicKey, boolean forward) { + return new SshIdentityAgentStrategy() { @Override public void prepareParent(ShellControl parent) throws Exception { if (parent.isLocal()) { @@ -121,6 +121,11 @@ public interface PasswordManagerKeyStrategy { } } + @Override + public FilePath determinetAgentSocketLocation(ShellControl parent) throws Exception { + return socket != null ? socket.resolveTildeHome(parent.view().userHome()) : null; + } + @Override public void buildCommand(CommandBuilder builder) {} @@ -170,7 +175,7 @@ public interface PasswordManagerKeyStrategy { } @Override - public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) { + public SshIdentityAgentStrategy getSshIdentityStrategy(String publicKey, boolean forward) { return OpenSshAgentStrategy.builder().build(); } } @@ -198,14 +203,14 @@ public interface PasswordManagerKeyStrategy { } @Override - public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) { + public SshIdentityAgentStrategy getSshIdentityStrategy(String publicKey, boolean forward) { return PageantStrategy.builder().build(); } } boolean useAgent(); - SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward); + SshIdentityAgentStrategy getSshIdentityStrategy(String publicKey, boolean forward); static List> getClasses() { var l = new ArrayList>();