diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategy.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategy.java index 48e83da7f..aa7664ebc 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategy.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategy.java @@ -81,8 +81,13 @@ public interface SshIdentityStrategy { } @JsonTypeName("pageant") + @Value + @Jacksonized + @Builder class Pageant implements SshIdentityStrategy { + boolean forwardAgent; + @Override public void prepareParent(ShellControl parent) throws Exception { if (!parent.getOsType().equals(OsType.WINDOWS)) { @@ -110,6 +115,9 @@ public interface SshIdentityStrategy { return null; }); + if (forwardAgent) { + builder.add(1, "-A"); + } } private String getPageantWindowsPipe(ShellControl parent) throws Exception { @@ -228,7 +236,7 @@ public interface SshIdentityStrategy { @JsonTypeName("gpgAgent") class GpgAgent implements SshIdentityStrategy { - private static final Set startedSystems = new HashSet<>(); + boolean forwardAgent; @Override public void prepareParent(ShellControl parent) throws Exception { @@ -246,6 +254,9 @@ public interface SshIdentityStrategy { var r = sc.executeSimpleStringCommand("gpgconf --list-dirs agent-ssh-socket"); return r; }); + if (forwardAgent) { + builder.add(1, "-A"); + } } } @@ -359,13 +370,21 @@ public interface SshIdentityStrategy { } @JsonTypeName("otherExternal") + @Value + @Jacksonized + @Builder class OtherExternal implements SshIdentityStrategy { + boolean forwardAgent; + @Override public void prepareParent(ShellControl parent) {} @Override public void buildCommand(CommandBuilder builder) { + if (forwardAgent) { + builder.add(1, "-A"); + } builder.add("-oIdentitiesOnly=no"); } } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategyHelper.java b/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategyHelper.java index 617496298..415637198 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategyHelper.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/identity/SshIdentityStrategyHelper.java @@ -32,6 +32,48 @@ public class SshIdentityStrategyHelper { p); } + private static OptionsBuilder gpgAgent(Property p) { + var forward = + new SimpleBooleanProperty(p.getValue() != null && p.getValue().isForwardAgent()); + return new OptionsBuilder() + .nameAndDescription("forwardAgent") + .addToggle(forward) + .nonNull() + .bind( + () -> { + return new SshIdentityStrategy.GpgAgent(forward.get()); + }, + p); + } + + private static OptionsBuilder pageant(Property p) { + var forward = + new SimpleBooleanProperty(p.getValue() != null && p.getValue().isForwardAgent()); + return new OptionsBuilder() + .nameAndDescription("forwardAgent") + .addToggle(forward) + .nonNull() + .bind( + () -> { + return new SshIdentityStrategy.Pageant(forward.get()); + }, + p); + } + + private static OptionsBuilder otherExternal(Property p) { + var forward = + new SimpleBooleanProperty(p.getValue() != null && p.getValue().isForwardAgent()); + return new OptionsBuilder() + .nameAndDescription("forwardAgent") + .addToggle(forward) + .nonNull() + .bind( + () -> { + return new SshIdentityStrategy.OtherExternal(forward.get()); + }, + p); + } + private static OptionsBuilder customPkcs11Library(Property p) { var file = new SimpleStringProperty(p.getValue() != null ? p.getValue().getFile() : null); return new OptionsBuilder() @@ -100,6 +142,9 @@ public class SshIdentityStrategyHelper { var customPkcs11 = new SimpleObjectProperty<>(strat instanceof SshIdentityStrategy.CustomPkcs11Library f ? f : null); var agent = new SimpleObjectProperty<>(strat instanceof SshIdentityStrategy.SshAgent a ? a : null); + var pageant = new SimpleObjectProperty<>(strat instanceof SshIdentityStrategy.Pageant a ? a : null); + var gpgAgent = new SimpleObjectProperty<>(strat instanceof SshIdentityStrategy.GpgAgent a ? a : null); + var otherExternal = new SimpleObjectProperty<>(strat instanceof SshIdentityStrategy.OtherExternal a ? a : null); var gpgFeature = LicenseProvider.get().getFeature("gpgAgent"); var pkcs11Feature = LicenseProvider.get().getFeature("pkcs11Identity"); @@ -110,11 +155,11 @@ public class SshIdentityStrategyHelper { AppI18n.observable("base.keyFile"), fileIdentity(proxy, file, perUserFile, allowSync)); map.put(AppI18n.observable("base.sshAgent"), agent(agent)); - map.put(AppI18n.observable("base.pageant"), new OptionsBuilder()); - map.put(gpgFeature.suffixObservable("base.gpgAgent"), new OptionsBuilder()); + map.put(AppI18n.observable("base.pageant"), pageant(pageant)); + map.put(gpgFeature.suffixObservable("base.gpgAgent"), gpgAgent(gpgAgent)); map.put(pkcs11Feature.suffixObservable("base.yubikeyPiv"), new OptionsBuilder()); map.put(pkcs11Feature.suffixObservable("base.customPkcs11Library"), customPkcs11Library(customPkcs11)); - map.put(AppI18n.observable("base.otherExternal"), new OptionsBuilder()); + map.put(AppI18n.observable("base.otherExternal"), otherExternal(otherExternal)); var identityMethodSelected = new SimpleIntegerProperty( strat instanceof SshIdentityStrategy.None ? 0 @@ -148,11 +193,11 @@ public class SshIdentityStrategyHelper { case 0 -> new SimpleObjectProperty<>(new SshIdentityStrategy.None()); case 1 -> file; case 2 -> agent; - case 3 -> new SimpleObjectProperty<>(new SshIdentityStrategy.Pageant()); - case 4 -> new SimpleObjectProperty<>(new SshIdentityStrategy.GpgAgent()); + case 3 -> pageant; + case 4 -> gpgAgent; case 5 -> new SimpleObjectProperty<>(new SshIdentityStrategy.YubikeyPiv()); case 6 -> customPkcs11; - case 7 -> new SimpleObjectProperty<>(new SshIdentityStrategy.OtherExternal()); + case 7 -> otherExternal; default -> new SimpleObjectProperty<>(); }; },