Organized libssh code
This commit is contained in:
parent
944f4e9955
commit
193755454e
@ -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
|
||||
|
@ -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<GProcess>,
|
||||
private val processSession: Provider<LibSshSession>,
|
||||
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")
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user