feat(cli): added --wno-keyring flag to disable keyring
Some checks are pending
Linux / build (push) Waiting to run
MacOS / build (push) Waiting to run
Windows / build (push) Waiting to run

closes #308
This commit is contained in:
veeso
2025-03-22 13:44:02 +01:00
parent 806793421e
commit 368570592f
9 changed files with 91 additions and 73 deletions

View File

@@ -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
View File

@@ -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",
]

View File

@@ -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 }

View File

@@ -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>

View File

@@ -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)
}

View File

@@ -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),
}

View File

@@ -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}");

View File

@@ -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(),

View File

@@ -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")