fix: added required changes

This commit is contained in:
itsvyle 2026-03-03 15:14:43 +01:00 committed by sxyazi
parent 288ca2ffa2
commit 437cbc2290
No known key found for this signature in database
3 changed files with 45 additions and 12 deletions

View file

@ -39,9 +39,9 @@ pub struct ServiceSftp {
pub key_file: PathBuf,
pub key_passphrase: Option<String>,
#[serde(default)]
pub cert_file: PathBuf,
pub cert_file: PathBuf,
#[serde(default)]
pub skip_cert_validation: bool,
pub no_cert_verify: bool,
#[serde(default)]
pub identity_agent: PathBuf,
}

View file

@ -1,6 +1,35 @@
use std::time::{SystemTime, UNIX_EPOCH};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[inline]
pub fn timestamp_us() -> u64 {
SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards").as_micros() as _
}
pub fn format_duration(duration: Duration) -> String {
// go till days precision, but only show the non-zero parts
let mut secs = duration.as_secs();
let days = secs / 86_400;
secs %= 86_400;
let hours = secs / 3_600;
secs %= 3_600;
let minutes = secs / 60;
secs %= 60;
let mut parts = Vec::with_capacity(4);
if days > 0 {
parts.push(format!("{}d", days));
}
if hours > 0 || days > 0 {
parts.push(format!("{:0>2}h", hours));
}
if minutes > 0 || hours > 0 || days > 0 {
parts.push(format!("{:0>2}m", minutes));
}
if secs > 0 || minutes > 0 || hours > 0 || days > 0 {
parts.push(format!("{:0>2}s", secs));
}
if parts.is_empty() {
"0s".to_string()
} else {
parts.join("")
}
}

View file

@ -3,6 +3,7 @@ use std::{io, sync::Arc, time::Duration};
use russh::keys::PrivateKeyWithHashAlg;
use yazi_config::vfs::ServiceSftp;
use yazi_fs::provider::local::Local;
use yazi_shared::{format_duration, timestamp_us};
#[derive(Clone, Copy)]
pub(super) struct Conn {
@ -169,18 +170,21 @@ impl Conn {
},
)?;
if !self.config.skip_cert_validation {
// TODO: Also validate the certificate cryptographically: https://docs.rs/russh/latest/russh/keys/struct.Certificate.html#method.validate
// however, this would require fetching CAs, which could require additional config and complexity
if !self.config.no_cert_verify {
cert.verify_signature().map_err(|e| {
russh::Error::InvalidConfig(format!("Certificate signature verification failed: {e}"))
})?;
let unix_timestamp = std::time::UNIX_EPOCH.elapsed().unwrap_or_default().as_secs();
if !(cert.valid_after() <= unix_timestamp && unix_timestamp <= cert.valid_before()) {
return Err(russh::Error::InvalidConfig(
"Certificate is not valid at this time".to_owned(),
));
let unix_timestamp = timestamp_us() / 1_000_000;
if unix_timestamp < cert.valid_after() {
return Err(russh::Error::InvalidConfig(format!(
"Certificate will be valid in {}",
format_duration(Duration::from_secs(cert.valid_after() - unix_timestamp))
)));
} else if unix_timestamp > cert.valid_before() {
return Err(russh::Error::InvalidConfig(format!(
"Certificate expired {} ago",
format_duration(Duration::from_secs(unix_timestamp - cert.valid_before()))
)));
}
}