diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 77cba3154..cf5eb12be 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -6,20 +6,20 @@ name: Build SSHJ on: push: - branches: [ master ] pull_request: branches: [ master ] jobs: java12: - name: Build with Java 12 + name: Build with Java 11 runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up JDK 12 - uses: actions/setup-java@v1 + - name: Set up Java 11 + uses: actions/setup-java@v3 with: - java-version: 12 + distribution: 'temurin' + java-version: 11 - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle @@ -29,14 +29,14 @@ jobs: integration: name: Integration test - needs: [java12] - runs-on: [ubuntu-latest] + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v3 with: - java-version: 12 + distribution: 'temurin' + java-version: 11 - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle diff --git a/README.adoc b/README.adoc index c08254a06..29ec174aa 100644 --- a/README.adoc +++ b/README.adoc @@ -95,7 +95,11 @@ If you need something that is not included, it shouldn't be too hard to add (do http://ssh-comparison.quendi.de/comparison.html[SSH Implementation Comparison] == Dependencies -Java 7+. http://www.slf4j.org/download.html[slf4j] is required. http://www.bouncycastle.org/java.html[bouncycastle] is highly recommended and required for using some of the crypto algorithms. + +- Java 8 or higher +- https://www.slf4j.org/[SLF4J 2.0.0] +- https://www.bouncycastle.org[Bouncy Castle] + == Reporting bugs Issue tracker: https://github.com/hierynomus/sshj/issues diff --git a/build.gradle b/build.gradle index ddacb2109..4560fd258 100644 --- a/build.gradle +++ b/build.gradle @@ -35,27 +35,29 @@ project.version = scmVersion.version configurations.implementation.transitive = false -def bouncycastleVersion = "1.70" -def sshdVersion = "2.8.0" +def bouncycastleVersion = "1.75" +def sshdVersion = "2.10.0" dependencies { - implementation "org.slf4j:slf4j-api:1.7.36" - implementation "org.bouncycastle:bcprov-jdk15on:$bouncycastleVersion" - implementation "org.bouncycastle:bcpkix-jdk15on:$bouncycastleVersion" + implementation "org.slf4j:slf4j-api:2.0.7" + implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion" + implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion" implementation "com.hierynomus:asn-one:0.6.0" - implementation "net.i2p.crypto:eddsa:0.3.0" - testImplementation "junit:junit:4.13.2" - testImplementation 'org.spockframework:spock-core:1.3-groovy-2.4' - testImplementation "org.mockito:mockito-core:4.2.0" + testImplementation(platform("org.junit:junit-bom:5.9.3")) + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine' + testRuntimeOnly 'org.junit.vintage:junit-vintage-engine' + testImplementation 'junit:junit:4.13.2' + testImplementation 'org.spockframework:spock-core:2.3-groovy-3.0' + testImplementation 'org.spockframework:spock-junit4:2.3-groovy-3.0' + testImplementation "org.mockito:mockito-core:4.11.0" testImplementation "org.apache.sshd:sshd-core:$sshdVersion" testImplementation "org.apache.sshd:sshd-sftp:$sshdVersion" testImplementation "org.apache.sshd:sshd-scp:$sshdVersion" - testImplementation "ch.qos.logback:logback-classic:1.2.11" - testImplementation 'org.glassfish.grizzly:grizzly-http-server:2.4.4' - testImplementation 'org.apache.httpcomponents:httpclient:4.5.13' - testImplementation 'org.testcontainers:testcontainers:1.16.2' + testImplementation "ch.qos.logback:logback-classic:1.3.8" + testImplementation 'org.glassfish.grizzly:grizzly-http-server:3.0.1' + testImplementation 'org.testcontainers:testcontainers:1.18.3' } license { @@ -83,7 +85,7 @@ if (JavaVersion.current().isJava8Compatible()) { } compileJava { - options.compilerArgs.addAll(['--release', '7']) + options.compilerArgs.addAll(['--release', '8']) } task writeSshjVersionProperties { @@ -119,7 +121,6 @@ jar { } } - java { withJavadocJar() withSourcesJar() @@ -163,14 +164,7 @@ tasks.withType(Test) { testLogging { exceptionFormat = 'full' } - include "**/*Test.*" - include "**/*Spec.*" - if (!project.hasProperty("allTests")) { - useJUnit { - excludeCategories 'com.hierynomus.sshj.test.SlowTests' - excludeCategories 'com.hierynomus.sshj.test.KnownFailingTests' - } - } + useJUnitPlatform() afterSuite { descriptor, result -> if (descriptor.className != null) { diff --git a/src/itest/groovy/com/hierynomus/sshj/RsaShaKeySignatureTest.groovy b/src/itest/groovy/com/hierynomus/sshj/RsaShaKeySignatureTest.groovy index a039b4c23..b8a8dfb80 100644 --- a/src/itest/groovy/com/hierynomus/sshj/RsaShaKeySignatureTest.groovy +++ b/src/itest/groovy/com/hierynomus/sshj/RsaShaKeySignatureTest.groovy @@ -38,7 +38,7 @@ class RsaShaKeySignatureTest extends Specification { private static void dockerfileBuilder(DockerfileBuilder it, String hostKey, String pubkeyAcceptedAlgorithms) { it.from("archlinux:base") - it.run('yes | pacman -Sy core/openssh' + + it.run('pacman -Sy --noconfirm core/openssh core/openssl' + ' && (' + ' V=$(echo $(/usr/sbin/sshd -h 2>&1) | grep -o \'OpenSSH_[0-9][0-9]*[.][0-9][0-9]*p[0-9]\');' + ' if [[ "$V" < OpenSSH_8.8p1 ]]; then' + @@ -61,7 +61,6 @@ class RsaShaKeySignatureTest extends Specification { '-D', '-e', '-f', '/dev/null', - '-o', 'LogLevel=DEBUG2', '-o', "HostKey=/etc/ssh/$hostKey", ] if (pubkeyAcceptedAlgorithms != null) { @@ -130,7 +129,7 @@ class RsaShaKeySignatureTest extends Specification { } @Unroll - def "connect to a server with host key #hostkey that supports only ssh-rsa"() { + def "connect to a server with host key #hostKey that supports only ssh-rsa"() { given: SshdContainer sshd = makeSshdContainer(hostKey, "ssh-rsa,ssh-ed25519") sshd.start() diff --git a/src/test/java/com/hierynomus/sshj/connection/channel/forwarded/LocalPortForwarderTest.java b/src/test/java/com/hierynomus/sshj/connection/channel/forwarded/LocalPortForwarderTest.java index fd48b8862..e923708f4 100644 --- a/src/test/java/com/hierynomus/sshj/connection/channel/forwarded/LocalPortForwarderTest.java +++ b/src/test/java/com/hierynomus/sshj/connection/channel/forwarded/LocalPortForwarderTest.java @@ -21,28 +21,28 @@ import net.schmizz.sshj.SSHClient; import net.schmizz.sshj.connection.channel.direct.LocalPortForwarder; import net.schmizz.sshj.connection.channel.direct.Parameters; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.HttpClientBuilder; import org.apache.sshd.server.forward.AcceptAllForwardingFilter; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; +import java.net.URL; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; public class LocalPortForwarderTest { - private static final Logger log = LoggerFactory.getLogger(LocalPortForwarderTest.class); + private static final String LOCALHOST_URL = "http://127.0.0.1:8080"; @Rule public SshFixture fixture = new SshFixture(); @@ -59,8 +59,7 @@ public void setUp() throws IOException { @Test public void shouldHaveWorkingHttpServer() throws IOException { - // Just to check that we have a working http server... - assertThat(httpGet("127.0.0.1", 8080), equalTo(200)); + assertEquals(200, httpGet()); } @Test @@ -93,7 +92,6 @@ public void shouldCloseConnectionWhenRemoteServerClosesConnection() throws IOExc } public static void httpGetAndAssertConnectionClosedByServer(int port) throws IOException { - System.out.println("HTTP GET to port: " + port); try (Socket socket = new Socket("localhost", port)) { // Send a basic HTTP GET // It returns 400 Bad Request because it's missing a bunch of info, but the HTTP response doesn't matter, we just want to test the connection closing. @@ -107,12 +105,8 @@ public static void httpGetAndAssertConnectionClosedByServer(int port) throws IOE InputStream inputStream = socket.getInputStream(); InputStreamReader reader = new InputStreamReader(inputStream); int buf = -2; - while (true) { + while (buf != -1) { buf = reader.read(); - System.out.print((char)buf); - if (buf == -1) { - break; - } } // Attempt to read more. If the server has closed the connection this will return -1 @@ -123,12 +117,12 @@ public static void httpGetAndAssertConnectionClosedByServer(int port) throws IOE } } - private int httpGet(String server, int port) throws IOException { - HttpClient client = HttpClientBuilder.create().build(); - String urlString = "http://" + server + ":" + port; - log.info("Trying: GET " + urlString); - HttpResponse execute = client.execute(new HttpGet(urlString)); - return execute.getStatusLine().getStatusCode(); + private int httpGet() throws IOException { + final URL url = new URL(LOCALHOST_URL); + final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.setConnectTimeout(3000); + urlConnection.setRequestMethod("GET"); + return urlConnection.getResponseCode(); } private SSHClient getFixtureClient() throws IOException { diff --git a/src/test/java/com/hierynomus/sshj/connection/channel/forwarded/RemotePortForwarderTest.java b/src/test/java/com/hierynomus/sshj/connection/channel/forwarded/RemotePortForwarderTest.java index b3738b8a9..9dda9e473 100644 --- a/src/test/java/com/hierynomus/sshj/connection/channel/forwarded/RemotePortForwarderTest.java +++ b/src/test/java/com/hierynomus/sshj/connection/channel/forwarded/RemotePortForwarderTest.java @@ -22,28 +22,23 @@ import net.schmizz.sshj.connection.ConnectionException; import net.schmizz.sshj.connection.channel.forwarded.RemotePortForwarder; import net.schmizz.sshj.connection.channel.forwarded.SocketForwardingConnectListener; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.HttpClientBuilder; import org.apache.sshd.server.forward.AcceptAllForwardingFilter; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; +import java.net.HttpURLConnection; import java.net.InetSocketAddress; +import java.net.URL; import static org.junit.Assert.assertEquals; public class RemotePortForwarderTest { - private static final Logger log = LoggerFactory.getLogger(RemotePortForwarderTest.class); - private static final PortRange RANGE = new PortRange(9000, 9999); private static final String LOCALHOST = "127.0.0.1"; + private static final String LOCALHOST_URL_FORMAT = "http://127.0.0.1:%d"; private static final InetSocketAddress HTTP_SERVER_SOCKET_ADDR = new InetSocketAddress(LOCALHOST, 8080); @Rule @@ -61,8 +56,7 @@ public void setUp() throws IOException { @Test public void shouldHaveWorkingHttpServer() throws IOException { - // Just to check that we have a working http server... - assertEquals(200, httpGet( 8080)); + assertEquals(200, httpGet(8080)); } @Test @@ -127,12 +121,12 @@ private RemotePortForwarder.Forward forwardPort(SSHClient sshClient, String addr } } - private int httpGet(int port) throws IOException { - HttpClient client = HttpClientBuilder.create().build(); - String urlString = "http://" + LOCALHOST + ":" + port; - log.info("Trying: GET " + urlString); - HttpResponse execute = client.execute(new HttpGet(urlString)); - return execute.getStatusLine().getStatusCode(); + private int httpGet(final int port) throws IOException { + final URL url = new URL(String.format(LOCALHOST_URL_FORMAT, port)); + final HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); + urlConnection.setConnectTimeout(3000); + urlConnection.setRequestMethod("GET"); + return urlConnection.getResponseCode(); } private SSHClient getFixtureClient() throws IOException {