From 6123a93af50be211c8bad2280bb4e99415ea90e4 Mon Sep 17 00:00:00 2001 From: Alexander Weiss Date: Mon, 11 Mar 2024 21:22:07 +0100 Subject: [PATCH 01/11] fix(rclone): Use semver for version checking --- crates/backend/Cargo.toml | 3 ++- crates/backend/src/rclone.rs | 36 ++++++++++++++++-------------------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/crates/backend/Cargo.toml b/crates/backend/Cargo.toml index 1941361e..d3647630 100644 --- a/crates/backend/Cargo.toml +++ b/crates/backend/Cargo.toml @@ -38,7 +38,7 @@ clap = ["dep:clap"] s3 = ["opendal"] opendal = ["dep:opendal", "dep:rayon", "dep:tokio", "tokio/rt-multi-thread"] rest = ["dep:reqwest", "dep:backoff"] -rclone = ["rest", "dep:rand"] +rclone = ["rest", "dep:rand", "dep:semver"] # Note: sftp is not yet supported on windows, see below sftp = ["opendal"] @@ -82,6 +82,7 @@ reqwest = { version = "0.11.25", default-features = false, features = ["json", " # rclone backend rand = { version = "0.8.5", optional = true } +semver = { version = "1.0.22", optional = true } # opendal backend rayon = { version = "1.9.0", optional = true } diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index fa284944..cdfab919 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -7,12 +7,13 @@ use std::{ use anyhow::Result; use bytes::Bytes; -use itertools::Itertools; use log::{debug, info, warn}; use rand::{ distributions::{Alphanumeric, DistString}, thread_rng, }; + +use semver::{Version, VersionReq}; use shell_words::split; use crate::{error::RcloneErrorKind, rest::RestBackend}; @@ -63,7 +64,7 @@ impl Drop for RcloneBackend { /// [`RcloneErrorKind::FromUtf8Error`]: RcloneErrorKind::FromUtf8Error /// [`RcloneErrorKind::NoOutputForRcloneVersion`]: RcloneErrorKind::NoOutputForRcloneVersion /// [`RcloneErrorKind::FromParseVersion`]: RcloneErrorKind::FromParseVersion -fn rclone_version() -> Result<(i32, i32, i32)> { +fn check_clone_version() -> Result<()> { let rclone_version_output = Command::new("rclone") .arg("version") .output() @@ -76,12 +77,17 @@ fn rclone_version() -> Result<(i32, i32, i32)> { .ok_or_else(|| RcloneErrorKind::NoOutputForRcloneVersion)? .trim_start_matches(|c: char| !c.is_numeric()); - let versions = rclone_version - .split(&['.', '-', ' '][..]) - .filter_map(|v| v.parse().ok()) - .collect_tuple() - .ok_or_else(|| RcloneErrorKind::FromParseVersion(rclone_version.to_string()))?; - Ok(versions) + let req = VersionReq::parse(">=1.52.2")?; + let version = Version::parse(rclone_version)?; + if !req.matches(&version) { + // TODO: This should be an error, and explicitly agreed to with a flag passed to `rustic`, + // check #812 for details + // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means + // we are setting up an rclone without authentication which is a security issue! + // (however, it still works, so we give a warning) + warn!("Using rclone without authentication! Upgrade to rclone >= 1.52.2 (current version: {})!", rclone_version); + } + Ok(()) } impl RcloneBackend { @@ -113,18 +119,8 @@ impl RcloneBackend { if use_password && rclone_command.is_none() { // if we want to use a password and rclone_command is not explicitely set, we check for a rclone version supporting // user/password via env variables - match rclone_version() { - Ok(v) => { - if v < (1, 52, 2) { - // TODO: This should be an error, and explicitly agreed to with a flag passed to `rustic`, - // check #812 for details - // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means - // we are setting up an rclone without authentication which is a security issue! - // (however, it still works, so we give a warning) - warn!("Using rclone without authentication! Upgrade to rclone >= 1.52.2 (current version: {}.{}.{})!", v.0, v.1, v.2); - } - } - Err(err) => warn!("Could not determine rclone version: {err}"), + if let Err(err) = check_clone_version() { + warn!("Could not determine rclone version: {err}"); } } From ba2d4c03bbf11c9fb1b6f549baab2f5eb5dcd4af Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 21:48:00 +0100 Subject: [PATCH 02/11] use error handling Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/backend/src/error.rs | 2 ++ crates/backend/src/rclone.rs | 15 ++++++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/backend/src/error.rs b/crates/backend/src/error.rs index 2773463d..ed8e5cac 100644 --- a/crates/backend/src/error.rs +++ b/crates/backend/src/error.rs @@ -54,6 +54,8 @@ pub enum RcloneErrorKind { FromUtf8Error(#[from] Utf8Error), /// error parsing verision number from `{0:?}` FromParseVersion(String), + /// Using rclone without authentication! Upgrade to rclone >= 1.52.2 (current version: `{0}`)! + RCloneWithoutAuthentication(String), } /// [`RestErrorKind`] describes the errors that can be returned while dealing with the REST API diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index cdfab919..71d82d8f 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -7,7 +7,7 @@ use std::{ use anyhow::Result; use bytes::Bytes; -use log::{debug, info, warn}; +use log::{debug, info}; use rand::{ distributions::{Alphanumeric, DistString}, thread_rng, @@ -80,12 +80,11 @@ fn check_clone_version() -> Result<()> { let req = VersionReq::parse(">=1.52.2")?; let version = Version::parse(rclone_version)?; if !req.matches(&version) { - // TODO: This should be an error, and explicitly agreed to with a flag passed to `rustic`, - // check #812 for details // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means // we are setting up an rclone without authentication which is a security issue! - // (however, it still works, so we give a warning) - warn!("Using rclone without authentication! Upgrade to rclone >= 1.52.2 (current version: {})!", rclone_version); + return Err( + RcloneErrorKind::RCloneWithoutAuthentication(rclone_version.to_string()).into(), + ); } Ok(()) } @@ -117,11 +116,9 @@ impl RcloneBackend { .unwrap_or(true); if use_password && rclone_command.is_none() { - // if we want to use a password and rclone_command is not explicitely set, we check for a rclone version supporting + // if we want to use a password and rclone_command is not explicitly set, we check for a rclone version supporting // user/password via env variables - if let Err(err) = check_clone_version() { - warn!("Could not determine rclone version: {err}"); - } + check_clone_version()?; } let user = Alphanumeric.sample_string(&mut thread_rng(), 12); From 807d51a017c7ff0010e1a65a41a0053dbb5d6281 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 21:57:34 +0100 Subject: [PATCH 03/11] test: make testable and add test Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/backend/src/rclone.rs | 49 +++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index 71d82d8f..50c60aa4 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -47,7 +47,11 @@ impl Drop for RcloneBackend { } } -/// Get the rclone version. +/// Check the rclone version. +/// +/// # Arguments +/// +/// * `rclone_version_output` - The output of `rclone version`. /// /// # Errors /// @@ -58,18 +62,13 @@ impl Drop for RcloneBackend { /// /// # Returns /// -/// The rclone version as a tuple of (major, minor, patch). +/// * `Ok(())` - If the rclone version is supported. /// /// [`RcloneErrorKind::FromIoError`]: RcloneErrorKind::FromIoError /// [`RcloneErrorKind::FromUtf8Error`]: RcloneErrorKind::FromUtf8Error /// [`RcloneErrorKind::NoOutputForRcloneVersion`]: RcloneErrorKind::NoOutputForRcloneVersion /// [`RcloneErrorKind::FromParseVersion`]: RcloneErrorKind::FromParseVersion -fn check_clone_version() -> Result<()> { - let rclone_version_output = Command::new("rclone") - .arg("version") - .output() - .map_err(RcloneErrorKind::FromIoError)? - .stdout; +fn check_clone_version(rclone_version_output: &[u8]) -> Result<()> { let rclone_version = std::str::from_utf8(&rclone_version_output) .map_err(RcloneErrorKind::FromUtf8Error)? .lines() @@ -116,9 +115,15 @@ impl RcloneBackend { .unwrap_or(true); if use_password && rclone_command.is_none() { + let rclone_version_output = Command::new("rclone") + .arg("version") + .output() + .map_err(RcloneErrorKind::FromIoError)? + .stdout; + // if we want to use a password and rclone_command is not explicitly set, we check for a rclone version supporting // user/password via env variables - check_clone_version()?; + check_clone_version(rclone_version_output.as_slice())?; } let user = Alphanumeric.sample_string(&mut thread_rng(), 12); @@ -291,3 +296,29 @@ impl WriteBackend for RcloneBackend { self.rest.remove(tpe, id, cacheable) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_check_clone_version_passes() { + let rclone_version_output = + b"rclone v1.52.2\n- os/arch: linux/amd64\n- go version: go1.14.4\n"; + assert!(check_clone_version(rclone_version_output).is_ok()); + + let rclone_version_output = + b"rclone v1.66.0\n- os/version: Microsoft Windows 11 Pro 23H2 (64 bit)\n- os/kernel: 10.0.22631.3155 (x86_64)\n- os/type: windows\n- os/arch: amd64\n- go/version: go1.22.1\n- go/linking: static\n- go/tags: cmount"; + assert!(check_clone_version(rclone_version_output).is_ok()); + } + + #[test] + fn test_check_clone_version_fails() { + let rclone_version_output = b""; + assert!(check_clone_version(rclone_version_output).is_err()); + + let rclone_version_output = + b"rclone v1.52.1\n- os/arch: linux/amd64\n- go version: go1.14.4\n"; + assert!(check_clone_version(rclone_version_output).is_err()); + } +} From 07312c437d562b157a2ec172287567a8fb4d3675 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 22:09:25 +0100 Subject: [PATCH 04/11] fix clippy lint Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/backend/src/rclone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index 50c60aa4..1ae8158f 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -69,7 +69,7 @@ impl Drop for RcloneBackend { /// [`RcloneErrorKind::NoOutputForRcloneVersion`]: RcloneErrorKind::NoOutputForRcloneVersion /// [`RcloneErrorKind::FromParseVersion`]: RcloneErrorKind::FromParseVersion fn check_clone_version(rclone_version_output: &[u8]) -> Result<()> { - let rclone_version = std::str::from_utf8(&rclone_version_output) + let rclone_version = std::str::from_utf8(rclone_version_output) .map_err(RcloneErrorKind::FromUtf8Error)? .lines() .next() From 3ad63ccfcaceacf5155810619f5a80be961823da Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 23:08:36 +0100 Subject: [PATCH 05/11] make tests pass also with version from issue Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- Cargo.toml | 1 + crates/backend/Cargo.toml | 2 +- crates/backend/src/rclone.rs | 33 ++++++++++++++------------------- crates/core/Cargo.toml | 2 +- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d2573697..eeb07956 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ rustic_core = { path = "crates/core" } simplelog = "0.12.2" # dev-dependencies +rstest = "0.18.2" tempfile = "3.10.1" # see: https://nnethercote.github.io/perf-book/build-configuration.html diff --git a/crates/backend/Cargo.toml b/crates/backend/Cargo.toml index d3647630..7a75de65 100644 --- a/crates/backend/Cargo.toml +++ b/crates/backend/Cargo.toml @@ -97,4 +97,4 @@ opendal = { version = "0.45", features = ["services-b2", "services-sftp", "servi opendal = { version = "0.45", features = ["services-b2", "services-swift", "layers-blocking"], optional = true } [dev-dependencies] -rstest = "0.18.2" +rstest = { workspace = true } diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index 1ae8158f..d06af527 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -76,15 +76,14 @@ fn check_clone_version(rclone_version_output: &[u8]) -> Result<()> { .ok_or_else(|| RcloneErrorKind::NoOutputForRcloneVersion)? .trim_start_matches(|c: char| !c.is_numeric()); - let req = VersionReq::parse(">=1.52.2")?; - let version = Version::parse(rclone_version)?; - if !req.matches(&version) { - // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means - // we are setting up an rclone without authentication which is a security issue! + // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means + // we are setting up an rclone without authentication which is a security issue! + if VersionReq::parse("<1.52.2")?.matches(&Version::parse(rclone_version)?) { return Err( RcloneErrorKind::RCloneWithoutAuthentication(rclone_version.to_string()).into(), ); } + Ok(()) } @@ -301,24 +300,20 @@ impl WriteBackend for RcloneBackend { mod tests { use super::*; - #[test] - fn test_check_clone_version_passes() { - let rclone_version_output = - b"rclone v1.52.2\n- os/arch: linux/amd64\n- go version: go1.14.4\n"; - assert!(check_clone_version(rclone_version_output).is_ok()); + use rstest::rstest; - let rclone_version_output = - b"rclone v1.66.0\n- os/version: Microsoft Windows 11 Pro 23H2 (64 bit)\n- os/kernel: 10.0.22631.3155 (x86_64)\n- os/type: windows\n- os/arch: amd64\n- go/version: go1.22.1\n- go/linking: static\n- go/tags: cmount"; + #[rstest] + #[case(b"rclone v1.52.2\n- os/arch: linux/amd64\n- go version: go1.14.4\n")] + #[case(b"rclone v1.66.0\n- os/version: Microsoft Windows 11 Pro 23H2 (64 bit)\n- os/kernel: 10.0.22631.3155 (x86_64)\n- os/type: windows\n- os/arch: amd64\n- go/version: go1.22.1\n- go/linking: static\n- go/tags: cmount")] + #[case(b"rclone v1.63.0-beta.7022.e649cf4d5\n- os/arch: linux/amd64\n- go version: go1.14.4\n")] + fn test_check_clone_version_passes(#[case] rclone_version_output: &[u8]) { assert!(check_clone_version(rclone_version_output).is_ok()); } - #[test] - fn test_check_clone_version_fails() { - let rclone_version_output = b""; - assert!(check_clone_version(rclone_version_output).is_err()); - - let rclone_version_output = - b"rclone v1.52.1\n- os/arch: linux/amd64\n- go version: go1.14.4\n"; + #[rstest] + #[case(b"")] + #[case(b"rclone v1.52.1\n- os/arch: linux/amd64\n- go version: go1.14.4\n")] + fn test_check_clone_version_fails(#[case] rclone_version_output: &[u8]) { assert!(check_clone_version(rclone_version_output).is_err()); } } diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index ba25860f..a431b189 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -136,7 +136,7 @@ mockall = "0.12.1" pretty_assertions = "1.4.0" quickcheck = "1.0.3" quickcheck_macros = "1.0.0" -rstest = "0.18.2" +rstest = { workspace = true } rustdoc-json = "0.8.9" # We need to have rustic_backend here, because the doc-tests in lib.rs of rustic_core rustic_backend = { workspace = true } From 1965b6486527ef54df7288fd4e156106c8ef415e Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 23:11:51 +0100 Subject: [PATCH 06/11] case should not pass Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/backend/src/rclone.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index d06af527..91273791 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -313,6 +313,7 @@ mod tests { #[rstest] #[case(b"")] #[case(b"rclone v1.52.1\n- os/arch: linux/amd64\n- go version: go1.14.4\n")] + #[case(b"rclone v1.51.3-beta\n- os/arch: linux/amd64\n- go version: go1.14.4\n")] fn test_check_clone_version_fails(#[case] rclone_version_output: &[u8]) { assert!(check_clone_version(rclone_version_output).is_err()); } From 0c6ba2e5d445f6ef89bbcab5b01746b08901ac55 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 23:20:19 +0100 Subject: [PATCH 07/11] strip build metadata and prerelease version in rclone version comparison Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/backend/src/rclone.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index 91273791..351d1c2d 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -13,7 +13,7 @@ use rand::{ thread_rng, }; -use semver::{Version, VersionReq}; +use semver::{BuildMetadata, Prerelease, Version, VersionReq}; use shell_words::split; use crate::{error::RcloneErrorKind, rest::RestBackend}; @@ -78,7 +78,11 @@ fn check_clone_version(rclone_version_output: &[u8]) -> Result<()> { // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means // we are setting up an rclone without authentication which is a security issue! - if VersionReq::parse("<1.52.2")?.matches(&Version::parse(rclone_version)?) { + let mut parsed_version = Version::parse(rclone_version)?; + parsed_version.pre = Prerelease::EMPTY; + parsed_version.build = BuildMetadata::EMPTY; + + if VersionReq::parse("<1.52.2")?.matches(&parsed_version) { return Err( RcloneErrorKind::RCloneWithoutAuthentication(rclone_version.to_string()).into(), ); From 4f19d6daeb67b4eb24184bf4e2cdb069a8eff425 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 23:23:40 +0100 Subject: [PATCH 08/11] add explanation for strip Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/backend/src/rclone.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index 351d1c2d..5fae316c 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -79,6 +79,10 @@ fn check_clone_version(rclone_version_output: &[u8]) -> Result<()> { // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means // we are setting up an rclone without authentication which is a security issue! let mut parsed_version = Version::parse(rclone_version)?; + + // we need to set the pre and build fields to empty to make the comparison work + // otherwise the comparison will take the pre and build fields into account + // which would make beta versions pass the check parsed_version.pre = Prerelease::EMPTY; parsed_version.build = BuildMetadata::EMPTY; From 61fd5258944decd999a0924f0f5a205069e8b512 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 23:24:07 +0100 Subject: [PATCH 09/11] move comment to where it belongs Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/backend/src/rclone.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index 5fae316c..f845ef8c 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -76,8 +76,6 @@ fn check_clone_version(rclone_version_output: &[u8]) -> Result<()> { .ok_or_else(|| RcloneErrorKind::NoOutputForRcloneVersion)? .trim_start_matches(|c: char| !c.is_numeric()); - // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means - // we are setting up an rclone without authentication which is a security issue! let mut parsed_version = Version::parse(rclone_version)?; // we need to set the pre and build fields to empty to make the comparison work @@ -86,6 +84,8 @@ fn check_clone_version(rclone_version_output: &[u8]) -> Result<()> { parsed_version.pre = Prerelease::EMPTY; parsed_version.build = BuildMetadata::EMPTY; + // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means + // we are setting up an rclone without authentication which is a security issue! if VersionReq::parse("<1.52.2")?.matches(&parsed_version) { return Err( RcloneErrorKind::RCloneWithoutAuthentication(rclone_version.to_string()).into(), From f531de95f86dfc374ba6172ec3bc97d9b71b6cc5 Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 23:30:53 +0100 Subject: [PATCH 10/11] add comment about it being a hard error now, if the version is not supported Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/backend/src/rclone.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index f845ef8c..a89d3393 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -128,8 +128,9 @@ impl RcloneBackend { .map_err(RcloneErrorKind::FromIoError)? .stdout; - // if we want to use a password and rclone_command is not explicitly set, we check for a rclone version supporting - // user/password via env variables + // if we want to use a password and rclone_command is not explicitly set, + // we check for a rclone version supporting user/password via env variables + // if the version is not supported, we return an error check_clone_version(rclone_version_output.as_slice())?; } From 7fcfeaeb22565eb084c3b898b67fe34223d378aa Mon Sep 17 00:00:00 2001 From: simonsan <14062932+simonsan@users.noreply.github.com> Date: Mon, 11 Mar 2024 23:37:28 +0100 Subject: [PATCH 11/11] add comment about lower bound for rclone Signed-off-by: simonsan <14062932+simonsan@users.noreply.github.com> --- crates/backend/src/rclone.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/backend/src/rclone.rs b/crates/backend/src/rclone.rs index a89d3393..a0402b84 100644 --- a/crates/backend/src/rclone.rs +++ b/crates/backend/src/rclone.rs @@ -86,6 +86,9 @@ fn check_clone_version(rclone_version_output: &[u8]) -> Result<()> { // for rclone < 1.52.2 setting user/password via env variable doesn't work. This means // we are setting up an rclone without authentication which is a security issue! + // we hard fail here to prevent this, as we can't guarantee the security of the data + // also because 1.52.2 has been released on Jun 24, 2020, we can assume that this is a + // reasonable lower bound for the version if VersionReq::parse("<1.52.2")?.matches(&parsed_version) { return Err( RcloneErrorKind::RCloneWithoutAuthentication(rclone_version.to_string()).into(),