From 865109d8d4494ff075cd39ba20f60fe7b979edd1 Mon Sep 17 00:00:00 2001 From: Abdelilah El Aissaoui Date: Wed, 20 Sep 2023 15:40:31 +0200 Subject: [PATCH] Added basic error and port handling --- rs/src/gitnuro.udl | 14 +++- rs/src/lib.rs | 22 ++++-- .../gitnuro/credentials/GRemoteSession.kt | 61 ---------------- .../gitnuro/credentials/GSessionManager.kt | 2 +- .../{GProcessLibSsh.kt => SshProcess.kt} | 9 ++- .../gitnuro/credentials/SshRemoteSession.kt | 70 +++++++++++++++++++ .../gitnuro/ssh/libssh/ChannelWrapper.kt | 31 ++++++++ .../jetpackduba/gitnuro/ssh/libssh/Enums.kt | 10 --- .../gitnuro/ssh/libssh/LibSshChannel.kt | 31 -------- ...rStream.kt => SshChannelInputErrStream.kt} | 2 +- ...nputStream.kt => SshChannelInputStream.kt} | 2 +- ...putStream.kt => SshChannelOutputStream.kt} | 2 +- 12 files changed, 135 insertions(+), 121 deletions(-) delete mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt rename src/main/kotlin/com/jetpackduba/gitnuro/credentials/{GProcessLibSsh.kt => SshProcess.kt} (86%) create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/credentials/SshRemoteSession.kt create mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/ChannelWrapper.kt delete mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/Enums.kt delete mode 100644 src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt rename src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/{LibSshChannelInputErrStream.kt => SshChannelInputErrStream.kt} (84%) rename src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/{LibSshChannelInputStream.kt => SshChannelInputStream.kt} (89%) rename src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/{LibSshChannelOutputStream.kt => SshChannelOutputStream.kt} (80%) diff --git a/rs/src/gitnuro.udl b/rs/src/gitnuro.udl index 3f29928..2162f52 100644 --- a/rs/src/gitnuro.udl +++ b/rs/src/gitnuro.udl @@ -19,12 +19,20 @@ interface WatcherInitError { MaxFilesWatch(); }; +enum AuthStatus { + "Success", + "Denied", + "Partial", + "Info", + "Again", +}; + interface Session { constructor(); - void setup(string host, string? user, i32 port); - void public_key_auth(); - void password_auth(string password); + void setup(string host, string? user, u16? port); + AuthStatus public_key_auth(string password); + AuthStatus password_auth(string password); void disconnect(); }; diff --git a/rs/src/lib.rs b/rs/src/lib.rs index 9a93859..cacfd3f 100644 --- a/rs/src/lib.rs +++ b/rs/src/lib.rs @@ -7,9 +7,10 @@ use std::sync::mpsc::{channel, RecvTimeoutError}; use std::sync::{Arc, RwLock}; use std::time::Duration; -use libssh_rs::{PollStatus, SshOption}; +use libssh_rs::{AuthStatus, PollStatus, SshOption}; use notify::{Config, Error, ErrorKind, Event, RecommendedWatcher, RecursiveMode, Watcher}; + uniffi::include_scaffolding!("gitnuro"); const ACCEPTED_SSH_TYPES: &str = "ssh-ed25519,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,rsa-sha2-512,rsa-sha2-256,ssh-dss"; @@ -133,7 +134,7 @@ impl Session { } } - fn setup(&self, host: String, user: Option, port: i32) { + fn setup(&self, host: String, user: Option, port: Option) { let session = self.session.write().unwrap(); session.set_option(SshOption::Hostname(host)).unwrap(); @@ -141,7 +142,7 @@ impl Session { session.set_option(SshOption::User(Some(user))).unwrap(); } - if let Ok(port) = port.try_into() { + if let Some(port) = port { session.set_option(SshOption::Port(port)).unwrap(); } @@ -150,14 +151,21 @@ impl Session { session.connect().unwrap(); } - fn public_key_auth(&self) { + fn public_key_auth(&self, password: String) -> AuthStatus { + println!("Public key auth"); + let session = self.session.write().unwrap(); - session.userauth_public_key_auto(None, Some("")).unwrap(); + + let status = session.userauth_public_key_auto(None, Some(&password)).unwrap(); + + println!("Status is {status:?}"); + + status } - fn password_auth(&self, password: String) { + fn password_auth(&self, password: String) -> AuthStatus { let session = self.session.write().unwrap(); - session.userauth_password(None, Some(&password)).unwrap(); + session.userauth_password(None, Some(&password)).unwrap() } fn disconnect(&self) { diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt deleted file mode 100644 index 292fc9b..0000000 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GRemoteSession.kt +++ /dev/null @@ -1,61 +0,0 @@ -package com.jetpackduba.gitnuro.credentials - -import org.eclipse.jgit.transport.RemoteSession -import org.eclipse.jgit.transport.URIish -import uniffi.gitnuro.Session -import javax.inject.Inject - - -private const val DEFAULT_SSH_PORT = 22 - -class GRemoteSession @Inject constructor( - private val credentialsStateManager: CredentialsStateManager, -) : RemoteSession { - private var session: Session? = null - - override fun exec(commandName: String, timeout: Int): Process { - println("Running command $commandName") - - val session = this.session ?: throw Exception("Session is null") - val process = GProcessLibSsh() - - process.setup(session, commandName) - return process - } - - override fun disconnect() { - session?.disconnect() - } - - fun setup(uri: URIish) { - val session = Session() - session.setup(uri.host, uri.user, uri.port) - - var result = session.publicKeyAuth() - -// if (result == 1) { -// credentialsStateManager.updateState(CredentialsRequested.SshCredentialsRequested) -// -// var credentials = credentialsStateManager.currentCredentialsState -// while (credentials is CredentialsRequested) { -// credentials = credentialsStateManager.currentCredentialsState -// } -// -// val password = if (credentials !is CredentialsAccepted.SshCredentialsAccepted) -// throw CancellationException("Credentials cancelled") -// else -// credentials.password -// -// result = session.userAuthPublicKeyAuto(null, password) -// -// if (result != 0) { -// result = session.userAuthPassword(password) -// } -// } -// -// if (result != 0) -// throw Exception("Something went wrong with authentication. Code $result") - - this.session = session - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GSessionManager.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GSessionManager.kt index c35f06f..c58e5a0 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GSessionManager.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GSessionManager.kt @@ -18,7 +18,7 @@ class GSessionManager @Inject constructor( } class MySessionFactory @Inject constructor( - private val sessionProvider: Provider + private val sessionProvider: Provider ) : SshSessionFactory(), CredentialsCache { override fun getSession( uri: URIish, diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/SshProcess.kt similarity index 86% rename from src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt rename to src/main/kotlin/com/jetpackduba/gitnuro/credentials/SshProcess.kt index 80dba1c..25bbef7 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/GProcessLibSsh.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/SshProcess.kt @@ -1,13 +1,12 @@ package com.jetpackduba.gitnuro.credentials -import com.jetpackduba.gitnuro.ssh.libssh.LibSshChannel -import uniffi.gitnuro.Channel +import com.jetpackduba.gitnuro.ssh.libssh.ChannelWrapper import uniffi.gitnuro.Session import java.io.InputStream import java.io.OutputStream -class GProcessLibSsh : Process() { - private lateinit var channel: LibSshChannel +class SshProcess : Process() { + private lateinit var channel: ChannelWrapper private lateinit var session: Session private val outputStream by lazy { @@ -61,7 +60,7 @@ class GProcessLibSsh : Process() { } fun setup(session: Session, commandName: String) { - val channel = LibSshChannel(session) + val channel = ChannelWrapper(session) channel.openSession() channel.requestExec(commandName) diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/credentials/SshRemoteSession.kt b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/SshRemoteSession.kt new file mode 100644 index 0000000..02219bb --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/credentials/SshRemoteSession.kt @@ -0,0 +1,70 @@ +package com.jetpackduba.gitnuro.credentials + +import org.eclipse.jgit.transport.RemoteSession +import org.eclipse.jgit.transport.URIish +import uniffi.gitnuro.AuthStatus +import uniffi.gitnuro.Session +import java.util.concurrent.CancellationException +import javax.inject.Inject + + +private const val DEFAULT_SSH_PORT = 22 +private const val NOT_EXPLICIT_PORT = -1 + +class SshRemoteSession @Inject constructor( + private val credentialsStateManager: CredentialsStateManager, +) : RemoteSession { + private var session: Session? = null + + override fun exec(commandName: String, timeout: Int): Process { + println("Running command $commandName") + + val session = this.session ?: throw Exception("Session is null") + val process = SshProcess() + + process.setup(session, commandName) + return process + } + + override fun disconnect() { + session?.disconnect() + } + + fun setup(uri: URIish) { + val session = Session() + + val port = if (uri.port == NOT_EXPLICIT_PORT) { + null + } else + uri.port + + session.setup(uri.host, uri.user, port?.toUShort()) + + var result = session.publicKeyAuth("") + + if (result == AuthStatus.DENIED) { + credentialsStateManager.updateState(CredentialsRequested.SshCredentialsRequested) + + var credentials = credentialsStateManager.currentCredentialsState + while (credentials is CredentialsRequested) { + credentials = credentialsStateManager.currentCredentialsState + } + + val password = if (credentials !is CredentialsAccepted.SshCredentialsAccepted) + throw CancellationException("Credentials cancelled") + else + credentials.password + + result = session.publicKeyAuth(password) + + if (result != AuthStatus.SUCCESS) { + result = session.passwordAuth(password) + } + } + + if (result != AuthStatus.SUCCESS) + throw Exception("Something went wrong with authentication. Code $result") + + this.session = session + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/ChannelWrapper.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/ChannelWrapper.kt new file mode 100644 index 0000000..0f7f0c0 --- /dev/null +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/ChannelWrapper.kt @@ -0,0 +1,31 @@ +package com.jetpackduba.gitnuro.ssh.libssh + +import com.jetpackduba.gitnuro.ssh.libssh.streams.SshChannelInputErrStream +import com.jetpackduba.gitnuro.ssh.libssh.streams.SshChannelInputStream +import com.jetpackduba.gitnuro.ssh.libssh.streams.SshChannelOutputStream +import uniffi.gitnuro.Channel +import uniffi.gitnuro.Session + +class ChannelWrapper internal constructor(sshSession: Session) { + private var channel = Channel(sshSession) + + val outputStream = SshChannelOutputStream(channel) + val inputStream = SshChannelInputStream(channel) + val errorOutputStream = SshChannelInputErrStream(channel) + + fun openSession() { + channel.openSession() + } + + fun requestExec(commandName: String) { + channel.requestExec(commandName) + } + + fun isOpen(): Boolean { + return channel.isOpen() + } + + fun close() { + channel.close() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/Enums.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/Enums.kt deleted file mode 100644 index 78f8d31..0000000 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/Enums.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.jetpackduba.gitnuro.ssh.libssh - -enum class sshAuthE(val value: Int) { - SSH_AUTH_SUCCESS(0), - SSH_AUTH_DENIED(1), - SSH_AUTH_PARTIAL(2), - SSH_AUTH_INFO(3), - SSH_AUTH_AGAIN(4), - SSH_AUTH_ERROR(-1) -} \ 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 deleted file mode 100644 index cf60b67..0000000 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/LibSshChannel.kt +++ /dev/null @@ -1,31 +0,0 @@ -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 -import uniffi.gitnuro.Channel -import uniffi.gitnuro.Session - -class LibSshChannel internal constructor(sshSession: Session) { - private var channel = Channel(sshSession) - - val outputStream = LibSshChannelOutputStream(channel) - val inputStream = LibSshChannelInputStream(channel) - val errorOutputStream = LibSshChannelInputErrStream(channel) - - fun openSession() { - channel.openSession() - } - - fun requestExec(commandName: String) { - channel.requestExec(commandName) - } - - fun isOpen(): Boolean { - return channel.isOpen() - } - - fun close() { - channel.close() - } -} \ 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/SshChannelInputErrStream.kt similarity index 84% rename from src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt rename to src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/SshChannelInputErrStream.kt index 49b4ebb..89f1d53 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputErrStream.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/SshChannelInputErrStream.kt @@ -3,7 +3,7 @@ package com.jetpackduba.gitnuro.ssh.libssh.streams import uniffi.gitnuro.Channel import java.io.InputStream -class LibSshChannelInputErrStream(private val sshChannel: Channel) : InputStream() { +class SshChannelInputErrStream(private val sshChannel: Channel) : InputStream() { private var cancelled = false override fun read(): Int { diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/SshChannelInputStream.kt similarity index 89% rename from src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt rename to src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/SshChannelInputStream.kt index 5af2833..2404f2b 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelInputStream.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/SshChannelInputStream.kt @@ -3,7 +3,7 @@ package com.jetpackduba.gitnuro.ssh.libssh.streams import uniffi.gitnuro.Channel import java.io.InputStream -class LibSshChannelInputStream(private val sshChannel: Channel) : InputStream() { +class SshChannelInputStream(private val sshChannel: Channel) : InputStream() { override fun read(b: ByteArray, off: Int, len: Int): Int { val result = sshChannel.read(false, len.toULong()) val byteArray = result.data diff --git a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/SshChannelOutputStream.kt similarity index 80% rename from src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt rename to src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/SshChannelOutputStream.kt index 9293c9c..04b8fa0 100644 --- a/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/LibSshChannelOutputStream.kt +++ b/src/main/kotlin/com/jetpackduba/gitnuro/ssh/libssh/streams/SshChannelOutputStream.kt @@ -3,7 +3,7 @@ package com.jetpackduba.gitnuro.ssh.libssh.streams import uniffi.gitnuro.Channel import java.io.OutputStream -class LibSshChannelOutputStream(private val sshChannel: Channel) : OutputStream() { +class SshChannelOutputStream(private val sshChannel: Channel) : OutputStream() { override fun write(b: Int) { val byteArrayData = byteArrayOf(b.toByte()) write(byteArrayData)