diff --git a/common/src/main/java/net/pcal/fastback/logging/Log4jLogger.java b/common/src/main/java/net/pcal/fastback/logging/Log4jLogger.java index 68636615..4abcd1b4 100644 --- a/common/src/main/java/net/pcal/fastback/logging/Log4jLogger.java +++ b/common/src/main/java/net/pcal/fastback/logging/Log4jLogger.java @@ -54,6 +54,11 @@ public void warn(String message) { this.log4j.warn(message); } + @Override + public void warn(String message, Throwable t) { + this.log4j.warn(message, t); + } + @Override public void info(String message) { this.log4j.info(message); diff --git a/common/src/main/java/net/pcal/fastback/logging/SystemLogger.java b/common/src/main/java/net/pcal/fastback/logging/SystemLogger.java index 8fcc60c8..4d7266f5 100644 --- a/common/src/main/java/net/pcal/fastback/logging/SystemLogger.java +++ b/common/src/main/java/net/pcal/fastback/logging/SystemLogger.java @@ -44,6 +44,8 @@ default void error(Throwable e) { void warn(String message); + void warn(String message, Throwable t); + void info(String message); void debug(String message); diff --git a/common/src/main/java/net/pcal/fastback/mod/ModImpl.java b/common/src/main/java/net/pcal/fastback/mod/ModImpl.java index 69b6df30..0082ca53 100644 --- a/common/src/main/java/net/pcal/fastback/mod/ModImpl.java +++ b/common/src/main/java/net/pcal/fastback/mod/ModImpl.java @@ -30,6 +30,7 @@ import java.nio.file.Path; import java.util.Collection; import java.util.Map; +import java.util.ServiceConfigurationError; import static java.nio.file.Files.createTempDirectory; import static java.util.Objects.requireNonNull; @@ -162,10 +163,14 @@ public void onInitialize() { syslog().info("git-lfs is installed: " + gitLfsVersion); } } - if (SshSessionFactory.getInstance() == null) { - syslog().warn("An ssh provider was not initialized for jgit. Operations on a remote repo over ssh will fail."); - } else { - syslog().info("SshSessionFactory: " + SshSessionFactory.getInstance().toString()); + try { + if (SshSessionFactory.getInstance() == null) { + syslog().warn("An ssh provider was not initialized for jgit. Operations on a remote repo over ssh will fail."); + } else { + syslog().info("SshSessionFactory: " + SshSessionFactory.getInstance().toString()); + } + } catch (Exception | ServiceConfigurationError e) { + syslog().warn("An ssh provider was not initialized for jgit. Operations on a remote repo over ssh will fail.", e); } syslog().debug("onInitialize complete"); } diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 91d65a84..e4196efd 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -41,14 +41,25 @@ dependencies { forgeRuntimeLibrary implementation("org.eclipse.jgit:org.eclipse.jgit:${project.jgit_version}") { transitive = false } shadowCommon("org.eclipse.jgit:org.eclipse.jgit:${project.jgit_version}") { transitive = false } - forgeRuntimeLibrary runtimeOnly("org.eclipse.jgit:org.eclipse.jgit.ssh.jsch:${project.jgit_version}") { transitive = false; } - shadowCommon("org.eclipse.jgit:org.eclipse.jgit.ssh.jsch:${project.jgit_version}") { transitive = false } - - forgeRuntimeLibrary runtimeOnly('com.jcraft:jsch:0.1.55') - shadowCommon('com.jcraft:jsch:0.1.55') - forgeRuntimeLibrary runtimeOnly("com.googlecode.javaewah:JavaEWAH:${project.JavaEWAH_version}") { transitive = false } shadowCommon("com.googlecode.javaewah:JavaEWAH:${project.JavaEWAH_version}") { transitive = false } + + // https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit.ssh.apache + forgeRuntimeLibrary runtimeOnly("org.eclipse.jgit:org.eclipse.jgit.ssh.apache:${project.jgit_version}") { transitive = false } + shadowCommon("org.eclipse.jgit:org.eclipse.jgit.ssh.apache:${project.jgit_version}") { transitive = false } + + // https://mvnrepository.com/artifact/org.apache.sshd/sshd-core + forgeRuntimeLibrary runtimeOnly("org.apache.sshd:sshd-core:${project.apache_sshd_version}") { transitive = false } + shadowCommon("org.apache.sshd:sshd-core:${project.apache_sshd_version}") { transitive = false } + + // https://mvnrepository.com/artifact/org.apache.sshd/sshd-common + forgeRuntimeLibrary runtimeOnly("org.apache.sshd:sshd-common:${project.apache_sshd_version}") { transitive = false } + shadowCommon("org.apache.sshd:sshd-common:${project.apache_sshd_version}") { transitive = false } + + // this enables ed25519 support in apache_sshd + // https://github.com/apache/mina-sshd/blob/dfa109b7b535d64e8ee395ddd0419e7696fb24ee/docs/dependencies.md + forgeRuntimeLibrary runtimeOnly("net.i2p.crypto:eddsa:${project.eddsa_version}") { transitive = false } + shadowCommon("net.i2p.crypto:eddsa:${project.eddsa_version}") { transitive = false } } processResources { diff --git a/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/ForgeCommonProvider.java b/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/ForgeCommonProvider.java index 57ef6a02..8d827c6b 100644 --- a/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/ForgeCommonProvider.java +++ b/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/ForgeCommonProvider.java @@ -97,7 +97,6 @@ void onInitialize() { this.lifecycleListener = MinecraftProvider.register(this); syslog().debug("registered backup command"); this.lifecycleListener.onInitialize(); - SshHacks.ensureSshSessionFactoryIsAvailable(); syslog().info("Fastback initialized"); syslog().warn("------------------------------------------------------------------------------------"); syslog().warn("Thanks for trying the new Forge version of Fastback. For help, go to:"); diff --git a/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/Slf4jSystemLogger.java b/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/Slf4jSystemLogger.java index b1831a40..f388be5b 100644 --- a/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/Slf4jSystemLogger.java +++ b/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/Slf4jSystemLogger.java @@ -38,6 +38,11 @@ public void warn(String message) { this.slf4j.warn(message); } + @Override + public void warn(String message, Throwable t) { + this.slf4j.warn(message, t); + } + @Override public void info(String message) { this.slf4j.info(message); diff --git a/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/SshHacks.java b/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/SshHacks.java deleted file mode 100644 index 11b082b6..00000000 --- a/neoforge/src/main/java/net/pcal/fastback/mod/neoforge/SshHacks.java +++ /dev/null @@ -1,113 +0,0 @@ -package net.pcal.fastback.mod.neoforge; - -import org.eclipse.jgit.transport.SshSessionFactory; - -import java.lang.reflect.InvocationTargetException; - -import static net.pcal.fastback.logging.SystemLogger.syslog; - -public class SshHacks { - - /** - * This is necessary because JGit looks for it's SshSessionFactory with java.util.ServiceLoader, and that - * just doesn't seem to be something that Forge is willing to accommodate. - */ - public static void ensureSshSessionFactoryIsAvailable() { - try { - if (SshSessionFactory.getInstance() == null) { - try { - final String clazz = "org.eclipse.jgit.transport.ssh.jsch.JschConfigSessionFactory"; - SshSessionFactory.setInstance((SshSessionFactory) Class.forName(clazz).getConstructor().newInstance()); - // AFAICT this only happens in Intellij. Something about shadowJar and relocate isn't working in dev environments. - // Seems fine in the launcher. - syslog().warn("A SshSessionFactory was not located via java services; a " + clazz + " has been installed manually. This is probably ok."); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | - NoSuchMethodException | InvocationTargetException ohwell) { - syslog().error("Unable to manually set SshSessionFactory. SSH connections will probably not work.", ohwell); - } - } - // - } catch (Error err) { - syslog().error("WAT", err); - } - } - - //JschConfigSessionFactory csf = new JschConfigSessionFactory(); - //SshSessionFactory.setInstance(csf); - // This works fine but the jsch provider doesn't support ed25519 keys; for that we need to get mina - // working, but that brings us into a whole other world of classloading and shading pain. Because - // Forge excludes everything under org.apache.*? Is that true? Ugh, FIXME. - // This all works perfectly fine with Fabric. :( - - - //https://stackoverflow.com/questions/67767455/setting-ssh-keys-to-use-with-jgit-with-ssh-from-apache-sshd - //https://www.eclipse.org/forums/index.php/t/1107487/ - //https://github.com/AzBuilder/terrakube/blob/67f992c84cb2f66ce17a2e2ab85796872429720b/api/src/main/java/org/terrakube/api/plugin/ssh/TerrakubeSshdSessionFactory.java#L6 - - //https://stackoverflow.com/questions/65566138/apache-mina-sshd-ssh-client-always-prints-eddsa-provider-not-supported - //If you don't fix this, then you will not be able to validate the host keys. My testing was not impacted because I was not validating the host keys yet. However, once deployed to production, I would have been impacted because host keys must be validated. - //https://dzone.com/articles/jgit-library-examples-in-java - - //SecurityUtils.setDefaultProviderChoice(new EdDSASecurityProviderRegistrar()); - - /** - String CLAZZ = EdDSASecurityProviderRegistrar.class.getNa this.lifecycleListener.onInitialize(); - me();//"net.pcal.fastback.relocated.org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderRegistrar"; - syslog().warn("!!!! "+CLAZZ); - try { - Class.forName(CLAZZ); - } catch (ClassNotFoundException e) { - syslog().error(new RuntimeException(e)); - } - System.setProperty("org.apache.sshd.security.registrars", CLAZZ); - **/ -// - - - /** - * - then we can try this, but i'm having a heck of a time getting the i2p provider to load >:( - if (false) { - File sshDir = new File(FS.DETECTED.userHome(), "/.ssh"); - - SshdSessionFactory sshSessionFactory = new SshdSessionFactoryBuilder() - .setPreferredAuthentications("publickey") - .setHomeDirectory(FS.DETECTED.userHome()) - .setSshDirectory(sshDir) - - .setServerKeyDatabase((h, s) -> new ServerKeyDatabase() { - - @Override public List lookup(String connectAddress, - InetSocketAddress remoteAddress, - Configuration config) { - return Collections.emptyList(); - } - - @Override public boolean accept(String connectAddress, - InetSocketAddress remoteAddress, - PublicKey serverKey, Configuration config, - CredentialsProvider provider) { - return true; - } - - }) - .build(new JGitKeyCache()); - SshSessionFactory.setInstance(sshSessionFactory); - } - **/ - /** - - //SshdSessionFactory factory = new SshdSessionFactory(new JGitKeyCache(), new DefaultProxyDataFactory()); - SshdSessionFactory factory = new SshdSessionFactory(); - try { - Runtime.getRuntime() - .addShutdownHook(new Thread(factory::close)); - } catch (IllegalStateException e) { - // ignore - the VM is already shutting down - } - SshSessionFactory.setInstance(factory); - - - } - **/ -}