From 193755454efed6fb40dac7a0fd329d42f602941f Mon Sep 17 00:00:00 2001 From: Abdelilah El Aissaoui Date: Sat, 24 Dec 2022 03:23:43 +0100 Subject: [PATCH] Organized libssh code --- .../gitnuro/credentials/GProcessLibSsh.kt | 33 ++++----- .../gitnuro/credentials/GRemoteSession.kt | 73 +++---------------- .../gitnuro/credentials/streams/Convertest.kt | 10 --- .../streams/LibSshInputErrStream.kt | 65 ----------------- .../gitnuro/ssh/libssh/LibSshChannel.kt | 32 ++++++++ .../gitnuro/ssh/libssh/LibSshOptions.kt | 50 +++++++++++++ .../gitnuro/ssh/libssh/LibSshSession.kt | 38 ++++++++++ .../libssh}/LibSshWrapper.kt | 7 +- .../streams/LibSshChannelInputErrStream.kt | 33 +++++++++ .../streams/LibSshChannelInputStream.kt} | 16 ++-- .../streams/LibSshChannelOutputStream.kt} | 11 +-- 11 files changed, 193 insertions(+), 175 deletions(-) delete mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/Convertest.kt delete mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshInputErrStream.kt create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshOptions.kt create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshSession.kt rename src/main/kotlin/com/jetpackduba/gitnuro/{credentials => ssh/libssh}/LibSshWrapper.kt (95%) create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt rename src/main/kotlin/com/jetpackduba/gitnuro/{credentials/streams/LibSshInputStream.kt => ssh/libssh/streams/LibSshChannelInputStream.kt} (59%) rename src/main/kotlin/com/jetpackduba/gitnuro/{credentials/streams/LibSshOutputStream.kt => ssh/libssh/streams/LibSshChannelOutputStream.kt} (65%) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt index 8862dbb..188d3ea 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt @@ -1,24 +1,21 @@ package com.jetpackduba.gitnuro.credentials -import com.jetpackduba.gitnuro.credentials.streams.LibSshInputErrStream -import com.jetpackduba.gitnuro.credentials.streams.LibSshInputStream -import com.jetpackduba.gitnuro.credentials.streams.LibSshOutputStream -import com.jetpackduba.gitnuro.credentials.streams.checkValidResult +import com.jetpackduba.gitnuro.ssh.libssh.* import java.io.InputStream import java.io.OutputStream class GProcessLibSsh : Process() { - private lateinit var channel: ssh_channel - private lateinit var session: ssh_session + private lateinit var channel: LibSshChannel + private lateinit var session: LibSshSession private val outputStream by lazy { - LibSshOutputStream(channel) + channel.outputStream } private val inputStream by lazy { - LibSshInputStream(channel) + channel.inputStream } private val errorOutputStream by lazy { - LibSshInputErrStream(channel) + channel.errorOutputStream } override fun getOutputStream(): OutputStream { @@ -44,27 +41,27 @@ class GProcessLibSsh : Process() { check(!isRunning()) println("exitValue called") - return sshLib.ssh_channel_close(channel) + return channel.close() } override fun destroy() { - if (sshLib.ssh_channel_is_open(channel) == 1) { - checkValidResult(sshLib.ssh_channel_close(channel)) + if (channel.isOpen()) { + channel.close() } - sshLib.ssh_disconnect(session) + session.disconnect() println("Destroy called") } private fun isRunning(): Boolean { - return sshLib.ssh_channel_is_open(channel) == 1 + return channel.isOpen() } - fun setup(session: ssh_session, commandName: String) { - val channel = sshLib.ssh_channel_new(session) + fun setup(session: LibSshSession, commandName: String) { + val channel = session.createChannel() - checkValidResult(sshLib.ssh_channel_open_session(channel)) - checkValidResult(sshLib.ssh_channel_request_exec(channel, commandName)) + channel.openSession() + channel.requestExec(commandName) this.session = session this.channel = channel diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt index ee3dcc8..7a9c6fd 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt @@ -1,12 +1,11 @@ package com.jetpackduba.gitnuro.credentials +import com.jetpackduba.gitnuro.ssh.libssh.LibSshOptions +import com.jetpackduba.gitnuro.ssh.libssh.LibSshSession import org.apache.sshd.client.SshClient import org.apache.sshd.client.future.ConnectFuture -import org.apache.sshd.client.session.ClientSession -import org.apache.sshd.common.config.keys.FilePasswordProvider import org.eclipse.jgit.transport.RemoteSession import org.eclipse.jgit.transport.URIish -import java.time.Duration import javax.inject.Inject import javax.inject.Provider @@ -15,33 +14,18 @@ private const val DEFAULT_SSH_PORT = 22 class GRemoteSession @Inject constructor( private val processProvider: Provider, + private val processSession: Provider, private val credentialsStateManager: CredentialsStateManager, ) : RemoteSession { private val client = SshClient.setUpDefaultClient() private var connectFuture: ConnectFuture? = null - private var ssh_session: ssh_session? = null + private var session: LibSshSession? = null override fun exec(commandName: String, timeout: Int): Process { - println(commandName) -// val session = connectFuture!!.clientSession -// -// val auth = session.auth() -// auth.addListener { arg0 -> -// println("Authentication completed with " + if (arg0.isSuccess) "success" else "failure") -// } -// -// session.waitFor( -// listOf( -// ClientSession.ClientSessionEvent.WAIT_AUTH, -// ClientSession.ClientSessionEvent.CLOSED, -// ClientSession.ClientSessionEvent.AUTHED -// ), Duration.ofHours(2) -// ) -// auth.verify() -// val process = processProvider.get() + println("Running command $commandName") - val session = this.ssh_session ?: throw Exception("Session is null") + val session = this.session ?: throw Exception("Session is null") val process = GProcessLibSsh() process.setup(session, commandName) @@ -54,46 +38,11 @@ class GRemoteSession @Inject constructor( } fun setup(uri: URIish) { + val session = processSession.get() + session.setOptions(LibSshOptions.SSH_OPTIONS_HOST, uri.host) + session.connect() + session.userAuthPublicKeyAuto(uri.user, null) - val session = sshLib.ssh_new() - sshLib.ssh_options_set(session, 0, uri.host) - sshLib.ssh_connect(session) - checkValidResult(sshLib.ssh_userauth_publickey_auto(session, uri.user, null)) - - this.ssh_session = session - -// client.open() -// -// val port = if (uri.port == -1) { -// DEFAULT_SSH_PORT -// } else -// uri.port -// -// val filePasswordProvider = -// FilePasswordProvider { _, _, _ -> -// credentialsStateManager.updateState(CredentialsState.SshCredentialsRequested) -// -// var credentials = credentialsStateManager.currentCredentialsState -// while (credentials is CredentialsState.CredentialsRequested) { -// credentials = credentialsStateManager.currentCredentialsState -// } -// -// if (credentials !is CredentialsState.SshCredentialsAccepted) -// null -// else -// credentials.password -// } -// -// client.filePasswordProvider = filePasswordProvider -// -// val connectFuture = client.connect(uri.user, uri.host, port) -// connectFuture.await() -// -// this.connectFuture = connectFuture + this.session = session } -} - -fun checkValidResult(result: Int) { - if (result != 0) - throw Exception("Result is $result") } \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/Convertest.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/Convertest.kt deleted file mode 100644 index 3d1742f..0000000 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/Convertest.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.jetpackduba.gitnuro.credentials.streams - -class Convertest { - companion object { - fun printIt(byteArray: ByteArray) { - val intList = byteArray.map { it.toInt() } - println(intList) - } - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshInputErrStream.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshInputErrStream.kt deleted file mode 100644 index 534dfd5..0000000 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshInputErrStream.kt +++ /dev/null @@ -1,65 +0,0 @@ -package com.jetpackduba.gitnuro.credentials.streams - -import com.jetpackduba.gitnuro.credentials.sshLib -import com.jetpackduba.gitnuro.credentials.ssh_channel -import java.io.InputStream - - -class LibSshInputErrStream(private val sshChannel: ssh_channel) : InputStream() { - private var cancelled = false - private var calls = 0 - -// override fun read(b: ByteArray, off: Int, len: Int): Int { -// return sshLib.ssh_channel_read(sshChannel, b, len, 1) -// } - - override fun read(): Int { - println("Read error") - val buffer = ByteArray(1) - - return if (sshLib.ssh_channel_poll(sshChannel, 1) > 0) { - sshLib.ssh_channel_read(sshChannel, buffer, 1, 1) - - val first = buffer.first() - println("Read error finished ${first.toInt()}") - - print(String(buffer)) - - first.toInt() - } else - -1 - } - -// override fun read(b: ByteArray, off: Int, len: Int): Int { -// calls++ -// -// println("Read error started, call $calls for len of $len with offset $off") -// -// val byteArray = ByteArray(len) -// val result = sshLib.ssh_channel_read(sshChannel, byteArray, len, 1) -// for(i in 0 until len) { -// b[off + i] = byteArray[i] -// } -// -// println("Read ended ${byteArray.map { it.toInt() }}") -// -// return result -// } -// -// override fun read(): Int { -// val buffer = ByteArray(1) -// -// sshLib.ssh_channel_read(sshChannel, buffer, 1, 1) -// -// val first = buffer.first() -// -// println("Error message is ${String(buffer)}") -// -// return first.toInt() -// } - - override fun close() { - println("Closing error") - cancelled = true - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt new file mode 100644 index 0000000..97c6a94 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt @@ -0,0 +1,32 @@ +package com.jetpackduba.gitnuro.ssh.libssh + +import com.jetpackduba.gitnuro.ssh.libssh.streams.LibSshChannelInputErrStream +import com.jetpackduba.gitnuro.ssh.libssh.streams.LibSshChannelInputStream +import com.jetpackduba.gitnuro.ssh.libssh.streams.LibSshChannelOutputStream + +class LibSshChannel internal constructor(sshSession: ssh_session) { + private val sshLib = SSHLibrary.INSTANCE + private var channel: ssh_channel = sshLib.ssh_channel_new(sshSession) + + val outputStream = LibSshChannelOutputStream(channel) + val inputStream = LibSshChannelInputStream(channel) + val errorOutputStream = LibSshChannelInputErrStream(channel) + + + fun openSession() { + sshLib.ssh_channel_open_session(channel) + } + + fun requestExec(commandName: String) { + sshLib.ssh_channel_request_exec(channel, commandName) + } + + fun isOpen(): Boolean { + return sshLib.ssh_channel_is_open(channel) == 1 + } + + fun close(): Int { + return sshLib.ssh_channel_close(channel) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshOptions.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshOptions.kt new file mode 100644 index 0000000..f98ed13 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshOptions.kt @@ -0,0 +1,50 @@ +package com.jetpackduba.gitnuro.ssh.libssh + +/** + * Enum based on the enum "ssh_options_e" of libssh/libssh.h + */ +enum class LibSshOptions { + SSH_OPTIONS_HOST, + SSH_OPTIONS_PORT, + SSH_OPTIONS_PORT_STR, + SSH_OPTIONS_FD, + SSH_OPTIONS_USER, + SSH_OPTIONS_SSH_DIR, + SSH_OPTIONS_IDENTITY, + SSH_OPTIONS_ADD_IDENTITY, + SSH_OPTIONS_KNOWNHOSTS, + SSH_OPTIONS_TIMEOUT, + SSH_OPTIONS_TIMEOUT_USEC, + SSH_OPTIONS_SSH1, + SSH_OPTIONS_SSH2, + SSH_OPTIONS_LOG_VERBOSITY, + SSH_OPTIONS_LOG_VERBOSITY_STR, + SSH_OPTIONS_CIPHERS_C_S, + SSH_OPTIONS_CIPHERS_S_C, + SSH_OPTIONS_COMPRESSION_C_S, + SSH_OPTIONS_COMPRESSION_S_C, + SSH_OPTIONS_PROXYCOMMAND, + SSH_OPTIONS_BINDADDR, + SSH_OPTIONS_STRICTHOSTKEYCHECK, + SSH_OPTIONS_COMPRESSION, + SSH_OPTIONS_COMPRESSION_LEVEL, + SSH_OPTIONS_KEY_EXCHANGE, + SSH_OPTIONS_HOSTKEYS, + SSH_OPTIONS_GSSAPI_SERVER_IDENTITY, + SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY, + SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS, + SSH_OPTIONS_HMAC_C_S, + SSH_OPTIONS_HMAC_S_C, + SSH_OPTIONS_PASSWORD_AUTH, + SSH_OPTIONS_PUBKEY_AUTH, + SSH_OPTIONS_KBDINT_AUTH, + SSH_OPTIONS_GSSAPI_AUTH, + SSH_OPTIONS_GLOBAL_KNOWNHOSTS, + SSH_OPTIONS_NODELAY, + SSH_OPTIONS_PUBLICKEY_ACCEPTED_TYPES, + SSH_OPTIONS_PROCESS_CONFIG, + SSH_OPTIONS_REKEY_DATA, + SSH_OPTIONS_REKEY_TIME, + SSH_OPTIONS_RSA_MIN_SIZE, + SSH_OPTIONS_IDENTITY_AGENT +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshSession.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshSession.kt new file mode 100644 index 0000000..282aa63 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshSession.kt @@ -0,0 +1,38 @@ +package com.jetpackduba.gitnuro.ssh.libssh + +import javax.inject.Inject + +class LibSshSession @Inject constructor() { + private val sshLib = SSHLibrary.INSTANCE + + private var session: ssh_session = sshLib.ssh_new() + private var channel: LibSshChannel? = null + + + fun setOptions(option: LibSshOptions, value: String) { + sshLib.ssh_options_set(session, option.ordinal, value) + } + + fun connect() { + sshLib.ssh_connect(session) + } + + + + fun userAuthPublicKeyAuto(username: String?, password: String?) { + sshLib.ssh_userauth_publickey_auto(session, username, password) + } + + fun createChannel(): LibSshChannel { + val newChannel = LibSshChannel(session) + + this.channel = newChannel + + return newChannel + } + + fun disconnect() { + sshLib.ssh_disconnect(session) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/LibSshWrapper.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshWrapper.kt similarity index 95% rename from src/main/kotlin/com/jetpackduba/gitnuro/credentials/LibSshWrapper.kt rename to src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshWrapper.kt index 17d07ce..fdd5ea6 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/LibSshWrapper.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshWrapper.kt @@ -1,4 +1,4 @@ -package com.jetpackduba.gitnuro.credentials +package com.jetpackduba.gitnuro.ssh.libssh import com.sun.jna.Library import com.sun.jna.Native @@ -7,6 +7,7 @@ import com.sun.jna.PointerType class ssh_session : PointerType() class ssh_channel : PointerType() +@Suppress("FunctionName") interface SSHLibrary : Library { fun ssh_new(): ssh_session fun ssh_disconnect(session: ssh_session): ssh_session @@ -42,6 +43,4 @@ interface SSHLibrary : Library { SSHLibrary::class.java ) as SSHLibrary } -} - -val sshLib = SSHLibrary.INSTANCE \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt new file mode 100644 index 0000000..500b965 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt @@ -0,0 +1,33 @@ +package com.jetpackduba.gitnuro.ssh.libssh.streams + +import com.jetpackduba.gitnuro.ssh.libssh.SSHLibrary +import com.jetpackduba.gitnuro.ssh.libssh.ssh_channel +import java.io.InputStream + + +class LibSshChannelInputErrStream(private val sshChannel: ssh_channel) : InputStream() { + private var cancelled = false + private val sshLib = SSHLibrary.INSTANCE + + override fun read(): Int { + println("Read error") + val buffer = ByteArray(1) + + return if (sshLib.ssh_channel_poll(sshChannel, 1) > 0) { + sshLib.ssh_channel_read(sshChannel, buffer, 1, 1) + + val first = buffer.first() + println("Read error finished ${first.toInt()}") + + print(String(buffer)) + + first.toInt() + } else + -1 + } + + override fun close() { + println("Closing error") + cancelled = true + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshInputStream.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt similarity index 59% rename from src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshInputStream.kt rename to src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt index fec56a9..8c65dc7 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshInputStream.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt @@ -1,26 +1,20 @@ -package com.jetpackduba.gitnuro.credentials.streams +package com.jetpackduba.gitnuro.ssh.libssh.streams -import com.jetpackduba.gitnuro.credentials.sshLib -import com.jetpackduba.gitnuro.credentials.ssh_channel +import com.jetpackduba.gitnuro.ssh.libssh.SSHLibrary +import com.jetpackduba.gitnuro.ssh.libssh.ssh_channel import java.io.InputStream -class LibSshInputStream(private val sshChannel: ssh_channel) : InputStream() { - private var calls = 0 +class LibSshChannelInputStream(private val sshChannel: ssh_channel) : InputStream() { + private val sshLib = SSHLibrary.INSTANCE override fun read(b: ByteArray, off: Int, len: Int): Int { - calls++ - - println("Read started, call $calls for len of $len with offset $off") - val byteArray = ByteArray(len) val result = sshLib.ssh_channel_read(sshChannel, byteArray, len, 0) for(i in 0 until len) { b[off + i] = byteArray[i] } - println("Read ended ${byteArray.map { it.toInt() }}") - return result } diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshOutputStream.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt similarity index 65% rename from src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshOutputStream.kt rename to src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt index bc0e17c..31b4f8e 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/streams/LibSshOutputStream.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt @@ -1,11 +1,12 @@ -package com.jetpackduba.gitnuro.credentials.streams +package com.jetpackduba.gitnuro.ssh.libssh.streams -import com.jetpackduba.gitnuro.credentials.sshLib -import com.jetpackduba.gitnuro.credentials.ssh_channel +import com.jetpackduba.gitnuro.ssh.libssh.SSHLibrary +import com.jetpackduba.gitnuro.ssh.libssh.ssh_channel import java.io.OutputStream -import java.nio.ByteBuffer -class LibSshOutputStream(private val sshChannel: ssh_channel) : OutputStream() { +class LibSshChannelOutputStream(private val sshChannel: ssh_channel) : OutputStream() { + private val sshLib = SSHLibrary.INSTANCE + override fun write(b: Int) { println("write int")