build: replaced libssh with russh for remotefs-ssh

This commit is contained in:
Christian Visintin
2026-03-20 22:56:23 +01:00
parent 53502e722a
commit 52dd762872
12 changed files with 1414 additions and 167 deletions

View File

@@ -138,7 +138,7 @@ Let's make it simple and clear:
In addition to the process described for the PRs, I've also decided to introduce a list of guidelines to follow when writing the code, that should be followed:
1. **Let's stop the NPM apocalypse**: personally I'm against the abuse of dependencies we make in software projects and I think that NodeJS has opened the way to this drama (and has already gone too far). Nowadays nobody cares about adding hundreds of dependencies to their projects. Don't misunderstand me: I think that package managers are cool, but I'm totally against the abuse we're making of them. I think when we work on a project, we should try to use the minor quantity of dependencies as possible, especially because it's not hard to see how many libraries are getting abandoned right now, causing compatibility issues after a while. So please, when working on termscp, try not to add useless dependencies.
2. **No C-bindings**: personally I think that Rust still relies too much on C. And that's bad, really bad. Many libraries in Rust are just wrappers to C libraries, which is a huge problem, especially considering this is a multiplatform project. Everytime you add a C-binding to your project, you're forcing your users to install additional libraries to their systems. Sometimes these libraries are already installed on their systems (as happens for libssh2 or openssl in this case), but sometimes not. So if you really have to add a dependency to this project, please AVOID completely adding C-bounded libraries.
2. **No C-bindings**: personally I think that Rust still relies too much on C. And that's bad, really bad. Many libraries in Rust are just wrappers to C libraries, which is a huge problem, especially considering this is a multiplatform project. Everytime you add a C-binding to your project, you're forcing your users to install additional libraries to their systems. Sometimes these libraries are already installed on their systems (as happens for openssl in this case), but sometimes not. So if you really have to add a dependency to this project, please AVOID completely adding C-bounded libraries.
3. **Test units matter**: Whenever you implement something new to this project, always implement test units which cover the most cases as possible.
4. **Comments are useful**: Many people say that the code should be that simple to talk by itself about what it does, and comments should then be useless. I personally don't agree. I'm not saying they're wrong, but I'm just saying that this approach has, in my personal opinion, many aspects which are underrated:
1. What's obvious for me, might not be for the others.

1506
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -57,15 +57,16 @@ notify = "8"
notify-rust = { version = "^4", default-features = false, features = ["d"] }
nucleo = "0.5"
open = "5"
rand = "0.10"
rand = "0.9"
regex = "^1"
remotefs = "^0.3"
remotefs-aws-s3 = "0.4"
remotefs-kube = "0.4"
remotefs-smb = { version = "^0.3", optional = true }
remotefs-ssh = { version = "0.8", default-features = false, features = ["russh"] }
remotefs-webdav = "^0.2"
rpassword = "^7"
self_update = { version = "^0.42", default-features = false, features = [
self_update = { version = "0.42", default-features = false, features = [
"rustls",
"archive-tar",
"archive-zip",
@@ -93,15 +94,10 @@ remotefs-ftp = { version = "^0.4", features = [
"native-tls-vendored",
"native-tls",
] }
remotefs-ssh = { version = "^0.7", default-features = false, features = [
"find",
"libssh-vendored",
] }
uzers = "0.12"
[target."cfg(target_family = \"windows\")".dependencies]
remotefs-ftp = { version = "^0.4", features = ["native-tls"] }
remotefs-ssh = { version = "^0.7" }
[dev-dependencies]
pretty_assertions = "^1"

View File

@@ -43,7 +43,6 @@ www: \"https://termscp.veeso.dev/termscp/\"\n\
maintainer: \"christian.visintin1997@gmail.com\"\n\
prefix: \"/usr/local/bin\"\n\
deps: {\n\
libssh: {origin: security/libssh, version: 0.9.5}\n\
}\n\
files: {\n\
/usr/local/bin/termscp: \"$HASH\"\n\

View File

@@ -193,12 +193,10 @@ Für weitere Informationen oder andere Plattformen besuchen Sie bitte [termscp.v
### Softwareanforderungen ❗
- **Linux** Benutzer:
- libssh
- libdbus-1
- pkg-config
- libsmbclient
- **FreeBSD** Benutzer:
- libssh
- dbus
- pkgconf
- libsmbclient
@@ -265,7 +263,7 @@ termscp wird von diesen großartigen Projekten unterstützt:
- [rpassword](https://github.com/conradkleinespel/rpassword)
- [rust-s3](https://github.com/durch/rust-s3)
- [self_update](https://github.com/jaemk/self_update)
- [ssh2-rs](https://github.com/alexcrichton/ssh2-rs)
- [russh](https://github.com/Eugeny/russh)
- [suppaftp](https://github.com/veeso/suppaftp)
- [ratatui](https://github.com/ratatui-org/ratatui)
- [tui-realm](https://github.com/veeso/tui-realm)

View File

@@ -263,7 +263,7 @@ termscp funciona con estos increíbles proyectos:
- [rpassword](https://github.com/conradkleinespel/rpassword)
- [rust-s3](https://github.com/durch/rust-s3)
- [self_update](https://github.com/jaemk/self_update)
- [ssh2-rs](https://github.com/alexcrichton/ssh2-rs)
- [russh](https://github.com/Eugeny/russh)
- [suppaftp](https://github.com/veeso/suppaftp)
- [ratatui](https://github.com/ratatui-org/ratatui)
- [tui-realm](https://github.com/veeso/tui-realm)

View File

@@ -265,7 +265,7 @@ termscp est soutenu par ces projets impressionnants:
- [rpassword](https://github.com/conradkleinespel/rpassword)
- [rust-s3](https://github.com/durch/rust-s3)
- [self_update](https://github.com/jaemk/self_update)
- [ssh2-rs](https://github.com/alexcrichton/ssh2-rs)
- [russh](https://github.com/Eugeny/russh)
- [suppaftp](https://github.com/veeso/suppaftp)
- [ratatui](https://github.com/ratatui-org/ratatui)
- [tui-realm](https://github.com/veeso/tui-realm)

View File

@@ -263,7 +263,7 @@ se termscp esiste, è anche grazie a questi fantastici progetti:
- [rpassword](https://github.com/conradkleinespel/rpassword)
- [rust-s3](https://github.com/durch/rust-s3)
- [self_update](https://github.com/jaemk/self_update)
- [ssh2-rs](https://github.com/alexcrichton/ssh2-rs)
- [russh](https://github.com/Eugeny/russh)
- [suppaftp](https://github.com/veeso/suppaftp)
- [ratatui](https://github.com/ratatui-org/ratatui)
- [tui-realm](https://github.com/veeso/tui-realm)

View File

@@ -196,12 +196,10 @@ choco install termscp
### 依赖 ❗
- **Linux** 用户:
- libssh
- libdbus-1
- pkg-config
- libsmbclient
- **FreeBSD** 用户:
- libssh
- dbus
- pkgconf
- libsmbclient
@@ -270,7 +268,7 @@ termscp 由这些很棒的项目提供支持:
- [rpassword](https://github.com/conradkleinespel/rpassword)
- [rust-s3](https://github.com/durch/rust-s3)
- [self_update](https://github.com/jaemk/self_update)
- [ssh2-rs](https://github.com/alexcrichton/ssh2-rs)
- [russh](https://github.com/Eugeny/russh)
- [suppaftp](https://github.com/veeso/suppaftp)
- [ratatui](https://github.com/ratatui-org/ratatui)
- [tui-realm](https://github.com/veeso/tui-realm)

View File

@@ -299,9 +299,9 @@ install_on_macos() {
install_bsd_cargo_deps() {
set -e
confirm "${YELLOW}libssh, gcc${NO_COLOR} are required to install ${GREEN}termscp${NO_COLOR}; would you like to proceed?"
confirm "${YELLOW}gcc${NO_COLOR} is required to install ${GREEN}termscp${NO_COLOR}; would you like to proceed?"
sudo="$(elevate_priv_ex /usr/local/bin)"
$sudo pkg install -y curl wget libssh gcc dbus pkgconf libsmbclient
$sudo pkg install -y curl wget gcc dbus pkgconf libsmbclient
info "Dependencies installed successfully"
}
@@ -327,7 +327,7 @@ install_linux_cargo_deps() {
exit 1
fi
set -e
confirm "${YELLOW}libssh, gcc, openssl, pkg-config, libdbus${NO_COLOR} are required to install ${GREEN}termscp${NO_COLOR}. The following command will be used to install the dependencies: '${BOLD}${YELLOW}${deps_cmd}${NO_COLOR}'. Would you like to proceed?"
confirm "${YELLOW}gcc, openssl, pkg-config, libdbus${NO_COLOR} are required to install ${GREEN}termscp${NO_COLOR}. The following command will be used to install the dependencies: '${BOLD}${YELLOW}${deps_cmd}${NO_COLOR}'. Would you like to proceed?"
sudo="$(elevate_priv_ex /usr/local/bin)"
$sudo $deps_cmd
info "Dependencies installed successfully"

View File

@@ -13,10 +13,7 @@ use remotefs_kube::KubeMultiPodFs as KubeFs;
use remotefs_smb::SmbOptions;
#[cfg(smb)]
use remotefs_smb::{SmbCredentials, SmbFs};
#[cfg(windows)]
use remotefs_ssh::LibSsh2Session as SshSession;
#[cfg(unix)]
use remotefs_ssh::LibSshSession as SshSession;
use remotefs_ssh::{NoCheckServerKey, RusshSession as SshSession};
use remotefs_ssh::{ScpFs, SftpFs, SshAgentIdentity, SshConfigParseRule, SshOpts};
use remotefs_webdav::WebDAVFs;
@@ -53,10 +50,10 @@ impl RemoteFsBuilder {
Ok(Box::new(Self::kube_client(params)?))
}
(FileTransferProtocol::Scp, ProtocolParams::Generic(params)) => {
Ok(Box::new(Self::scp_client(params, config_client)))
Ok(Box::new(Self::scp_client(params, config_client)?))
}
(FileTransferProtocol::Sftp, ProtocolParams::Generic(params)) => {
Ok(Box::new(Self::sftp_client(params, config_client)))
Ok(Box::new(Self::sftp_client(params, config_client)?))
}
#[cfg(smb)]
(FileTransferProtocol::Smb, ProtocolParams::Smb(params)) => {
@@ -126,13 +123,7 @@ impl RemoteFsBuilder {
/// Build kube client
fn kube_client(params: KubeProtocolParams) -> Result<KubeFs, String> {
let rt = Arc::new(
tokio::runtime::Builder::new_current_thread()
.worker_threads(1)
.enable_all()
.build()
.map_err(|e| format!("Unable to create tokio runtime: {e}"))?,
);
let rt = Self::tokio_runtime()?;
let kube_fs = KubeFs::new(&rt);
if let Some(config) = params.config() {
Ok(kube_fs.config(config))
@@ -145,16 +136,20 @@ impl RemoteFsBuilder {
fn scp_client(
params: GenericProtocolParams,
config_client: &ConfigClient,
) -> ScpFs<SshSession> {
Self::build_ssh_opts(params, config_client).into()
) -> Result<ScpFs<SshSession<NoCheckServerKey>>, String> {
let opts = Self::build_ssh_opts(params, config_client);
let rt = Self::tokio_runtime()?;
Ok(ScpFs::russh(opts, rt))
}
/// Build sftp client
fn sftp_client(
params: GenericProtocolParams,
config_client: &ConfigClient,
) -> SftpFs<SshSession> {
Self::build_ssh_opts(params, config_client).into()
) -> Result<SftpFs<SshSession<NoCheckServerKey>>, String> {
let opts = Self::build_ssh_opts(params, config_client);
let rt = Self::tokio_runtime()?;
Ok(SftpFs::russh(opts, rt))
}
#[cfg(smb_unix)]
@@ -262,6 +257,17 @@ impl RemoteFsBuilder {
fn make_ssh_storage(config_client: &ConfigClient) -> SshKeyStorage {
SshKeyStorage::from(config_client)
}
/// Create tokio runtime to run async code for remotefs
fn tokio_runtime() -> Result<Arc<tokio::runtime::Runtime>, String> {
Ok(Arc::new(
tokio::runtime::Builder::new_current_thread()
.worker_threads(1)
.enable_all()
.build()
.map_err(|e| format!("Unable to create tokio runtime: {e}"))?,
))
}
}
#[cfg(test)]

View File

@@ -5,7 +5,7 @@
// Ext
use rand::distr::Alphanumeric;
use rand::{RngExt as _, rng};
use rand::{Rng as _, rng};
/// Generate a random alphanumeric string with provided length
pub fn random_alphanumeric_with_len(len: usize) -> String {