mirror of
https://github.com/veeso/termscp.git
synced 2025-12-06 17:15:35 -08:00
@@ -44,6 +44,7 @@
|
||||
|
||||
Released on ??
|
||||
|
||||
- [issue 308](https://github.com/veeso/termscp/issues/308): added `--wno-keyring` flag to disable keyring
|
||||
- [issue 316](https://github.com/veeso/termscp/issues/316): Local directory path is not switching to what's specified in the bookmark. Now the local directory path is correctly set following this hierarchy:
|
||||
1. Local directory path specified for the host bridge
|
||||
2. Local directory path specified in the bookmark
|
||||
|
||||
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -1125,6 +1125,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"num",
|
||||
"once_cell",
|
||||
"openssl",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
@@ -2334,6 +2335,7 @@ dependencies = [
|
||||
"byteorder",
|
||||
"dbus-secret-service",
|
||||
"log",
|
||||
"openssl",
|
||||
"security-framework 2.11.1",
|
||||
"security-framework 3.2.0",
|
||||
"windows-sys 0.59.0",
|
||||
@@ -2472,6 +2474,7 @@ version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
|
||||
@@ -41,10 +41,11 @@ dirs = "^6"
|
||||
edit = "^0.1"
|
||||
filetime = "^0.2"
|
||||
hostname = "^0.4"
|
||||
keyring = { version = "^3", optional = true, features = [
|
||||
keyring = { version = "^3", features = [
|
||||
"apple-native",
|
||||
"windows-native",
|
||||
"sync-secret-service",
|
||||
"vendored",
|
||||
] }
|
||||
lazy-regex = "^3"
|
||||
lazy_static = "^1"
|
||||
@@ -92,11 +93,11 @@ vergen-git2 = { version = "1", features = ["build", "cargo", "rustc", "si"] }
|
||||
|
||||
|
||||
[features]
|
||||
default = ["smb", "with-keyring"]
|
||||
default = ["smb", "keyring"]
|
||||
github-actions = []
|
||||
isolated-tests = []
|
||||
smb = ["remotefs-smb"]
|
||||
with-keyring = ["keyring"]
|
||||
smb = ["dep:remotefs-smb"]
|
||||
keyring = []
|
||||
|
||||
[target."cfg(not(target_os = \"macos\"))".dependencies]
|
||||
remotefs-smb = { version = "^0.3", optional = true }
|
||||
|
||||
@@ -157,7 +157,7 @@ sudo <span class="function">dpkg</span> -i <span class="string">termscp.deb</spa
|
||||
</p>
|
||||
<pre><span class="function">cargo</span> install --locked --no-default-features --features smb <span class="string">termscp</span></pre>
|
||||
<p translate="getStarted.cargo.noSMB" class="pt-4 pb-2"></p>
|
||||
<pre><span class="function">cargo</span> install --locked --no-default-features --features with-keyring <span class="string">termscp</span></pre>
|
||||
<pre><span class="function">cargo</span> install --locked --no-default-features --features keyring <span class="string">termscp</span></pre>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -50,7 +50,7 @@ pub struct ActivityManager {
|
||||
|
||||
impl ActivityManager {
|
||||
/// Initializes a new Activity Manager
|
||||
pub fn new(ticks: Duration) -> Result<ActivityManager, HostError> {
|
||||
pub fn new(ticks: Duration, keyring: bool) -> Result<ActivityManager, HostError> {
|
||||
// Prepare Context
|
||||
// Initialize configuration client
|
||||
let (config_client, error_config): (ConfigClient, Option<String>) =
|
||||
@@ -61,7 +61,7 @@ impl ActivityManager {
|
||||
(ConfigClient::degraded(), Some(err))
|
||||
}
|
||||
};
|
||||
let (bookmarks_client, error_bookmark) = match Self::init_bookmarks_client() {
|
||||
let (bookmarks_client, error_bookmark) = match Self::init_bookmarks_client(keyring) {
|
||||
Ok(cli) => (cli, None),
|
||||
Err(err) => (None, Some(err)),
|
||||
};
|
||||
@@ -447,7 +447,7 @@ impl ActivityManager {
|
||||
|
||||
// -- misc
|
||||
|
||||
fn init_bookmarks_client() -> Result<Option<BookmarksClient>, String> {
|
||||
fn init_bookmarks_client(keyring: bool) -> Result<Option<BookmarksClient>, String> {
|
||||
// Get config dir
|
||||
match environment::init_config_dir() {
|
||||
Ok(path) => {
|
||||
@@ -456,16 +456,21 @@ impl ActivityManager {
|
||||
let bookmarks_file: PathBuf =
|
||||
environment::get_bookmarks_paths(config_dir_path.as_path());
|
||||
// Initialize client
|
||||
BookmarksClient::new(bookmarks_file.as_path(), config_dir_path.as_path(), 16)
|
||||
.map(Option::Some)
|
||||
.map_err(|e| {
|
||||
format!(
|
||||
"Could not initialize bookmarks (at \"{}\", \"{}\"): {}",
|
||||
bookmarks_file.display(),
|
||||
config_dir_path.display(),
|
||||
e
|
||||
)
|
||||
})
|
||||
BookmarksClient::new(
|
||||
bookmarks_file.as_path(),
|
||||
config_dir_path.as_path(),
|
||||
16,
|
||||
keyring,
|
||||
)
|
||||
.map(Option::Some)
|
||||
.map_err(|e| {
|
||||
format!(
|
||||
"Could not initialize bookmarks (at \"{}\", \"{}\"): {}",
|
||||
bookmarks_file.display(),
|
||||
config_dir_path.display(),
|
||||
e
|
||||
)
|
||||
})
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@@ -60,6 +60,9 @@ pub struct Args {
|
||||
/// print version
|
||||
#[argh(switch, short = 'v')]
|
||||
pub version: bool,
|
||||
/// disable keyring support
|
||||
#[argh(switch)]
|
||||
pub wno_keyring: bool,
|
||||
// -- positional
|
||||
#[argh(positional, description = "address1 address2 local-wrkdir")]
|
||||
pub positional: Vec<String>,
|
||||
@@ -94,6 +97,7 @@ pub struct LoadThemeArgs {
|
||||
|
||||
pub struct RunOpts {
|
||||
pub remote: RemoteArgs,
|
||||
pub keyring: bool,
|
||||
pub ticks: Duration,
|
||||
pub log_level: LogLevel,
|
||||
pub task: Task,
|
||||
@@ -127,6 +131,7 @@ impl Default for RunOpts {
|
||||
Self {
|
||||
remote: RemoteArgs::default(),
|
||||
ticks: Duration::from_millis(10),
|
||||
keyring: true,
|
||||
log_level: LogLevel::Info,
|
||||
task: Task::Activity(NextActivity::Authentication),
|
||||
}
|
||||
|
||||
12
src/main.rs
12
src/main.rs
@@ -76,6 +76,7 @@ fn parse_args(args: Args) -> Result<RunOpts, String> {
|
||||
Some(ArgsSubcommands::Config(_)) => RunOpts::config(),
|
||||
None => {
|
||||
let mut run_opts: RunOpts = RunOpts::default();
|
||||
|
||||
// Version
|
||||
if args.version {
|
||||
run_opts.task = Task::Version;
|
||||
@@ -87,6 +88,10 @@ fn parse_args(args: Args) -> Result<RunOpts, String> {
|
||||
} else if args.quiet {
|
||||
run_opts.log_level = LogLevel::Off;
|
||||
}
|
||||
// set keyring
|
||||
if args.wno_keyring {
|
||||
run_opts.keyring = false;
|
||||
}
|
||||
// Match ticks
|
||||
run_opts.ticks = Duration::from_millis(args.ticks);
|
||||
// Remote argument
|
||||
@@ -124,7 +129,9 @@ fn run(run_opts: RunOpts) -> MainResult<()> {
|
||||
match run_opts.task {
|
||||
Task::ImportTheme(theme) => run_import_theme(&theme),
|
||||
Task::InstallUpdate => run_install_update(),
|
||||
Task::Activity(activity) => run_activity(activity, run_opts.ticks, run_opts.remote),
|
||||
Task::Activity(activity) => {
|
||||
run_activity(activity, run_opts.ticks, run_opts.remote, run_opts.keyring)
|
||||
}
|
||||
Task::Version => print_version(),
|
||||
}
|
||||
}
|
||||
@@ -168,9 +175,10 @@ fn run_activity(
|
||||
activity: NextActivity,
|
||||
ticks: Duration,
|
||||
remote_args: RemoteArgs,
|
||||
keyring: bool,
|
||||
) -> MainResult<()> {
|
||||
// Create activity manager (and context too)
|
||||
let mut manager: ActivityManager = match ActivityManager::new(ticks) {
|
||||
let mut manager: ActivityManager = match ActivityManager::new(ticks, keyring) {
|
||||
Ok(m) => m,
|
||||
Err(err) => {
|
||||
eprintln!("Could not start activity manager: {err}");
|
||||
|
||||
@@ -10,7 +10,6 @@ use std::string::ToString;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use super::keys::filestorage::FileStorage;
|
||||
#[cfg(feature = "with-keyring")]
|
||||
use super::keys::keyringstorage::KeyringStorage;
|
||||
use super::keys::{KeyStorage, KeyStorageError};
|
||||
// Local
|
||||
@@ -39,42 +38,13 @@ impl BookmarksClient {
|
||||
bookmarks_file: &Path,
|
||||
storage_path: &Path,
|
||||
recents_size: usize,
|
||||
keyring: bool,
|
||||
) -> Result<BookmarksClient, SerializerError> {
|
||||
// Create default hosts
|
||||
let default_hosts: UserHosts = UserHosts::default();
|
||||
debug!("Setting up bookmarks client...");
|
||||
// Make a key storage (with-keyring)
|
||||
#[cfg(feature = "with-keyring")]
|
||||
let (key_storage, service_id): (Box<dyn KeyStorage>, &str) = {
|
||||
debug!("Setting up KeyStorage");
|
||||
let username: String = whoami::username();
|
||||
let storage: KeyringStorage = KeyringStorage::new(username.as_str());
|
||||
// Check if keyring storage is supported
|
||||
#[cfg(not(test))]
|
||||
let app_name: &str = "termscp";
|
||||
#[cfg(test)] // NOTE: when running test, add -test
|
||||
let app_name: &str = "termscp-test";
|
||||
match storage.is_supported() {
|
||||
true => {
|
||||
debug!("Using KeyringStorage");
|
||||
(Box::new(storage), app_name)
|
||||
}
|
||||
false => {
|
||||
warn!("KeyringStorage is not supported; using FileStorage");
|
||||
(Box::new(FileStorage::new(storage_path)), "bookmarks")
|
||||
}
|
||||
}
|
||||
};
|
||||
// Make a key storage (wno-keyring)
|
||||
#[cfg(not(feature = "with-keyring"))]
|
||||
let (key_storage, service_id): (Box<dyn KeyStorage>, &str) = {
|
||||
#[cfg(not(test))]
|
||||
let app_name: &str = "bookmarks";
|
||||
#[cfg(test)] // NOTE: when running test, add -test
|
||||
let app_name: &str = "bookmarks-test";
|
||||
debug!("Using FileStorage");
|
||||
(Box::new(FileStorage::new(storage_path)), app_name)
|
||||
};
|
||||
// Get key storage
|
||||
let (key_storage, service_id) = Self::keyring(storage_path, keyring);
|
||||
// Load key
|
||||
let key: String = match key_storage.get_key(service_id) {
|
||||
Ok(k) => {
|
||||
@@ -130,6 +100,37 @@ impl BookmarksClient {
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
/// Get the key storage
|
||||
fn keyring(storage_path: &Path, keyring: bool) -> (Box<dyn KeyStorage>, &'static str) {
|
||||
if keyring && cfg!(feature = "keyring") {
|
||||
debug!("Setting up KeyStorage");
|
||||
let username: String = whoami::username();
|
||||
let storage: KeyringStorage = KeyringStorage::new(username.as_str());
|
||||
// Check if keyring storage is supported
|
||||
#[cfg(not(test))]
|
||||
let app_name: &str = "termscp";
|
||||
#[cfg(test)] // NOTE: when running test, add -test
|
||||
let app_name: &str = "termscp-test";
|
||||
match storage.is_supported() {
|
||||
true => {
|
||||
debug!("Using KeyringStorage");
|
||||
(Box::new(storage), app_name)
|
||||
}
|
||||
false => {
|
||||
warn!("KeyringStorage is not supported; using FileStorage");
|
||||
(Box::new(FileStorage::new(storage_path)), "bookmarks")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#[cfg(not(test))]
|
||||
let app_name: &str = "bookmarks";
|
||||
#[cfg(test)] // NOTE: when running test, add -test
|
||||
let app_name: &str = "bookmarks-test";
|
||||
debug!("Using FileStorage");
|
||||
(Box::new(FileStorage::new(storage_path)), app_name)
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over bookmarks keys
|
||||
pub fn iter_bookmarks(&self) -> impl Iterator<Item = &String> + '_ {
|
||||
Box::new(self.hosts.bookmarks.keys())
|
||||
@@ -389,7 +390,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Verify client
|
||||
assert_eq!(client.hosts.bookmarks.len(), 0);
|
||||
assert_eq!(client.hosts.recents.len(), 0);
|
||||
@@ -405,7 +406,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add some bookmarks
|
||||
client.add_bookmark(
|
||||
"raspberry",
|
||||
@@ -430,7 +431,7 @@ mod tests {
|
||||
let key: String = client.key.clone();
|
||||
// Re-initialize a client
|
||||
let client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Verify it loaded parameters correctly
|
||||
assert_eq!(client.key, key);
|
||||
let bookmark = ftparams_to_tup(client.get_bookmark("raspberry").unwrap());
|
||||
@@ -453,7 +454,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add s3 bookmark
|
||||
client.add_bookmark("my-bucket", make_s3_ftparams(), true);
|
||||
// Verify bookmark
|
||||
@@ -473,7 +474,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add s3 bookmark
|
||||
client.add_bookmark("my-bucket", make_s3_ftparams(), false);
|
||||
// Verify bookmark
|
||||
@@ -494,7 +495,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add s3 bookmark
|
||||
client.add_recent(make_s3_ftparams());
|
||||
// Verify bookmark
|
||||
@@ -517,7 +518,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add bookmark
|
||||
client.add_bookmark(
|
||||
"raspberry",
|
||||
@@ -568,7 +569,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add bookmark
|
||||
client.add_bookmark(
|
||||
"",
|
||||
@@ -589,7 +590,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add bookmark
|
||||
client.add_bookmark(
|
||||
"raspberry",
|
||||
@@ -617,7 +618,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add bookmark
|
||||
client.add_recent(make_generic_ftparams(
|
||||
FileTransferProtocol::Sftp,
|
||||
@@ -653,7 +654,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add bookmark
|
||||
client.add_recent(make_generic_ftparams(
|
||||
FileTransferProtocol::Sftp,
|
||||
@@ -680,7 +681,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 2).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 2, true).unwrap();
|
||||
// Add recent, wait 1 second for each one (cause the name depends on time)
|
||||
// 1
|
||||
client.add_recent(make_generic_ftparams(
|
||||
@@ -748,7 +749,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
// Add bookmark
|
||||
client.add_bookmark(
|
||||
"",
|
||||
@@ -769,7 +770,7 @@ mod tests {
|
||||
let (cfg_path, key_path): (PathBuf, PathBuf) = get_paths(tmp_dir.path());
|
||||
// Initialize a new bookmarks client
|
||||
let mut client: BookmarksClient =
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16).unwrap();
|
||||
BookmarksClient::new(cfg_path.as_path(), key_path.as_path(), 16, true).unwrap();
|
||||
client.key = "MYSUPERSECRETKEY".to_string();
|
||||
assert_eq!(
|
||||
client.decrypt_str("z4Z6LpcpYqBW4+bkIok+5A==").ok().unwrap(),
|
||||
|
||||
@@ -4,29 +4,24 @@
|
||||
|
||||
// Storages
|
||||
pub mod filestorage;
|
||||
#[cfg(feature = "with-keyring")]
|
||||
pub mod keyringstorage;
|
||||
// ext
|
||||
#[cfg(feature = "with-keyring")]
|
||||
use keyring::Error as KeyringError;
|
||||
use thiserror::Error;
|
||||
|
||||
/// defines the error type for the `KeyStorage`
|
||||
#[derive(Debug, Error)]
|
||||
pub enum KeyStorageError {
|
||||
#[cfg(feature = "with-keyring")]
|
||||
#[error("Key has a bad syntax")]
|
||||
BadSytax,
|
||||
#[error("Provider service error")]
|
||||
ProviderError,
|
||||
#[error("No such key")]
|
||||
NoSuchKey,
|
||||
#[cfg(feature = "with-keyring")]
|
||||
#[error("keyring error: {0}")]
|
||||
KeyringError(KeyringError),
|
||||
}
|
||||
|
||||
#[cfg(feature = "with-keyring")]
|
||||
impl From<KeyringError> for KeyStorageError {
|
||||
fn from(e: KeyringError) -> Self {
|
||||
Self::KeyringError(e)
|
||||
@@ -58,7 +53,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_system_keys_mod_errors() {
|
||||
#[cfg(feature = "with-keyring")]
|
||||
assert_eq!(
|
||||
KeyStorageError::BadSytax.to_string(),
|
||||
String::from("Key has a bad syntax")
|
||||
|
||||
Reference in New Issue
Block a user