diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml
index e02f766141..202b3b8763 100644
--- a/libraries-security/pom.xml
+++ b/libraries-security/pom.xml
@@ -14,29 +14,24 @@
-
org.springframework.boot
spring-boot-starter-web
-
org.springframework.security.oauth
spring-security-oauth2
${spring-boot.version}
-
org.springframework
spring-web
-
com.github.scribejava
scribejava-apis
${scribejava.version}
-
com.google.crypto.tink
tink
@@ -72,6 +67,16 @@
jasypt
${jasypt.version}
+
+ com.jcraft
+ jsch
+ ${jsch.version}
+
+
+ org.apache.sshd
+ sshd-core
+ ${apache-mina.version}
+
@@ -81,6 +86,8 @@
1.2.2
1.9.2
1.58
+ 0.1.55
+ 2.5.1
diff --git a/libraries-security/src/main/java/com/baeldung/ssh/apachesshd/SshdDemo.java b/libraries-security/src/main/java/com/baeldung/ssh/apachesshd/SshdDemo.java
new file mode 100644
index 0000000000..05d8034040
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/ssh/apachesshd/SshdDemo.java
@@ -0,0 +1,64 @@
+package com.baeldung.ssh.apachesshd;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.util.EnumSet;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.client.SshClient;
+import org.apache.sshd.client.channel.ClientChannel;
+import org.apache.sshd.client.channel.ClientChannelEvent;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.channel.Channel;
+
+public class SshdDemo {
+
+ public static void main(String[] args) throws Exception {
+ String username = "demo";
+ String password = "password";
+ String host = "test.rebex.net";
+ int port = 22;
+ long defaultTimeoutSeconds = 10l;
+ String command = "ls\n";
+
+ listFolderStructure(username, password, host, port, defaultTimeoutSeconds, command);
+ }
+
+ public static String listFolderStructure(String username, String password, String host, int port, long defaultTimeoutSeconds, String command) throws Exception {
+ SshClient client = SshClient.setUpDefaultClient();
+ client.start();
+ try (ClientSession session = client.connect(username, host, port)
+ .verify(defaultTimeoutSeconds, TimeUnit.SECONDS)
+ .getSession()) {
+ session.addPasswordIdentity(password);
+ session.auth()
+ .verify(5L, TimeUnit.SECONDS);
+ try (ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
+ ByteArrayOutputStream errorResponseStream = new ByteArrayOutputStream();
+ ClientChannel channel = session.createChannel(Channel.CHANNEL_SHELL)) {
+ channel.setOut(responseStream);
+ channel.setErr(errorResponseStream);
+ try {
+ channel.open()
+ .verify(defaultTimeoutSeconds, TimeUnit.SECONDS);
+ try (OutputStream pipedIn = channel.getInvertedIn()) {
+ pipedIn.write(command.getBytes());
+ pipedIn.flush();
+ }
+ channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), TimeUnit.SECONDS.toMillis(defaultTimeoutSeconds));
+ String errorString = new String(errorResponseStream.toByteArray());
+ if(!errorString.isEmpty()) {
+ throw new Exception(errorString);
+ }
+ String responseString = new String(responseStream.toByteArray());
+ return responseString;
+ } finally {
+ channel.close(false);
+ }
+ }
+ } finally {
+ client.stop();
+ }
+ }
+
+}
diff --git a/libraries-security/src/main/java/com/baeldung/ssh/jsch/JschDemo.java b/libraries-security/src/main/java/com/baeldung/ssh/jsch/JschDemo.java
new file mode 100644
index 0000000000..34a40318bb
--- /dev/null
+++ b/libraries-security/src/main/java/com/baeldung/ssh/jsch/JschDemo.java
@@ -0,0 +1,52 @@
+package com.baeldung.ssh.jsch;
+
+import java.io.ByteArrayOutputStream;
+
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.Session;
+
+public class JschDemo {
+
+ public static void main(String args[]) throws Exception {
+ String username = "demo";
+ String password = "password";
+ String host = "test.rebex.net";
+ int port = 22;
+ String command = "ls";
+ listFolderStructure(username, password, host, port, command);
+ }
+
+ public static String listFolderStructure(String username, String password, String host, int port, String command) throws Exception {
+ Session session = null;
+ ChannelExec channel = null;
+ String response = null;
+ try {
+ session = new JSch().getSession(username, host, port);
+ session.setPassword(password);
+ session.setConfig("StrictHostKeyChecking", "no");
+ session.connect();
+ channel = (ChannelExec) session.openChannel("exec");
+ channel.setCommand(command);
+ ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
+ ByteArrayOutputStream errorResponseStream = new ByteArrayOutputStream();
+ channel.setOutputStream(responseStream);
+ channel.setErrStream(errorResponseStream);
+ channel.connect();
+ while (channel.isConnected()) {
+ Thread.sleep(100);
+ }
+ String errorResponse = new String(errorResponseStream.toByteArray());
+ response = new String(responseStream.toByteArray());
+ if(!errorResponse.isEmpty()) {
+ throw new Exception(errorResponse);
+ }
+ } finally {
+ if (session != null)
+ session.disconnect();
+ if (channel != null)
+ channel.disconnect();
+ }
+ return response;
+ }
+}
diff --git a/libraries-security/src/test/java/com/baeldung/ssh/ApacheMinaSshdLiveTest.java b/libraries-security/src/test/java/com/baeldung/ssh/ApacheMinaSshdLiveTest.java
new file mode 100644
index 0000000000..3cefca05cb
--- /dev/null
+++ b/libraries-security/src/test/java/com/baeldung/ssh/ApacheMinaSshdLiveTest.java
@@ -0,0 +1,38 @@
+package com.baeldung.ssh;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+import com.baeldung.ssh.apachesshd.SshdDemo;
+
+public class ApacheMinaSshdLiveTest {
+
+ @Test
+ public void givenValidCredentials_whenConnectionIsEstablished_thenServerReturnsResponse() throws Exception {
+ String username = "demo";
+ String password = "password";
+ String host = "test.rebex.net";
+ int port = 22;
+ long defaultTimeoutSeconds = 10l;
+ String command = "ls\n";
+ String responseString = SshdDemo.listFolderStructure(username, password, host, port, defaultTimeoutSeconds, command);
+
+ assertNotNull(responseString);
+ }
+
+ @Test(expected = Exception.class)
+ public void givenInvalidCredentials_whenConnectionAttemptIsMade_thenServerReturnsErrorResponse() throws Exception {
+ String username = "invalidUsername";
+ String password = "password";
+ String host = "test.rebex.net";
+ int port = 22;
+ long defaultTimeoutSeconds = 10l;
+ String command = "ls\n";
+ String responseString = SshdDemo.listFolderStructure(username, password, host, port, defaultTimeoutSeconds, command);
+
+ assertNull(responseString);
+ }
+
+}
diff --git a/libraries-security/src/test/java/com/baeldung/ssh/JSchLiveTest.java b/libraries-security/src/test/java/com/baeldung/ssh/JSchLiveTest.java
new file mode 100644
index 0000000000..c95c3c319c
--- /dev/null
+++ b/libraries-security/src/test/java/com/baeldung/ssh/JSchLiveTest.java
@@ -0,0 +1,35 @@
+package com.baeldung.ssh;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+import com.baeldung.ssh.jsch.JschDemo;
+
+public class JSchLiveTest {
+
+ @Test
+ public void givenValidCredentials_whenConnectionIsEstablished_thenServerReturnsResponse() throws Exception {
+ String username = "demo";
+ String password = "password";
+ String host = "test.rebex.net";
+ int port = 22;
+ String command = "ls";
+ String responseString = JschDemo.listFolderStructure(username, password, host, port, command);
+
+ assertNotNull(responseString);
+ }
+
+ @Test(expected = Exception.class)
+ public void givenInvalidCredentials_whenConnectionAttemptIsMade_thenServerReturnsErrorResponse() throws Exception {
+ String username = "invalidUsername";
+ String password = "password";
+ String host = "test.rebex.net";
+ int port = 22;
+ String command = "ls";
+ String responseString = JschDemo.listFolderStructure(username, password, host, port, command);
+
+ assertNull(responseString);
+ }
+}