Skip to content

Instantly share code, notes, and snippets.

@dacr
Last active April 2, 2023 10:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacr/4403cb3b8809cf256226a4a4b33e2ae2 to your computer and use it in GitHub Desktop.
Save dacr/4403cb3b8809cf256226a4a4b33e2ae2 to your computer and use it in GitHub Desktop.
SSH server and client operations both within a single script using apache sshd. / published by https://github.com/dacr/code-examples-manager #a267b427-a378-445c-b91e-e26ddf889c72/b17ef5468391cc1fba96d19d13fc37730a7a662f
// summary : SSH server and client operations both within a single script using apache sshd.
// keywords : scala, ssh, client, server, apache-sshd, mina, @testable
// publish : gist
// authors : David Crosson
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : a267b427-a378-445c-b91e-e26ddf889c72
// created-on : 2018-07-02T19:35:49Z
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file
// ---------------------
//> using scala "3.1.1"
//> using dep "org.apache.sshd:sshd-core:2.8.0"
//> using dep "org.apache.sshd:sshd-sftp:2.8.0"
//> using dep "org.apache.sshd:sshd-scp:2.8.0"
//> using dep "org.slf4j:slf4j-simple:1.7.32"
// ---------------------
import java.util.concurrent.TimeUnit
import org.apache.sshd.client.SshClient
import org.apache.sshd.common.channel.Channel
import org.apache.sshd.server.SshServer
import org.apache.sshd.server.auth.password.PasswordAuthenticator
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider
import org.apache.sshd.server.session.ServerSession
import java.io.OutputStreamWriter
import org.apache.sshd.client.channel.{ClientChannel, ClientChannelEvent}
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import org.apache.sshd.server.shell.ProcessShellFactory
// Everything in a object as soon as we have to deal with futures, promises, asynchronous operations
//
object Main {
val sshHost = "localhost"
val sshPort = 2222
val testUsername = "test"
val testPassword = "test"
def go:Unit = {
println("Starting operations")
val sshd = SshServer.setUpDefaultServer
sshd.setHost(sshHost)
sshd.setPort(sshPort)
// first command is the "unparsed one"
sshd.setShellFactory(new ProcessShellFactory("/bin/cat", "/bin/cat")) // TODO Take care not always installed at this place
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider())
sshd.setPasswordAuthenticator(new PasswordAuthenticator {
override def authenticate(username: String, password: String, serverSession: ServerSession): Boolean = {
username==testUsername && password == testPassword
}
})
sshd.start()
val ssh = SshClient.setUpDefaultClient()
ssh.start()
val session = ssh.connect(testUsername, sshHost, sshPort).verify(5, TimeUnit.SECONDS).getSession
session.addPasswordIdentity(testPassword)
session.auth.verify(5, TimeUnit.SECONDS)
val channel:ClientChannel = session.createChannel(Channel.CHANNEL_SHELL)
val baos = new ByteArrayOutputStream
val w = new OutputStreamWriter(baos)
w.write("Hello world")
//w.flush()
w.close()
channel.setIn(new ByteArrayInputStream(baos.toByteArray))
val out: ByteArrayOutputStream = new ByteArrayOutputStream
val err: ByteArrayOutputStream = new ByteArrayOutputStream
channel.setOut(out)
channel.setErr(err)
channel.open
channel.waitFor(java.util.Arrays.asList(ClientChannelEvent.CLOSED), 0)
val result: String = out.toString.trim
println(s"-->'$result'") // should print 'id' if the current os has an available "/bin/cat" command
assert(result == "Hello world")
sshd.stop()
}
}
Main.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment